Skip to content

Commit 3e459c0

Browse files
hujun260xiaoxiang781216
authored andcommitted
riscv: use g_running_task store current regs
This commit fixes the regression from apache#13561 In order to determine whether a context switch has occurred, we can use g_running_task to store the current regs. This allows us to compare the current register state with the previously stored state to identify if a context switch has taken place. Signed-off-by: hujun5 <[email protected]>
1 parent e706805 commit 3e459c0

File tree

6 files changed

+26
-35
lines changed

6 files changed

+26
-35
lines changed

arch/risc-v/src/common/riscv_doirq.c

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858

5959
uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
6060
{
61+
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
6162
struct tcb_s *tcb = this_task();
6263

6364
board_autoled_on(LED_INIRQ);
@@ -71,9 +72,10 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
7172
{
7273
regs[REG_EPC] += 4;
7374
}
74-
else
75+
76+
if (*running_task != NULL)
7577
{
76-
tcb->xcp.regs = regs;
78+
(*running_task)->xcp.regs = regs;
7779
}
7880

7981
/* Current regs non-zero indicates that we are processing an interrupt;
@@ -97,7 +99,7 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
9799
* returning from the interrupt.
98100
*/
99101

100-
if (regs != tcb->xcp.regs)
102+
if ((*running_task) != tcb)
101103
{
102104
#ifdef CONFIG_ARCH_ADDRENV
103105
/* Make sure that the address environment for the previously
@@ -119,15 +121,7 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
119121
* crashes.
120122
*/
121123

122-
g_running_tasks[this_cpu()] = tcb;
123-
124-
/* If a context switch occurred while processing the interrupt then
125-
* current_regs may have change value. If we return any value
126-
* different from the input regs, then the lower level will know
127-
* that a context switch occurred during interrupt processing.
128-
*/
129-
130-
regs = tcb->xcp.regs;
124+
*running_task = tcb;
131125
}
132126

133127
/* Set current_regs to NULL to indicate that we are no longer in an
@@ -138,5 +132,5 @@ uintreg_t *riscv_doirq(int irq, uintreg_t *regs)
138132

139133
#endif
140134
board_autoled_off(LED_INIRQ);
141-
return regs;
135+
return tcb->xcp.regs;
142136
}

arch/risc-v/src/common/riscv_exit.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ void up_exit(int status)
7878

7979
nxsched_resume_scheduler(tcb);
8080

81+
/* g_running_tasks is not valid now */
82+
83+
g_running_tasks[this_cpu()] = NULL;
84+
8185
/* Then switch contexts */
8286

8387
riscv_fullcontextrestore(tcb);

arch/risc-v/src/common/riscv_internal.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,6 @@
109109
#define PMP_ACCESS_DENIED (-1) /* Access set and denied */
110110
#define PMP_ACCESS_FULL (1) /* Access set and allowed */
111111

112-
/* Return values from riscv_swint */
113-
114-
#define SWINT_CONTEXT_SWITCH (1) /* Indicate we need context switch */
115-
116112
#ifndef __ASSEMBLY__
117113

118114
/* Use ASM as rv64ilp32 compiler generated address is limited */

arch/risc-v/src/common/riscv_sigdeliver.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ void riscv_sigdeliver(void)
162162
rtcb->irqcount--;
163163
#endif
164164

165+
/* g_running_tasks is not valid now */
166+
167+
g_running_tasks[this_cpu()] = NULL;
168+
165169
rtcb->xcp.regs = regs;
166170
riscv_fullcontextrestore(rtcb);
167171
}

arch/risc-v/src/common/riscv_swint.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ int riscv_swint(int irq, void *context, void *arg)
257257
struct tcb_s *next = (struct tcb_s *)(uintptr_t)regs[REG_A2];
258258

259259
DEBUGASSERT(regs[REG_A1] != 0 && regs[REG_A2] != 0);
260-
prev->xcp.regs = regs;
261260
riscv_savecontext(prev);
262261
new_regs = next->xcp.regs;
263262
riscv_restorecontext(next);
@@ -496,7 +495,6 @@ int riscv_swint(int irq, void *context, void *arg)
496495
if (regs != new_regs)
497496
{
498497
restore_critical_section(this_task(), this_cpu());
499-
return SWINT_CONTEXT_SWITCH;
500498
}
501499

502500
return OK;

arch/risc-v/src/common/supervisor/riscv_perform_syscall.c

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,24 @@
3737

3838
void *riscv_perform_syscall(uintreg_t *regs)
3939
{
40+
struct tcb_s **running_task = &g_running_tasks[this_cpu()];
4041
struct tcb_s *tcb;
41-
int cpu;
42-
int ret;
42+
43+
if (*running_task != NULL)
44+
{
45+
(*running_task)->xcp.regs = regs;
46+
}
4347

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

4650
up_set_current_regs(regs);
4751

4852
/* Run the system call handler (swint) */
4953

50-
ret = riscv_swint(0, regs, NULL);
54+
riscv_swint(0, regs, NULL);
55+
tcb = this_task();
5156

52-
if (ret == SWINT_CONTEXT_SWITCH)
57+
if ((*running_task) != tcb)
5358
{
5459
#ifdef CONFIG_ARCH_ADDRENV
5560
/* Make sure that the address environment for the previously
@@ -65,20 +70,10 @@ void *riscv_perform_syscall(uintreg_t *regs)
6570
* assertion logic for reporting crashes.
6671
*/
6772

68-
cpu = this_cpu();
69-
tcb = current_task(cpu);
70-
g_running_tasks[cpu] = tcb;
71-
72-
/* If a context switch occurred while processing the interrupt then
73-
* current_regs may have change value. If we return any value
74-
* different from the input regs, then the lower level will know
75-
* that a context switch occurred during interrupt processing.
76-
*/
77-
78-
regs = tcb->xcp.regs;
73+
*running_task = tcb;
7974
}
8075

8176
up_set_current_regs(NULL);
8277

83-
return regs;
78+
return tcb->xcp.regs;
8479
}

0 commit comments

Comments
 (0)