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:
parent
a5754a2f03
commit
e4a0470527
@ -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().
|
||||
*/
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user