xref: /openbmc/linux/arch/powerpc/kernel/interrupt_64.S (revision 9b69d48c7516a29cdaacd18d8bf5f575014a42a1)
1e754f4d1SNicholas Piggin#include <asm/asm-offsets.h>
2e754f4d1SNicholas Piggin#include <asm/bug.h>
3e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
4e754f4d1SNicholas Piggin#include <asm/exception-64s.h>
5e754f4d1SNicholas Piggin#else
6e754f4d1SNicholas Piggin#include <asm/exception-64e.h>
7e754f4d1SNicholas Piggin#endif
8e754f4d1SNicholas Piggin#include <asm/feature-fixups.h>
9e754f4d1SNicholas Piggin#include <asm/head-64.h>
10e754f4d1SNicholas Piggin#include <asm/hw_irq.h>
11e754f4d1SNicholas Piggin#include <asm/kup.h>
12e754f4d1SNicholas Piggin#include <asm/mmu.h>
13e754f4d1SNicholas Piggin#include <asm/ppc_asm.h>
14e754f4d1SNicholas Piggin#include <asm/ptrace.h>
15e754f4d1SNicholas Piggin#include <asm/tm.h>
16e754f4d1SNicholas Piggin
17e754f4d1SNicholas Piggin	.section	".toc","aw"
18e754f4d1SNicholas PigginSYS_CALL_TABLE:
19e754f4d1SNicholas Piggin	.tc sys_call_table[TC],sys_call_table
20e754f4d1SNicholas Piggin
21e754f4d1SNicholas Piggin#ifdef CONFIG_COMPAT
22e754f4d1SNicholas PigginCOMPAT_SYS_CALL_TABLE:
23e754f4d1SNicholas Piggin	.tc compat_sys_call_table[TC],compat_sys_call_table
24e754f4d1SNicholas Piggin#endif
25e754f4d1SNicholas Piggin	.previous
26e754f4d1SNicholas Piggin
27e754f4d1SNicholas Piggin	.align 7
28e754f4d1SNicholas Piggin
29e754f4d1SNicholas Piggin.macro DEBUG_SRR_VALID srr
30e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_RFI_SRR_DEBUG
31e754f4d1SNicholas Piggin	.ifc \srr,srr
32e754f4d1SNicholas Piggin	mfspr	r11,SPRN_SRR0
33e754f4d1SNicholas Piggin	ld	r12,_NIP(r1)
34e754f4d1SNicholas Piggin100:	tdne	r11,r12
35e754f4d1SNicholas Piggin	EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
36e754f4d1SNicholas Piggin	mfspr	r11,SPRN_SRR1
37e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
38e754f4d1SNicholas Piggin100:	tdne	r11,r12
39e754f4d1SNicholas Piggin	EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
40e754f4d1SNicholas Piggin	.else
41e754f4d1SNicholas Piggin	mfspr	r11,SPRN_HSRR0
42e754f4d1SNicholas Piggin	ld	r12,_NIP(r1)
43e754f4d1SNicholas Piggin100:	tdne	r11,r12
44e754f4d1SNicholas Piggin	EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
45e754f4d1SNicholas Piggin	mfspr	r11,SPRN_HSRR1
46e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
47e754f4d1SNicholas Piggin100:	tdne	r11,r12
48e754f4d1SNicholas Piggin	EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
49e754f4d1SNicholas Piggin	.endif
50e754f4d1SNicholas Piggin#endif
51e754f4d1SNicholas Piggin.endm
52e754f4d1SNicholas Piggin
53e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
54e754f4d1SNicholas Piggin.macro system_call_vectored name trapnr
55e754f4d1SNicholas Piggin	.globl system_call_vectored_\name
56e754f4d1SNicholas Pigginsystem_call_vectored_\name:
57e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
58e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
59e754f4d1SNicholas PigginBEGIN_FTR_SECTION
60e754f4d1SNicholas Piggin	extrdi.	r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
6113799748SNicholas Piggin	bne	tabort_syscall
62e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_TM)
63e754f4d1SNicholas Piggin#endif
64e754f4d1SNicholas Piggin	SCV_INTERRUPT_TO_KERNEL
65e754f4d1SNicholas Piggin	mr	r10,r1
66e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
67e754f4d1SNicholas Piggin	std	r10,0(r1)
68e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
69e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
70e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
71e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
72e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
73e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
74e754f4d1SNicholas Piggin	mfcr	r12
75e754f4d1SNicholas Piggin	li	r11,0
76e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
77e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
78e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
79e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
80e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
81e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
82e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
83e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
84e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
85e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
86e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
87e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
88e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
89e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
90e754f4d1SNicholas Piggin	std	r11,_XER(r1)
91e754f4d1SNicholas Piggin	std	r11,_LINK(r1)
92e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
93e754f4d1SNicholas Piggin
94e754f4d1SNicholas Piggin	li	r11,\trapnr
95e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
96e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
97e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
98e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
99e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
100e754f4d1SNicholas Piggin
101e754f4d1SNicholas PigginBEGIN_FTR_SECTION
102e754f4d1SNicholas Piggin	HMT_MEDIUM
103e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
104e754f4d1SNicholas Piggin
105e754f4d1SNicholas Piggin	/*
106e754f4d1SNicholas Piggin	 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
107e754f4d1SNicholas Piggin	 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
108e754f4d1SNicholas Piggin	 * and interrupts may be masked and pending already.
109e754f4d1SNicholas Piggin	 * system_call_exception() will call trace_hardirqs_off() which means
110e754f4d1SNicholas Piggin	 * interrupts could already have been blocked before trace_hardirqs_off,
111e754f4d1SNicholas Piggin	 * but this is the best we can do.
112e754f4d1SNicholas Piggin	 */
113e754f4d1SNicholas Piggin
114e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
115e754f4d1SNicholas Piggin	mr	r9,r0
116e754f4d1SNicholas Piggin	bl	system_call_exception
117e754f4d1SNicholas Piggin
118e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_exit:
119e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
120e754f4d1SNicholas Piggin	li	r5,1 /* scv */
121e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
12213799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
12313799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_start:
12413799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
12513799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
12613799748SNicholas Piggin	bne-	syscall_vectored_\name\()_restart
12713799748SNicholas Piggin	li	r11,IRQS_ENABLED
12813799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
12913799748SNicholas Piggin	li	r11,0
13013799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
131e754f4d1SNicholas Piggin
132e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
133e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
134e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
135e754f4d1SNicholas Piggin
136e754f4d1SNicholas PigginBEGIN_FTR_SECTION
137e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
138e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
139e754f4d1SNicholas Piggin
140e754f4d1SNicholas PigginBEGIN_FTR_SECTION
141e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
142e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
143e754f4d1SNicholas Piggin
144e754f4d1SNicholas Piggin	cmpdi	r3,0
145e754f4d1SNicholas Piggin	bne	.Lsyscall_vectored_\name\()_restore_regs
146e754f4d1SNicholas Piggin
147e754f4d1SNicholas Piggin	/* rfscv returns with LR->NIA and CTR->MSR */
148e754f4d1SNicholas Piggin	mtlr	r4
149e754f4d1SNicholas Piggin	mtctr	r5
150e754f4d1SNicholas Piggin
151e754f4d1SNicholas Piggin	/* Could zero these as per ABI, but we may consider a stricter ABI
152e754f4d1SNicholas Piggin	 * which preserves these if libc implementations can benefit, so
153e754f4d1SNicholas Piggin	 * restore them for now until further measurement is done. */
154e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
155e754f4d1SNicholas Piggin	ld	r4,GPR4(r1)
156e754f4d1SNicholas Piggin	ld	r5,GPR5(r1)
157e754f4d1SNicholas Piggin	ld	r6,GPR6(r1)
158e754f4d1SNicholas Piggin	ld	r7,GPR7(r1)
159e754f4d1SNicholas Piggin	ld	r8,GPR8(r1)
160e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
161e754f4d1SNicholas Piggin	li	r9,0
162e754f4d1SNicholas Piggin	li	r10,0
163e754f4d1SNicholas Piggin	li	r11,0
164e754f4d1SNicholas Piggin	li	r12,0
165e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
166e754f4d1SNicholas Piggin
167e754f4d1SNicholas Piggin	/*
168e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
169e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
170e754f4d1SNicholas Piggin	 */
171e754f4d1SNicholas Piggin	mtcr	r2
172e754f4d1SNicholas Piggin	ld	r2,GPR2(r1)
173e754f4d1SNicholas Piggin	ld	r3,GPR3(r1)
174e754f4d1SNicholas Piggin	ld	r13,GPR13(r1)
175e754f4d1SNicholas Piggin	ld	r1,GPR1(r1)
176e754f4d1SNicholas Piggin	RFSCV_TO_USER
177e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
178e754f4d1SNicholas Piggin
179e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_restore_regs:
180e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
181e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
182e754f4d1SNicholas Piggin
183e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
184e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
185e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
186e754f4d1SNicholas Piggin
187e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
188e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
189e754f4d1SNicholas Piggin	mtcr	r2
190e754f4d1SNicholas Piggin	mtctr	r3
191e754f4d1SNicholas Piggin	mtlr	r4
192e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
193e754f4d1SNicholas Piggin	REST_10GPRS(2, r1)
194e754f4d1SNicholas Piggin	REST_2GPRS(12, r1)
195e754f4d1SNicholas Piggin	ld	r1,GPR1(r1)
196e754f4d1SNicholas Piggin	RFI_TO_USER
19713799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_end:
19813799748SNicholas Piggin
19913799748SNicholas Pigginsyscall_vectored_\name\()_restart:
20013799748SNicholas Piggin	GET_PACA(r13)
20113799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
20213799748SNicholas Piggin	ld	r2,PACATOC(r13)
20313799748SNicholas Piggin	ld	r3,RESULT(r1)
20413799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
20513799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
20613799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
20713799748SNicholas Piggin	bl	syscall_exit_restart
20813799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
20913799748SNicholas Piggin	b	.Lsyscall_vectored_\name\()_rst_start
21013799748SNicholas Piggin
21113799748SNicholas PigginRESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
21213799748SNicholas Piggin
213e754f4d1SNicholas Piggin.endm
214e754f4d1SNicholas Piggin
215e754f4d1SNicholas Pigginsystem_call_vectored common 0x3000
21613799748SNicholas Piggin
217e754f4d1SNicholas Piggin/*
218e754f4d1SNicholas Piggin * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
219e754f4d1SNicholas Piggin * which is tested by system_call_exception when r0 is -1 (as set by vector
220e754f4d1SNicholas Piggin * entry code).
221e754f4d1SNicholas Piggin */
222e754f4d1SNicholas Pigginsystem_call_vectored sigill 0x7ff0
223e754f4d1SNicholas Piggin
224e754f4d1SNicholas Piggin
225e754f4d1SNicholas Piggin/*
226e754f4d1SNicholas Piggin * Entered via kernel return set up by kernel/sstep.c, must match entry regs
227e754f4d1SNicholas Piggin */
228e754f4d1SNicholas Piggin	.globl system_call_vectored_emulate
229e754f4d1SNicholas Pigginsystem_call_vectored_emulate:
230e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate)
231e754f4d1SNicholas Piggin	li	r10,IRQS_ALL_DISABLED
232e754f4d1SNicholas Piggin	stb	r10,PACAIRQSOFTMASK(r13)
233e754f4d1SNicholas Piggin	b	system_call_vectored_common
234*9b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
235e754f4d1SNicholas Piggin
236e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
237e754f4d1SNicholas Piggin	.globl system_call_common_real
238e754f4d1SNicholas Pigginsystem_call_common_real:
239e754f4d1SNicholas Piggin	ld	r10,PACAKMSR(r13)	/* get MSR value for kernel */
240e754f4d1SNicholas Piggin	mtmsrd	r10
241e754f4d1SNicholas Piggin
242e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
243e754f4d1SNicholas Piggin	.globl system_call_common
244e754f4d1SNicholas Pigginsystem_call_common:
245e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common)
246e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
247e754f4d1SNicholas PigginBEGIN_FTR_SECTION
248e754f4d1SNicholas Piggin	extrdi.	r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
24913799748SNicholas Piggin	bne	tabort_syscall
250e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_TM)
251e754f4d1SNicholas Piggin#endif
252e754f4d1SNicholas Piggin	mr	r10,r1
253e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
254e754f4d1SNicholas Piggin	std	r10,0(r1)
255e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
256e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
257e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
258e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
259e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
260e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_FSL_BOOK3E
261e754f4d1SNicholas PigginSTART_BTB_FLUSH_SECTION
262e754f4d1SNicholas Piggin	BTB_FLUSH(r10)
263e754f4d1SNicholas PigginEND_BTB_FLUSH_SECTION
264e754f4d1SNicholas Piggin#endif
265e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
266e754f4d1SNicholas Piggin	mfcr	r12
267e754f4d1SNicholas Piggin	li	r11,0
268e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
269e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
270e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
271e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
272e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
273e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
274e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
275e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
276e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
277e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
278e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
279e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
280e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
281e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
282e754f4d1SNicholas Piggin	std	r11,_XER(r1)
283e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
284e754f4d1SNicholas Piggin	mflr	r10
285e754f4d1SNicholas Piggin
286e754f4d1SNicholas Piggin	/*
287e754f4d1SNicholas Piggin	 * This clears CR0.SO (bit 28), which is the error indication on
288e754f4d1SNicholas Piggin	 * return from this system call.
289e754f4d1SNicholas Piggin	 */
290e754f4d1SNicholas Piggin	rldimi	r12,r11,28,(63-28)
291e754f4d1SNicholas Piggin	li	r11,0xc00
292e754f4d1SNicholas Piggin	std	r10,_LINK(r1)
293e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
294e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
295e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
296e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
297e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
298e754f4d1SNicholas Piggin
299e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
300e754f4d1SNicholas Piggin	li	r11,1
301e754f4d1SNicholas Piggin	stb	r11,PACASRR_VALID(r13)
302e754f4d1SNicholas Piggin#endif
303e754f4d1SNicholas Piggin
304e754f4d1SNicholas Piggin	/*
305e754f4d1SNicholas Piggin	 * We always enter kernel from userspace with irq soft-mask enabled and
306e754f4d1SNicholas Piggin	 * nothing pending. system_call_exception() will call
307e754f4d1SNicholas Piggin	 * trace_hardirqs_off().
308e754f4d1SNicholas Piggin	 */
309e754f4d1SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
310dd152f70SNicholas Piggin	li	r12,-1 /* Set MSR_EE and MSR_RI */
311e754f4d1SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
312dd152f70SNicholas Piggin	mtmsrd	r12,1
313e754f4d1SNicholas Piggin
314e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
315e754f4d1SNicholas Piggin	mr	r9,r0
316e754f4d1SNicholas Piggin	bl	system_call_exception
317e754f4d1SNicholas Piggin
318e754f4d1SNicholas Piggin.Lsyscall_exit:
319e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
320e754f4d1SNicholas Piggin	li	r5,0 /* !scv */
321e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
32213799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
323*9b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
32413799748SNicholas Piggin.Lsyscall_rst_start:
32513799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
32613799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
32713799748SNicholas Piggin	bne-	syscall_restart
328*9b69d48cSNicholas Piggin#endif
32913799748SNicholas Piggin	li	r11,IRQS_ENABLED
33013799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
33113799748SNicholas Piggin	li	r11,0
33213799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
333e754f4d1SNicholas Piggin
334e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
335e754f4d1SNicholas Piggin	ld	r6,_LINK(r1)
336e754f4d1SNicholas Piggin	mtlr	r6
337e754f4d1SNicholas Piggin
338e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
339e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
340e754f4d1SNicholas Piggin	cmpdi	r4,0
341e754f4d1SNicholas Piggin	bne	1f
342e754f4d1SNicholas Piggin	li	r4,0
343e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
344e754f4d1SNicholas Piggin#endif
345e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
346e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
347e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
348e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
349e754f4d1SNicholas Piggin1:
350e754f4d1SNicholas Piggin	DEBUG_SRR_VALID srr
351e754f4d1SNicholas Piggin
352e754f4d1SNicholas PigginBEGIN_FTR_SECTION
353e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
354e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
355e754f4d1SNicholas Piggin
356e754f4d1SNicholas Piggin	cmpdi	r3,0
357e754f4d1SNicholas Piggin	bne	.Lsyscall_restore_regs
358e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
359e754f4d1SNicholas Piggin	li	r0,0
360e754f4d1SNicholas Piggin	li	r4,0
361e754f4d1SNicholas Piggin	li	r5,0
362e754f4d1SNicholas Piggin	li	r6,0
363e754f4d1SNicholas Piggin	li	r7,0
364e754f4d1SNicholas Piggin	li	r8,0
365e754f4d1SNicholas Piggin	li	r9,0
366e754f4d1SNicholas Piggin	li	r10,0
367e754f4d1SNicholas Piggin	li	r11,0
368e754f4d1SNicholas Piggin	li	r12,0
369e754f4d1SNicholas Piggin	mtctr	r0
370e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
371e754f4d1SNicholas Piggin.Lsyscall_restore_regs_cont:
372e754f4d1SNicholas Piggin
373e754f4d1SNicholas PigginBEGIN_FTR_SECTION
374e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
375e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
376e754f4d1SNicholas Piggin
377e754f4d1SNicholas Piggin	/*
378e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
379e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
380e754f4d1SNicholas Piggin	 */
381e754f4d1SNicholas Piggin	mtcr	r2
382e754f4d1SNicholas Piggin	ld	r2,GPR2(r1)
383e754f4d1SNicholas Piggin	ld	r3,GPR3(r1)
384e754f4d1SNicholas Piggin	ld	r13,GPR13(r1)
385e754f4d1SNicholas Piggin	ld	r1,GPR1(r1)
386e754f4d1SNicholas Piggin	RFI_TO_USER
387e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
388e754f4d1SNicholas Piggin
389e754f4d1SNicholas Piggin.Lsyscall_restore_regs:
390e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
391e754f4d1SNicholas Piggin	ld	r4,_XER(r1)
392e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
393e754f4d1SNicholas Piggin	mtctr	r3
394e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r4
395e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
396e754f4d1SNicholas Piggin	REST_8GPRS(4, r1)
397e754f4d1SNicholas Piggin	ld	r12,GPR12(r1)
398e754f4d1SNicholas Piggin	b	.Lsyscall_restore_regs_cont
39913799748SNicholas Piggin.Lsyscall_rst_end:
40013799748SNicholas Piggin
401*9b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
40213799748SNicholas Pigginsyscall_restart:
40313799748SNicholas Piggin	GET_PACA(r13)
40413799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
40513799748SNicholas Piggin	ld	r2,PACATOC(r13)
40613799748SNicholas Piggin	ld	r3,RESULT(r1)
40713799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
40813799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
40913799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
41013799748SNicholas Piggin	bl	syscall_exit_restart
41113799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
41213799748SNicholas Piggin	b	.Lsyscall_rst_start
41313799748SNicholas Piggin
41413799748SNicholas PigginRESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
415*9b69d48cSNicholas Piggin#endif
416e754f4d1SNicholas Piggin
417e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
41813799748SNicholas Piggintabort_syscall:
419e754f4d1SNicholas Piggin	/* Firstly we need to enable TM in the kernel */
420e754f4d1SNicholas Piggin	mfmsr	r10
421e754f4d1SNicholas Piggin	li	r9, 1
422e754f4d1SNicholas Piggin	rldimi	r10, r9, MSR_TM_LG, 63-MSR_TM_LG
423e754f4d1SNicholas Piggin	mtmsrd	r10, 0
424e754f4d1SNicholas Piggin
425e754f4d1SNicholas Piggin	/* tabort, this dooms the transaction, nothing else */
426e754f4d1SNicholas Piggin	li	r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
427e754f4d1SNicholas Piggin	TABORT(R9)
428e754f4d1SNicholas Piggin
429e754f4d1SNicholas Piggin	/*
430e754f4d1SNicholas Piggin	 * Return directly to userspace. We have corrupted user register state,
431e754f4d1SNicholas Piggin	 * but userspace will never see that register state. Execution will
432e754f4d1SNicholas Piggin	 * resume after the tbegin of the aborted transaction with the
433e754f4d1SNicholas Piggin	 * checkpointed register state.
434e754f4d1SNicholas Piggin	 */
435e754f4d1SNicholas Piggin	li	r9, MSR_RI
436e754f4d1SNicholas Piggin	andc	r10, r10, r9
437e754f4d1SNicholas Piggin	mtmsrd	r10, 1
438e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0, r11
439e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1, r12
440e754f4d1SNicholas Piggin	RFI_TO_USER
441e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
442e754f4d1SNicholas Piggin#endif
443e754f4d1SNicholas Piggin
444e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
445e754f4d1SNicholas Piggin_GLOBAL(ret_from_fork_scv)
446e754f4d1SNicholas Piggin	bl	schedule_tail
447e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
448e754f4d1SNicholas Piggin	li	r3,0	/* fork() return value */
449e754f4d1SNicholas Piggin	b	.Lsyscall_vectored_common_exit
450e754f4d1SNicholas Piggin#endif
451e754f4d1SNicholas Piggin
452e754f4d1SNicholas Piggin_GLOBAL(ret_from_fork)
453e754f4d1SNicholas Piggin	bl	schedule_tail
454e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
455e754f4d1SNicholas Piggin	li	r3,0	/* fork() return value */
456e754f4d1SNicholas Piggin	b	.Lsyscall_exit
457e754f4d1SNicholas Piggin
458e754f4d1SNicholas Piggin_GLOBAL(ret_from_kernel_thread)
459e754f4d1SNicholas Piggin	bl	schedule_tail
460e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
461e754f4d1SNicholas Piggin	mtctr	r14
462e754f4d1SNicholas Piggin	mr	r3,r15
463e754f4d1SNicholas Piggin#ifdef PPC64_ELF_ABI_v2
464e754f4d1SNicholas Piggin	mr	r12,r14
465e754f4d1SNicholas Piggin#endif
466e754f4d1SNicholas Piggin	bctrl
467e754f4d1SNicholas Piggin	li	r3,0
468e754f4d1SNicholas Piggin	b	.Lsyscall_exit
469e754f4d1SNicholas Piggin
470e754f4d1SNicholas Piggin	/*
471e754f4d1SNicholas Piggin	 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
472e754f4d1SNicholas Piggin	 * touched, no exit work created, then this can be used.
473e754f4d1SNicholas Piggin	 */
474e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
475e754f4d1SNicholas Piggin	.globl fast_interrupt_return_srr
476e754f4d1SNicholas Pigginfast_interrupt_return_srr:
477e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
478e754f4d1SNicholas Piggin	kuap_check_amr r3, r4
479e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
480e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_PR
481e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
48213799748SNicholas Piggin	beq	1f
48313799748SNicholas Piggin	kuap_user_restore r3, r4
48413799748SNicholas Piggin	b	.Lfast_user_interrupt_return_srr
48513799748SNicholas Piggin1:	kuap_kernel_restore r3, r4
486e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_RI
487e754f4d1SNicholas Piggin	li	r3,0 /* 0 return value, no EMULATE_STACK_STORE */
488e754f4d1SNicholas Piggin	bne+	.Lfast_kernel_interrupt_return_srr
489e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
490e754f4d1SNicholas Piggin	bl	unrecoverable_exception
491e754f4d1SNicholas Piggin	b	. /* should not get here */
492e754f4d1SNicholas Piggin#else
493e754f4d1SNicholas Piggin	bne	.Lfast_user_interrupt_return_srr
494e754f4d1SNicholas Piggin	b	.Lfast_kernel_interrupt_return_srr
495e754f4d1SNicholas Piggin#endif
496e754f4d1SNicholas Piggin
497e754f4d1SNicholas Piggin.macro interrupt_return_macro srr
498e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
499e754f4d1SNicholas Piggin	.globl interrupt_return_\srr
500e754f4d1SNicholas Piggininterrupt_return_\srr\():
501e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
502e754f4d1SNicholas Piggin	ld	r4,_MSR(r1)
503e754f4d1SNicholas Piggin	andi.	r0,r4,MSR_PR
504e754f4d1SNicholas Piggin	beq	.Lkernel_interrupt_return_\srr
505e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
506e754f4d1SNicholas Piggin	bl	interrupt_exit_user_prepare
507e754f4d1SNicholas Piggin	cmpdi	r3,0
508e754f4d1SNicholas Piggin	bne-	.Lrestore_nvgprs_\srr
50913799748SNicholas Piggin.Lrestore_nvgprs_\srr\()_cont:
51013799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
511*9b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
51213799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_start:
51313799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
51413799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
51513799748SNicholas Piggin	bne-	interrupt_return_\srr\()_user_restart
516*9b69d48cSNicholas Piggin#endif
51713799748SNicholas Piggin	li	r11,IRQS_ENABLED
51813799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
51913799748SNicholas Piggin	li	r11,0
52013799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
521e754f4d1SNicholas Piggin
522e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_\srr\():
523e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
524e754f4d1SNicholas Piggin	.ifc \srr,srr
525e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
526e754f4d1SNicholas Piggin	.else
527e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
528e754f4d1SNicholas Piggin	.endif
529e754f4d1SNicholas Piggin	cmpdi	r4,0
530e754f4d1SNicholas Piggin	li	r4,0
531e754f4d1SNicholas Piggin	bne	1f
532e754f4d1SNicholas Piggin#endif
533e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
534e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
535e754f4d1SNicholas Piggin	.ifc \srr,srr
536e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
537e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
538e754f4d1SNicholas Piggin1:
539e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
540e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
541e754f4d1SNicholas Piggin#endif
542e754f4d1SNicholas Piggin	.else
543e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
544e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
545e754f4d1SNicholas Piggin1:
546e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
547e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
548e754f4d1SNicholas Piggin#endif
549e754f4d1SNicholas Piggin	.endif
550e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
551e754f4d1SNicholas Piggin
55213799748SNicholas Piggin#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
55313799748SNicholas Piggin	lbz	r4,PACAIRQSOFTMASK(r13)
55413799748SNicholas Piggin	tdnei	r4,IRQS_ENABLED
55513799748SNicholas Piggin#endif
55613799748SNicholas Piggin
55713799748SNicholas PigginBEGIN_FTR_SECTION
55813799748SNicholas Piggin	ld	r10,_PPR(r1)
55913799748SNicholas Piggin	mtspr	SPRN_PPR,r10
56013799748SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
56113799748SNicholas Piggin
562e754f4d1SNicholas PigginBEGIN_FTR_SECTION
563e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
564e754f4d1SNicholas PigginFTR_SECTION_ELSE
565e754f4d1SNicholas Piggin	ldarx	r0,0,r1
566e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
567e754f4d1SNicholas Piggin
568e754f4d1SNicholas Piggin	ld	r3,_CCR(r1)
569e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
570e754f4d1SNicholas Piggin	ld	r5,_CTR(r1)
571e754f4d1SNicholas Piggin	ld	r6,_XER(r1)
572e754f4d1SNicholas Piggin	li	r0,0
573e754f4d1SNicholas Piggin
574e754f4d1SNicholas Piggin	REST_4GPRS(7, r1)
575e754f4d1SNicholas Piggin	REST_2GPRS(11, r1)
576e754f4d1SNicholas Piggin	REST_GPR(13, r1)
577e754f4d1SNicholas Piggin
578e754f4d1SNicholas Piggin	mtcr	r3
579e754f4d1SNicholas Piggin	mtlr	r4
580e754f4d1SNicholas Piggin	mtctr	r5
581e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r6
582e754f4d1SNicholas Piggin
583e754f4d1SNicholas Piggin	REST_4GPRS(2, r1)
584e754f4d1SNicholas Piggin	REST_GPR(6, r1)
585e754f4d1SNicholas Piggin	REST_GPR(0, r1)
586e754f4d1SNicholas Piggin	REST_GPR(1, r1)
587e754f4d1SNicholas Piggin	.ifc \srr,srr
588e754f4d1SNicholas Piggin	RFI_TO_USER
589e754f4d1SNicholas Piggin	.else
590e754f4d1SNicholas Piggin	HRFI_TO_USER
591e754f4d1SNicholas Piggin	.endif
592e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
59313799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_end:
594e754f4d1SNicholas Piggin
595e754f4d1SNicholas Piggin.Lrestore_nvgprs_\srr\():
596e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
59713799748SNicholas Piggin	b	.Lrestore_nvgprs_\srr\()_cont
59813799748SNicholas Piggin
599*9b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
60013799748SNicholas Piggininterrupt_return_\srr\()_user_restart:
60113799748SNicholas Piggin	GET_PACA(r13)
60213799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
60313799748SNicholas Piggin	ld	r2,PACATOC(r13)
60413799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
60513799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
60613799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
60713799748SNicholas Piggin	bl	interrupt_exit_user_restart
60813799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
60913799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_user_rst_start
61013799748SNicholas Piggin
61113799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
612*9b69d48cSNicholas Piggin#endif
613e754f4d1SNicholas Piggin
614e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
615e754f4d1SNicholas Piggin.Lkernel_interrupt_return_\srr\():
61613799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel:
617e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
618e754f4d1SNicholas Piggin	bl	interrupt_exit_kernel_prepare
619e754f4d1SNicholas Piggin
62013799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
62113799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_start:
62213799748SNicholas Piggin	ld	r11,SOFTE(r1)
62313799748SNicholas Piggin	cmpwi	r11,IRQS_ENABLED
62413799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
62513799748SNicholas Piggin	bne	1f
626*9b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
62713799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
62813799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
62913799748SNicholas Piggin	bne-	interrupt_return_\srr\()_kernel_restart
630*9b69d48cSNicholas Piggin#endif
63113799748SNicholas Piggin	li	r11,0
63213799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
63313799748SNicholas Piggin1:
63413799748SNicholas Piggin
635e754f4d1SNicholas Piggin.Lfast_kernel_interrupt_return_\srr\():
636e754f4d1SNicholas Piggin	cmpdi	cr1,r3,0
637e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
638e754f4d1SNicholas Piggin	.ifc \srr,srr
639e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
640e754f4d1SNicholas Piggin	.else
641e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
642e754f4d1SNicholas Piggin	.endif
643e754f4d1SNicholas Piggin	cmpdi	r4,0
644e754f4d1SNicholas Piggin	li	r4,0
645e754f4d1SNicholas Piggin	bne	1f
646e754f4d1SNicholas Piggin#endif
647e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
648e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
649e754f4d1SNicholas Piggin	.ifc \srr,srr
650e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
651e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
652e754f4d1SNicholas Piggin1:
653e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
654e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
655e754f4d1SNicholas Piggin#endif
656e754f4d1SNicholas Piggin	.else
657e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
658e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
659e754f4d1SNicholas Piggin1:
660e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
661e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
662e754f4d1SNicholas Piggin#endif
663e754f4d1SNicholas Piggin	.endif
664e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
665e754f4d1SNicholas Piggin
666e754f4d1SNicholas PigginBEGIN_FTR_SECTION
667e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
668e754f4d1SNicholas PigginFTR_SECTION_ELSE
669e754f4d1SNicholas Piggin	ldarx	r0,0,r1
670e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
671e754f4d1SNicholas Piggin
672e754f4d1SNicholas Piggin	ld	r3,_LINK(r1)
673e754f4d1SNicholas Piggin	ld	r4,_CTR(r1)
674e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
675e754f4d1SNicholas Piggin	ld	r6,_CCR(r1)
676e754f4d1SNicholas Piggin	li	r0,0
677e754f4d1SNicholas Piggin
678e754f4d1SNicholas Piggin	REST_4GPRS(7, r1)
679e754f4d1SNicholas Piggin	REST_2GPRS(11, r1)
680e754f4d1SNicholas Piggin
681e754f4d1SNicholas Piggin	mtlr	r3
682e754f4d1SNicholas Piggin	mtctr	r4
683e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
684e754f4d1SNicholas Piggin
685e754f4d1SNicholas Piggin	/*
686e754f4d1SNicholas Piggin	 * Leaving a stale exception_marker on the stack can confuse
687e754f4d1SNicholas Piggin	 * the reliable stack unwinder later on. Clear it.
688e754f4d1SNicholas Piggin	 */
689e754f4d1SNicholas Piggin	std	r0,STACK_FRAME_OVERHEAD-16(r1)
690e754f4d1SNicholas Piggin
691e754f4d1SNicholas Piggin	REST_4GPRS(2, r1)
692e754f4d1SNicholas Piggin
693e754f4d1SNicholas Piggin	bne-	cr1,1f /* emulate stack store */
694e754f4d1SNicholas Piggin	mtcr	r6
695e754f4d1SNicholas Piggin	REST_GPR(6, r1)
696e754f4d1SNicholas Piggin	REST_GPR(0, r1)
697e754f4d1SNicholas Piggin	REST_GPR(1, r1)
698e754f4d1SNicholas Piggin	.ifc \srr,srr
699e754f4d1SNicholas Piggin	RFI_TO_KERNEL
700e754f4d1SNicholas Piggin	.else
701e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
702e754f4d1SNicholas Piggin	.endif
703e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
704e754f4d1SNicholas Piggin
705e754f4d1SNicholas Piggin1:	/*
706e754f4d1SNicholas Piggin	 * Emulate stack store with update. New r1 value was already calculated
707e754f4d1SNicholas Piggin	 * and updated in our interrupt regs by emulate_loadstore, but we can't
708e754f4d1SNicholas Piggin	 * store the previous value of r1 to the stack before re-loading our
709e754f4d1SNicholas Piggin	 * registers from it, otherwise they could be clobbered.  Use
710e754f4d1SNicholas Piggin	 * PACA_EXGEN as temporary storage to hold the store data, as
711e754f4d1SNicholas Piggin	 * interrupts are disabled here so it won't be clobbered.
712e754f4d1SNicholas Piggin	 */
713e754f4d1SNicholas Piggin	mtcr	r6
714e754f4d1SNicholas Piggin	std	r9,PACA_EXGEN+0(r13)
715e754f4d1SNicholas Piggin	addi	r9,r1,INT_FRAME_SIZE /* get original r1 */
716e754f4d1SNicholas Piggin	REST_GPR(6, r1)
717e754f4d1SNicholas Piggin	REST_GPR(0, r1)
718e754f4d1SNicholas Piggin	REST_GPR(1, r1)
719e754f4d1SNicholas Piggin	std	r9,0(r1) /* perform store component of stdu */
720e754f4d1SNicholas Piggin	ld	r9,PACA_EXGEN+0(r13)
721e754f4d1SNicholas Piggin
722e754f4d1SNicholas Piggin	.ifc \srr,srr
723e754f4d1SNicholas Piggin	RFI_TO_KERNEL
724e754f4d1SNicholas Piggin	.else
725e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
726e754f4d1SNicholas Piggin	.endif
727e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
72813799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_end:
72913799748SNicholas Piggin
730*9b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
73113799748SNicholas Piggininterrupt_return_\srr\()_kernel_restart:
73213799748SNicholas Piggin	GET_PACA(r13)
73313799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
73413799748SNicholas Piggin	ld	r2,PACATOC(r13)
73513799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
73613799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
73713799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
73813799748SNicholas Piggin	bl	interrupt_exit_kernel_restart
73913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
74013799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_kernel_rst_start
74113799748SNicholas Piggin
74213799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
743*9b69d48cSNicholas Piggin#endif
74413799748SNicholas Piggin
745e754f4d1SNicholas Piggin.endm
746e754f4d1SNicholas Piggin
747e754f4d1SNicholas Piggininterrupt_return_macro srr
748e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
749e754f4d1SNicholas Piggininterrupt_return_macro hsrr
7509d1988caSNicholas Piggin
7519d1988caSNicholas Piggin	.globl __end_soft_masked
7529d1988caSNicholas Piggin__end_soft_masked:
7539d1988caSNicholas PigginDEFINE_FIXED_SYMBOL(__end_soft_masked)
754*9b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
755