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 <[email protected]>
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 <[email protected]>
---
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