This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push: new e4a0470527 riscv: add a return value to riscv_swint indicating whether a context switch is required e4a0470527 is described below commit e4a047052745251cff26b5cbb39c239ad8f1a3e9 Author: hujun5 <huj...@xiaomi.com> AuthorDate: Sat Sep 21 11:14:18 2024 +0800 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 Signed-off-by: hujun5 <huj...@xiaomi.com> --- arch/risc-v/src/common/riscv_fork.c | 7 +++++++ arch/risc-v/src/common/riscv_internal.h | 4 ++++ arch/risc-v/src/common/riscv_swint.c | 1 + arch/risc-v/src/common/supervisor/riscv_perform_syscall.c | 10 +++------- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/risc-v/src/common/riscv_fork.c b/arch/risc-v/src/common/riscv_fork.c index 40e463b2ae..896d8d46c4 100644 --- a/arch/risc-v/src/common/riscv_fork.c +++ b/arch/risc-v/src/common/riscv_fork.c @@ -108,11 +108,16 @@ pid_t riscv_fork(const struct fork_s *context) uintptr_t newtop; uintptr_t stacktop; uintptr_t stackutil; + irqstate_t flags; #ifdef CONFIG_SCHED_THREAD_LOCAL uintptr_t tp; #endif UNUSED(context); + /* parent regs may change in irq, we should disable irq here */ + + flags = up_irq_save(); + /* Allocate and initialize a TCB for the child task. */ child = nxtask_setup_fork((start_t)parent->xcp.regs[REG_RA]); @@ -164,6 +169,8 @@ pid_t riscv_fork(const struct fork_s *context) child->cmn.xcp.regs[REG_TP] = tp; #endif + up_irq_restore(flags); + /* And, finally, start the child task. On a failure, nxtask_start_fork() * will discard the TCB by calling nxtask_abort_fork(). */ diff --git a/arch/risc-v/src/common/riscv_internal.h b/arch/risc-v/src/common/riscv_internal.h index d9165356a9..c8b5f184bf 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 510161db6f..4cf68ac0aa 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 8e26221e40..022c58155e 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