mm: fix exec activate_mm vs TLB shootdown and lazy tlb switching race
[linux/fpc-iii.git] / arch / arc / include / asm / entry-arcv2.h
blob9f581553dcc36f5a82dc0bc9ae571b8555a79f55
1 /* SPDX-License-Identifier: GPL-2.0 */
3 #ifndef __ASM_ARC_ENTRY_ARCV2_H
4 #define __ASM_ARC_ENTRY_ARCV2_H
6 #include <asm/asm-offsets.h>
7 #include <asm/irqflags-arcv2.h>
8 #include <asm/thread_info.h> /* For THREAD_SIZE */
10 /*------------------------------------------------------------------------*/
11 .macro INTERRUPT_PROLOGUE called_from
13 ; Before jumping to Interrupt Vector, hardware micro-ops did following:
14 ; 1. SP auto-switched to kernel mode stack
15 ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1, K:0)
16 ; 3. Auto saved: r0-r11, blink, LPE,LPS,LPC, JLI,LDI,EI, PC, STAT32
18 ; Now manually save: r12, sp, fp, gp, r25
20 #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
21 .ifnc \called_from, exception
22 st.as r9, [sp, -10] ; save r9 in it's final stack slot
23 sub sp, sp, 12 ; skip JLI, LDI, EI
25 PUSH lp_count
26 PUSHAX lp_start
27 PUSHAX lp_end
28 PUSH blink
30 PUSH r11
31 PUSH r10
33 sub sp, sp, 4 ; skip r9
35 PUSH r8
36 PUSH r7
37 PUSH r6
38 PUSH r5
39 PUSH r4
40 PUSH r3
41 PUSH r2
42 PUSH r1
43 PUSH r0
44 .endif
45 #endif
47 #ifdef CONFIG_ARC_HAS_ACCL_REGS
48 PUSH r59
49 PUSH r58
50 #endif
52 PUSH r30
53 PUSH r12
55 ; Saving pt_regs->sp correctly requires some extra work due to the way
56 ; Auto stack switch works
57 ; - U mode: retrieve it from AUX_USER_SP
58 ; - K mode: add the offset from current SP where H/w starts auto push
60 ; Utilize the fact that Z bit is set if Intr taken in U mode
61 mov.nz r9, sp
62 add.nz r9, r9, SZ_PT_REGS - PT_sp - 4
63 bnz 1f
65 lr r9, [AUX_USER_SP]
67 PUSH r9 ; SP
69 PUSH fp
70 PUSH gp
72 #ifdef CONFIG_ARC_CURR_IN_REG
73 PUSH r25 ; user_r25
74 GET_CURR_TASK_ON_CPU r25
75 #else
76 sub sp, sp, 4
77 #endif
79 .ifnc \called_from, exception
80 sub sp, sp, 12 ; BTA/ECR/orig_r0 placeholder per pt_regs
81 .endif
83 .endm
85 /*------------------------------------------------------------------------*/
86 .macro INTERRUPT_EPILOGUE called_from
88 .ifnc \called_from, exception
89 add sp, sp, 12 ; skip BTA/ECR/orig_r0 placeholderss
90 .endif
92 #ifdef CONFIG_ARC_CURR_IN_REG
93 POP r25
94 #else
95 add sp, sp, 4
96 #endif
98 POP gp
99 POP fp
101 ; Don't touch AUX_USER_SP if returning to K mode (Z bit set)
102 ; (Z bit set on K mode is inverse of INTERRUPT_PROLOGUE)
103 add.z sp, sp, 4
104 bz 1f
106 POPAX AUX_USER_SP
108 POP r12
109 POP r30
111 #ifdef CONFIG_ARC_HAS_ACCL_REGS
112 POP r58
113 POP r59
114 #endif
116 #ifdef CONFIG_ARC_IRQ_NO_AUTOSAVE
117 .ifnc \called_from, exception
118 POP r0
119 POP r1
120 POP r2
121 POP r3
122 POP r4
123 POP r5
124 POP r6
125 POP r7
126 POP r8
127 POP r9
128 POP r10
129 POP r11
131 POP blink
132 POPAX lp_end
133 POPAX lp_start
135 POP r9
136 mov lp_count, r9
138 add sp, sp, 12 ; skip JLI, LDI, EI
139 ld.as r9, [sp, -10] ; reload r9 which got clobbered
140 .endif
141 #endif
143 .endm
145 /*------------------------------------------------------------------------*/
146 .macro EXCEPTION_PROLOGUE
148 ; Before jumping to Exception Vector, hardware micro-ops did following:
149 ; 1. SP auto-switched to kernel mode stack
150 ; 2. STATUS32.Z flag set to U mode at time of interrupt (U:1,K:0)
152 ; Now manually save the complete reg file
154 PUSH r9 ; freeup a register: slot of erstatus
156 PUSHAX eret
157 sub sp, sp, 12 ; skip JLI, LDI, EI
158 PUSH lp_count
159 PUSHAX lp_start
160 PUSHAX lp_end
161 PUSH blink
163 PUSH r11
164 PUSH r10
166 ld.as r9, [sp, 10] ; load stashed r9 (status32 stack slot)
167 lr r10, [erstatus]
168 st.as r10, [sp, 10] ; save status32 at it's right stack slot
170 PUSH r9
171 PUSH r8
172 PUSH r7
173 PUSH r6
174 PUSH r5
175 PUSH r4
176 PUSH r3
177 PUSH r2
178 PUSH r1
179 PUSH r0
181 ; -- for interrupts, regs above are auto-saved by h/w in that order --
182 ; Now do what ISR prologue does (manually save r12, sp, fp, gp, r25)
184 ; Set Z flag if this was from U mode (expected by INTERRUPT_PROLOGUE)
185 ; Although H/w exception micro-ops do set Z flag for U mode (just like
186 ; for interrupts), it could get clobbered in case we soft land here from
187 ; a TLB Miss exception handler (tlbex.S)
189 and r10, r10, STATUS_U_MASK
190 xor.f 0, r10, STATUS_U_MASK
192 INTERRUPT_PROLOGUE exception
194 PUSHAX erbta
195 PUSHAX ecr ; r9 contains ECR, expected by EV_Trap
197 PUSH r0 ; orig_r0
198 .endm
200 /*------------------------------------------------------------------------*/
201 .macro EXCEPTION_EPILOGUE
203 ; Assumes r0 has PT_status32
204 btst r0, STATUS_U_BIT ; Z flag set if K, used in INTERRUPT_EPILOGUE
206 add sp, sp, 8 ; orig_r0/ECR don't need restoring
207 POPAX erbta
209 INTERRUPT_EPILOGUE exception
211 POP r0
212 POP r1
213 POP r2
214 POP r3
215 POP r4
216 POP r5
217 POP r6
218 POP r7
219 POP r8
220 POP r9
221 POP r10
222 POP r11
224 POP blink
225 POPAX lp_end
226 POPAX lp_start
228 POP r9
229 mov lp_count, r9
231 add sp, sp, 12 ; skip JLI, LDI, EI
232 POPAX eret
233 POPAX erstatus
235 ld.as r9, [sp, -12] ; reload r9 which got clobbered
236 .endm
238 .macro FAKE_RET_FROM_EXCPN
239 lr r9, [status32]
240 bic r9, r9, (STATUS_U_MASK|STATUS_DE_MASK|STATUS_AE_MASK)
241 or r9, r9, (STATUS_L_MASK|STATUS_IE_MASK)
242 kflag r9
243 .endm
245 /* Get thread_info of "current" tsk */
246 .macro GET_CURR_THR_INFO_FROM_SP reg
247 bmskn \reg, sp, THREAD_SHIFT - 1
248 .endm
250 /* Get CPU-ID of this core */
251 .macro GET_CPU_ID reg
252 lr \reg, [identity]
253 xbfu \reg, \reg, 0xE8 /* 00111 01000 */
254 /* M = 8-1 N = 8 */
255 .endm
257 #endif