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 <hujun5@xiaomi.com>
This commit is contained in:
hujun5 2024-09-21 11:14:18 +08:00 committed by Alan C. Assis
parent a5754a2f03
commit e4a0470527
4 changed files with 15 additions and 7 deletions

View File

@ -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().
*/

View File

@ -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 */

View File

@ -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;

View File

@ -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