From cfab545992a33384b30b5fc1831cbc3f189d24dd Mon Sep 17 00:00:00 2001 From: hujun5 Date: Sat, 21 Sep 2024 11:14:18 +0800 Subject: [PATCH] riscv: add a return value to riscv_swint indicating whether a context switch is required This commit fixes the regression from https://github.com/apache/nuttx/pull/13561 Change-Id: Ifb0623c0c60f7da55c762926e93cd1708c421ce6 --- arch/risc-v/src/common/riscv_internal.h | 4 ++++ arch/risc-v/src/common/riscv_swint.c | 1 + .../src/common/supervisor/riscv_perform_syscall.c | 10 +++------- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index d9165356a97c1..c8b5f184bfb09 100644 --- a/arch/risc-v/src/common/riscv_internal.h +++ b/arch/risc-v/src/common/riscv_internal.h @@ -109,6 +109,10 @@ #define PMP_ACCESS_DENIED (-1) /* Access set and denied */ #define PMP_ACCESS_FULL (1) /* Access set and allowed */ +/* Return values from riscv_swint */ + +#define SWINT_CONTEXT_SWITCH (1) /* Indicate we need context switch */ + #ifndef __ASSEMBLY__ /* Use ASM as rv64ilp32 compiler generated address is limited */ diff --git a/arch/risc-v/src/common/riscv_swint.c b/arch/risc-v/src/common/riscv_swint.c index 510161db6fefc..4cf68ac0aa9c7 100644 --- a/arch/risc-v/src/common/riscv_swint.c +++ b/arch/risc-v/src/common/riscv_swint.c @@ -496,6 +496,7 @@ int riscv_swint(int irq, void *context, void *arg) if (regs != new_regs) { restore_critical_section(this_task(), this_cpu()); + return SWINT_CONTEXT_SWITCH; } return OK; diff --git a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c index 8e26221e40c5b..022c58155e3e1 100644 --- a/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c +++ b/arch/risc-v/src/common/supervisor/riscv_perform_syscall.c @@ -39,6 +39,7 @@ void *riscv_perform_syscall(uintreg_t *regs) { struct tcb_s *tcb; int cpu; + int ret; /* Set up the interrupt register set needed by swint() */ @@ -46,10 +47,9 @@ void *riscv_perform_syscall(uintreg_t *regs) /* Run the system call handler (swint) */ - riscv_swint(0, regs, NULL); - tcb = this_task(); + ret = riscv_swint(0, regs, NULL); - if (regs != tcb->xcp.regs) + if (ret == SWINT_CONTEXT_SWITCH) { #ifdef CONFIG_ARCH_ADDRENV /* Make sure that the address environment for the previously @@ -69,10 +69,6 @@ void *riscv_perform_syscall(uintreg_t *regs) tcb = current_task(cpu); g_running_tasks[cpu] = tcb; - /* Restore the cpu lock */ - - restore_critical_section(tcb, cpu); - /* If a context switch occurred while processing the interrupt then * current_regs may have change value. If we return any value * different from the input regs, then the lower level will know