Skip to content

Commit 5b6f860

Browse files
Wayne RenMaureenHelm
authored andcommitted
arch: arc: use a separate stack for exception handling
* use a separate stack for exception handling, this will gurantee the exception handling always work, not affected by some speical cases, e.g., stack check exception or mem. protection exception at the exception entry. * this commit can fix the second case of #8092 * note: the thread switch is still possible in exception handling, e.g, caused by thread_abort. But the switched out thread cannot be recovered, as the thread context is not setup. Signed-off-by: Wayne Ren <[email protected]>
1 parent c6c856b commit 5b6f860

File tree

1 file changed

+26
-51
lines changed

1 file changed

+26
-51
lines changed

arch/arc/core/fault_s.S

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ GTEXT(__ev_maligned)
3636

3737
GDATA(exc_nest_count)
3838

39+
.balign 4
40+
SECTION_VAR(BSS, saved_value)
41+
.word 0
42+
43+
#define EXCEPTION_STACK_SIZE 256
44+
45+
SECTION_VAR(NOINIT, _exception_stack)
46+
.space EXCEPTION_STACK_SIZE
47+
3948
/*
4049
* @brief Fault handler installed in the fault and reserved vectors
4150
*/
@@ -53,21 +62,18 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_div_zero)
5362
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_dc_error)
5463
SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_maligned)
5564

56-
/*
57-
* Before invoking exception handler, the kernel switches to an exception
58-
* stack, to save the faulting thread's registers.
59-
* The exception is fatal and all the kernel can do is just print
60-
* a diagnostic message and halt.
61-
*/
6265

6366
#ifdef CONFIG_ARC_STACK_CHECKING
64-
push_s r2
67+
st r0, [saved_value]
6568
/* disable stack checking */
66-
lr r2, [_ARC_V2_STATUS32]
67-
bclr r2, r2, _ARC_V2_STATUS32_SC_BIT
68-
kflag r2
69-
pop_s r2
69+
lr r0, [_ARC_V2_STATUS32]
70+
bclr r0, r0, _ARC_V2_STATUS32_SC_BIT
71+
kflag r0
72+
ld r0, [saved_value]
7073
#endif
74+
st sp, [saved_value]
75+
mov_s sp, _exception_stack
76+
add sp, sp, EXCEPTION_STACK_SIZE
7177

7278
/* save caller saved registers */
7379
_create_irq_stack_frame
@@ -81,30 +87,11 @@ SECTION_SUBSEC_FUNC(TEXT,__fault,__ev_maligned)
8187
lr r0,[_ARC_V2_ERET]
8288
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
8389

84-
ld r1, [exc_nest_count]
85-
add r0, r1, 1
86-
st r0, [exc_nest_count]
87-
cmp r1, 0
88-
89-
bgt.d exc_nest_handle
9090
mov r0, sp
9191

92-
mov r1, _kernel
93-
ld sp, [r1, _kernel_offset_to_irq_stack]
94-
exc_nest_handle:
95-
push_s r0
96-
9792
jl _Fault
9893

9994
_exc_return:
100-
pop sp
101-
102-
mov r1, exc_nest_count
103-
ld r0, [r1]
104-
sub r0, r0, 1
105-
cmp r0, 0
106-
bne.d _exc_return_from_exc
107-
st r0, [r1]
10895

10996
#ifdef CONFIG_PREEMPT_ENABLED
11097
mov_s r1, _kernel
@@ -114,11 +101,6 @@ _exc_return:
114101
ld_s r0, [r1, _kernel_offset_to_ready_q_cache]
115102
breq r0, r2, _exc_return_from_exc
116103

117-
_save_callee_saved_regs
118-
119-
st _CAUSE_RIRQ, [r2, _thread_offset_to_relinquish_cause]
120-
/* note: Ok to use _CAUSE_RIRQ since everything is saved */
121-
122104
ld_s r2, [r1, _kernel_offset_to_ready_q_cache]
123105
st_s r2, [r1, _kernel_offset_to_current]
124106

@@ -152,6 +134,7 @@ _exc_return:
152134

153135
_exc_return_from_exc:
154136
_pop_irq_stack_frame
137+
ld sp, [saved_value]
155138
rtie
156139

157140

@@ -204,13 +187,16 @@ valid_syscall_id:
204187
_do_other_trap:
205188
#endif /* CONFIG_USERSPACE */
206189
#ifdef CONFIG_ARC_STACK_CHECKING
207-
push_s r2
190+
st r0, [saved_value]
208191
/* disable stack checking */
209-
lr r2, [_ARC_V2_STATUS32]
210-
bclr r2, r2, _ARC_V2_STATUS32_SC_BIT
211-
kflag r2
212-
pop_s r2
192+
lr r0, [_ARC_V2_STATUS32]
193+
bclr r0, r0, _ARC_V2_STATUS32_SC_BIT
194+
kflag r0
195+
ld r0, [saved_value]
213196
#endif
197+
st sp, [saved_value]
198+
mov_s sp, _exception_stack
199+
add sp, sp, EXCEPTION_STACK_SIZE
214200

215201
/* save caller saved registers */
216202
_create_irq_stack_frame
@@ -224,19 +210,8 @@ _do_other_trap:
224210
lr r0,[_ARC_V2_ERET]
225211
st_s r0, [sp, ___isf_t_pc_OFFSET] /* eret into pc */
226212

227-
ld r1, [exc_nest_count]
228-
add r0, r1, 1
229-
st r0, [exc_nest_count]
230-
cmp r1, 0
231-
232-
bgt.d trap_nest_handle
233213
mov r0, sp
234214

235-
mov r1, _kernel
236-
ld sp, [r1, _kernel_offset_to_irq_stack]
237-
trap_nest_handle:
238-
push_s r0
239-
240215
mov blink, _exc_return
241216

242217
cmp ilink, _TRAP_S_CALL_RUNTIME_EXCEPT

0 commit comments

Comments
 (0)