Skip to content

Commit

Permalink
riscv: add a return value to riscv_swint indicating whether a context…
Browse files Browse the repository at this point in the history
… switch is required

This commit fixes the regression from #13561

Signed-off-by: hujun5 <[email protected]>
  • Loading branch information
hujun260 committed Sep 21, 2024
1 parent 72acec7 commit 72e2525
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 7 deletions.
7 changes: 7 additions & 0 deletions arch/risc-v/src/common/riscv_fork.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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().
*/
Expand Down
4 changes: 4 additions & 0 deletions arch/risc-v/src/common/riscv_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions arch/risc-v/src/common/riscv_swint.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 3 additions & 7 deletions arch/risc-v/src/common/supervisor/riscv_perform_syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ void *riscv_perform_syscall(uintreg_t *regs)
{
struct tcb_s *tcb;
int cpu;
int ret;

/* Set up the interrupt register set needed by swint() */

up_set_current_regs(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
Expand All @@ -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
Expand Down

0 comments on commit 72e2525

Please sign in to comment.