xref: /openbmc/linux/arch/powerpc/kernel/interrupt_64.S (revision 91fc46eced0f70526d74468ac6c932c90a8585b3)
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:
20098798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart)
20113799748SNicholas Piggin	GET_PACA(r13)
20213799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
20313799748SNicholas Piggin	ld	r2,PACATOC(r13)
20413799748SNicholas Piggin	ld	r3,RESULT(r1)
20513799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
20613799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
20713799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
20813799748SNicholas Piggin	bl	syscall_exit_restart
20913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
21013799748SNicholas Piggin	b	.Lsyscall_vectored_\name\()_rst_start
211325678fdSNicholas Piggin1:
21213799748SNicholas Piggin
213325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)
21413799748SNicholas PigginRESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
21513799748SNicholas Piggin
216e754f4d1SNicholas Piggin.endm
217e754f4d1SNicholas Piggin
218e754f4d1SNicholas Pigginsystem_call_vectored common 0x3000
21913799748SNicholas Piggin
220e754f4d1SNicholas Piggin/*
221e754f4d1SNicholas Piggin * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
222e754f4d1SNicholas Piggin * which is tested by system_call_exception when r0 is -1 (as set by vector
223e754f4d1SNicholas Piggin * entry code).
224e754f4d1SNicholas Piggin */
225e754f4d1SNicholas Pigginsystem_call_vectored sigill 0x7ff0
226e754f4d1SNicholas Piggin
227e754f4d1SNicholas Piggin
228e754f4d1SNicholas Piggin/*
229e754f4d1SNicholas Piggin * Entered via kernel return set up by kernel/sstep.c, must match entry regs
230e754f4d1SNicholas Piggin */
231e754f4d1SNicholas Piggin	.globl system_call_vectored_emulate
232e754f4d1SNicholas Pigginsystem_call_vectored_emulate:
233e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_vectored_emulate)
234e754f4d1SNicholas Piggin	li	r10,IRQS_ALL_DISABLED
235e754f4d1SNicholas Piggin	stb	r10,PACAIRQSOFTMASK(r13)
236e754f4d1SNicholas Piggin	b	system_call_vectored_common
2379b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
238e754f4d1SNicholas Piggin
239e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
240e754f4d1SNicholas Piggin	.globl system_call_common_real
241e754f4d1SNicholas Pigginsystem_call_common_real:
24298798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common_real)
243e754f4d1SNicholas Piggin	ld	r10,PACAKMSR(r13)	/* get MSR value for kernel */
244e754f4d1SNicholas Piggin	mtmsrd	r10
245e754f4d1SNicholas Piggin
246e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
247e754f4d1SNicholas Piggin	.globl system_call_common
248e754f4d1SNicholas Pigginsystem_call_common:
249e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common)
250e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
251e754f4d1SNicholas PigginBEGIN_FTR_SECTION
252e754f4d1SNicholas Piggin	extrdi.	r10, r12, 1, (63-MSR_TS_T_LG) /* transaction active? */
25313799748SNicholas Piggin	bne	tabort_syscall
254e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_TM)
255e754f4d1SNicholas Piggin#endif
256e754f4d1SNicholas Piggin	mr	r10,r1
257e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
258e754f4d1SNicholas Piggin	std	r10,0(r1)
259e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
260e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
261e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
262e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
263e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
264e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_FSL_BOOK3E
265e754f4d1SNicholas PigginSTART_BTB_FLUSH_SECTION
266e754f4d1SNicholas Piggin	BTB_FLUSH(r10)
267e754f4d1SNicholas PigginEND_BTB_FLUSH_SECTION
268e754f4d1SNicholas Piggin#endif
269e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
270e754f4d1SNicholas Piggin	mfcr	r12
271e754f4d1SNicholas Piggin	li	r11,0
272e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
273e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
274e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
275e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
276e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
277e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
278e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
279e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
280e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
281e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
282e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
283e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
284e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
285e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
286e754f4d1SNicholas Piggin	std	r11,_XER(r1)
287e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
288e754f4d1SNicholas Piggin	mflr	r10
289e754f4d1SNicholas Piggin
290e754f4d1SNicholas Piggin	/*
291e754f4d1SNicholas Piggin	 * This clears CR0.SO (bit 28), which is the error indication on
292e754f4d1SNicholas Piggin	 * return from this system call.
293e754f4d1SNicholas Piggin	 */
294e754f4d1SNicholas Piggin	rldimi	r12,r11,28,(63-28)
295e754f4d1SNicholas Piggin	li	r11,0xc00
296e754f4d1SNicholas Piggin	std	r10,_LINK(r1)
297e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
298e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
299e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
300e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
301e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
302e754f4d1SNicholas Piggin
303e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
304e754f4d1SNicholas Piggin	li	r11,1
305e754f4d1SNicholas Piggin	stb	r11,PACASRR_VALID(r13)
306e754f4d1SNicholas Piggin#endif
307e754f4d1SNicholas Piggin
308e754f4d1SNicholas Piggin	/*
309e754f4d1SNicholas Piggin	 * We always enter kernel from userspace with irq soft-mask enabled and
310e754f4d1SNicholas Piggin	 * nothing pending. system_call_exception() will call
311e754f4d1SNicholas Piggin	 * trace_hardirqs_off().
312e754f4d1SNicholas Piggin	 */
313e754f4d1SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
314dd152f70SNicholas Piggin	li	r12,-1 /* Set MSR_EE and MSR_RI */
315e754f4d1SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
316dd152f70SNicholas Piggin	mtmsrd	r12,1
317e754f4d1SNicholas Piggin
318e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
319e754f4d1SNicholas Piggin	mr	r9,r0
320e754f4d1SNicholas Piggin	bl	system_call_exception
321e754f4d1SNicholas Piggin
322e754f4d1SNicholas Piggin.Lsyscall_exit:
323e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
324e754f4d1SNicholas Piggin	li	r5,0 /* !scv */
325e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
32613799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
3279b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
32813799748SNicholas Piggin.Lsyscall_rst_start:
32913799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
33013799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
33113799748SNicholas Piggin	bne-	syscall_restart
3329b69d48cSNicholas Piggin#endif
33313799748SNicholas Piggin	li	r11,IRQS_ENABLED
33413799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
33513799748SNicholas Piggin	li	r11,0
33613799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
337e754f4d1SNicholas Piggin
338e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
339e754f4d1SNicholas Piggin	ld	r6,_LINK(r1)
340e754f4d1SNicholas Piggin	mtlr	r6
341e754f4d1SNicholas Piggin
342e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
343e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
344e754f4d1SNicholas Piggin	cmpdi	r4,0
345e754f4d1SNicholas Piggin	bne	1f
346e754f4d1SNicholas Piggin	li	r4,0
347e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
348e754f4d1SNicholas Piggin#endif
349e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
350e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
351e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
352e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
353e754f4d1SNicholas Piggin1:
354e754f4d1SNicholas Piggin	DEBUG_SRR_VALID srr
355e754f4d1SNicholas Piggin
356e754f4d1SNicholas PigginBEGIN_FTR_SECTION
357e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
358e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
359e754f4d1SNicholas Piggin
360e754f4d1SNicholas Piggin	cmpdi	r3,0
361e754f4d1SNicholas Piggin	bne	.Lsyscall_restore_regs
362e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
363e754f4d1SNicholas Piggin	li	r0,0
364e754f4d1SNicholas Piggin	li	r4,0
365e754f4d1SNicholas Piggin	li	r5,0
366e754f4d1SNicholas Piggin	li	r6,0
367e754f4d1SNicholas Piggin	li	r7,0
368e754f4d1SNicholas Piggin	li	r8,0
369e754f4d1SNicholas Piggin	li	r9,0
370e754f4d1SNicholas Piggin	li	r10,0
371e754f4d1SNicholas Piggin	li	r11,0
372e754f4d1SNicholas Piggin	li	r12,0
373e754f4d1SNicholas Piggin	mtctr	r0
374e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
375e754f4d1SNicholas Piggin.Lsyscall_restore_regs_cont:
376e754f4d1SNicholas Piggin
377e754f4d1SNicholas PigginBEGIN_FTR_SECTION
378e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
379e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
380e754f4d1SNicholas Piggin
381e754f4d1SNicholas Piggin	/*
382e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
383e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
384e754f4d1SNicholas Piggin	 */
385e754f4d1SNicholas Piggin	mtcr	r2
386e754f4d1SNicholas Piggin	ld	r2,GPR2(r1)
387e754f4d1SNicholas Piggin	ld	r3,GPR3(r1)
388e754f4d1SNicholas Piggin	ld	r13,GPR13(r1)
389e754f4d1SNicholas Piggin	ld	r1,GPR1(r1)
390e754f4d1SNicholas Piggin	RFI_TO_USER
391e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
392e754f4d1SNicholas Piggin
393e754f4d1SNicholas Piggin.Lsyscall_restore_regs:
394e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
395e754f4d1SNicholas Piggin	ld	r4,_XER(r1)
396e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
397e754f4d1SNicholas Piggin	mtctr	r3
398e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r4
399e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
400e754f4d1SNicholas Piggin	REST_8GPRS(4, r1)
401e754f4d1SNicholas Piggin	ld	r12,GPR12(r1)
402e754f4d1SNicholas Piggin	b	.Lsyscall_restore_regs_cont
40313799748SNicholas Piggin.Lsyscall_rst_end:
40413799748SNicholas Piggin
4059b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
40613799748SNicholas Pigginsyscall_restart:
40798798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_restart)
40813799748SNicholas Piggin	GET_PACA(r13)
40913799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
41013799748SNicholas Piggin	ld	r2,PACATOC(r13)
41113799748SNicholas Piggin	ld	r3,RESULT(r1)
41213799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
41313799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
41413799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
41513799748SNicholas Piggin	bl	syscall_exit_restart
41613799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
41713799748SNicholas Piggin	b	.Lsyscall_rst_start
418325678fdSNicholas Piggin1:
41913799748SNicholas Piggin
420325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
42113799748SNicholas PigginRESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
4229b69d48cSNicholas Piggin#endif
423e754f4d1SNicholas Piggin
424e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
42513799748SNicholas Piggintabort_syscall:
42698798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(tabort_syscall)
427e754f4d1SNicholas Piggin	/* Firstly we need to enable TM in the kernel */
428e754f4d1SNicholas Piggin	mfmsr	r10
429e754f4d1SNicholas Piggin	li	r9, 1
430e754f4d1SNicholas Piggin	rldimi	r10, r9, MSR_TM_LG, 63-MSR_TM_LG
431e754f4d1SNicholas Piggin	mtmsrd	r10, 0
432e754f4d1SNicholas Piggin
433e754f4d1SNicholas Piggin	/* tabort, this dooms the transaction, nothing else */
434e754f4d1SNicholas Piggin	li	r9, (TM_CAUSE_SYSCALL|TM_CAUSE_PERSISTENT)
435e754f4d1SNicholas Piggin	TABORT(R9)
436e754f4d1SNicholas Piggin
437e754f4d1SNicholas Piggin	/*
438e754f4d1SNicholas Piggin	 * Return directly to userspace. We have corrupted user register state,
439e754f4d1SNicholas Piggin	 * but userspace will never see that register state. Execution will
440e754f4d1SNicholas Piggin	 * resume after the tbegin of the aborted transaction with the
441e754f4d1SNicholas Piggin	 * checkpointed register state.
442e754f4d1SNicholas Piggin	 */
443e754f4d1SNicholas Piggin	li	r9, MSR_RI
444e754f4d1SNicholas Piggin	andc	r10, r10, r9
445e754f4d1SNicholas Piggin	mtmsrd	r10, 1
446e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0, r11
447e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1, r12
448e754f4d1SNicholas Piggin	RFI_TO_USER
449e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
450e754f4d1SNicholas Piggin#endif
451e754f4d1SNicholas Piggin
452e754f4d1SNicholas Piggin	/*
453e754f4d1SNicholas Piggin	 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
454e754f4d1SNicholas Piggin	 * touched, no exit work created, then this can be used.
455e754f4d1SNicholas Piggin	 */
456e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
457e754f4d1SNicholas Piggin	.globl fast_interrupt_return_srr
458e754f4d1SNicholas Pigginfast_interrupt_return_srr:
459e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
460e754f4d1SNicholas Piggin	kuap_check_amr r3, r4
461e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
462e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_PR
463e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
46413799748SNicholas Piggin	beq	1f
46513799748SNicholas Piggin	kuap_user_restore r3, r4
46613799748SNicholas Piggin	b	.Lfast_user_interrupt_return_srr
46713799748SNicholas Piggin1:	kuap_kernel_restore r3, r4
468e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_RI
469e754f4d1SNicholas Piggin	li	r3,0 /* 0 return value, no EMULATE_STACK_STORE */
470e754f4d1SNicholas Piggin	bne+	.Lfast_kernel_interrupt_return_srr
471e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
472e754f4d1SNicholas Piggin	bl	unrecoverable_exception
473e754f4d1SNicholas Piggin	b	. /* should not get here */
474e754f4d1SNicholas Piggin#else
475e754f4d1SNicholas Piggin	bne	.Lfast_user_interrupt_return_srr
476e754f4d1SNicholas Piggin	b	.Lfast_kernel_interrupt_return_srr
477e754f4d1SNicholas Piggin#endif
478e754f4d1SNicholas Piggin
479e754f4d1SNicholas Piggin.macro interrupt_return_macro srr
480e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
481e754f4d1SNicholas Piggin	.globl interrupt_return_\srr
482e754f4d1SNicholas Piggininterrupt_return_\srr\():
483e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
484e754f4d1SNicholas Piggin	ld	r4,_MSR(r1)
485e754f4d1SNicholas Piggin	andi.	r0,r4,MSR_PR
486c59458b0SNicholas Piggin	beq	interrupt_return_\srr\()_kernel
487c59458b0SNicholas Piggininterrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */
488c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user)
489e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
490e754f4d1SNicholas Piggin	bl	interrupt_exit_user_prepare
491e754f4d1SNicholas Piggin	cmpdi	r3,0
492e754f4d1SNicholas Piggin	bne-	.Lrestore_nvgprs_\srr
49313799748SNicholas Piggin.Lrestore_nvgprs_\srr\()_cont:
49413799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
4959b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
49613799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_start:
49713799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
49813799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
49913799748SNicholas Piggin	bne-	interrupt_return_\srr\()_user_restart
5009b69d48cSNicholas Piggin#endif
50113799748SNicholas Piggin	li	r11,IRQS_ENABLED
50213799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
50313799748SNicholas Piggin	li	r11,0
50413799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
505e754f4d1SNicholas Piggin
506e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_\srr\():
507e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
508e754f4d1SNicholas Piggin	.ifc \srr,srr
509e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
510e754f4d1SNicholas Piggin	.else
511e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
512e754f4d1SNicholas Piggin	.endif
513e754f4d1SNicholas Piggin	cmpdi	r4,0
514e754f4d1SNicholas Piggin	li	r4,0
515e754f4d1SNicholas Piggin	bne	1f
516e754f4d1SNicholas Piggin#endif
517e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
518e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
519e754f4d1SNicholas Piggin	.ifc \srr,srr
520e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
521e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
522e754f4d1SNicholas Piggin1:
523e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
524e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
525e754f4d1SNicholas Piggin#endif
526e754f4d1SNicholas Piggin	.else
527e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
528e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
529e754f4d1SNicholas Piggin1:
530e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
531e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
532e754f4d1SNicholas Piggin#endif
533e754f4d1SNicholas Piggin	.endif
534e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
535e754f4d1SNicholas Piggin
53613799748SNicholas Piggin#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
53713799748SNicholas Piggin	lbz	r4,PACAIRQSOFTMASK(r13)
53813799748SNicholas Piggin	tdnei	r4,IRQS_ENABLED
53913799748SNicholas Piggin#endif
54013799748SNicholas Piggin
54113799748SNicholas PigginBEGIN_FTR_SECTION
54213799748SNicholas Piggin	ld	r10,_PPR(r1)
54313799748SNicholas Piggin	mtspr	SPRN_PPR,r10
54413799748SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
54513799748SNicholas Piggin
546e754f4d1SNicholas PigginBEGIN_FTR_SECTION
547e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
548e754f4d1SNicholas PigginFTR_SECTION_ELSE
549e754f4d1SNicholas Piggin	ldarx	r0,0,r1
550e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
551e754f4d1SNicholas Piggin
552e754f4d1SNicholas Piggin	ld	r3,_CCR(r1)
553e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
554e754f4d1SNicholas Piggin	ld	r5,_CTR(r1)
555e754f4d1SNicholas Piggin	ld	r6,_XER(r1)
556e754f4d1SNicholas Piggin	li	r0,0
557e754f4d1SNicholas Piggin
558e754f4d1SNicholas Piggin	REST_4GPRS(7, r1)
559e754f4d1SNicholas Piggin	REST_2GPRS(11, r1)
560e754f4d1SNicholas Piggin	REST_GPR(13, r1)
561e754f4d1SNicholas Piggin
562e754f4d1SNicholas Piggin	mtcr	r3
563e754f4d1SNicholas Piggin	mtlr	r4
564e754f4d1SNicholas Piggin	mtctr	r5
565e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r6
566e754f4d1SNicholas Piggin
567e754f4d1SNicholas Piggin	REST_4GPRS(2, r1)
568e754f4d1SNicholas Piggin	REST_GPR(6, r1)
569e754f4d1SNicholas Piggin	REST_GPR(0, r1)
570e754f4d1SNicholas Piggin	REST_GPR(1, r1)
571e754f4d1SNicholas Piggin	.ifc \srr,srr
572e754f4d1SNicholas Piggin	RFI_TO_USER
573e754f4d1SNicholas Piggin	.else
574e754f4d1SNicholas Piggin	HRFI_TO_USER
575e754f4d1SNicholas Piggin	.endif
576e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
57713799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_end:
578e754f4d1SNicholas Piggin
579e754f4d1SNicholas Piggin.Lrestore_nvgprs_\srr\():
580e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
58113799748SNicholas Piggin	b	.Lrestore_nvgprs_\srr\()_cont
58213799748SNicholas Piggin
5839b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
58413799748SNicholas Piggininterrupt_return_\srr\()_user_restart:
58598798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user_restart)
58613799748SNicholas Piggin	GET_PACA(r13)
58713799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
58813799748SNicholas Piggin	ld	r2,PACATOC(r13)
58913799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
59013799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
59113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
59213799748SNicholas Piggin	bl	interrupt_exit_user_restart
59313799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
59413799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_user_rst_start
595325678fdSNicholas Piggin1:
59613799748SNicholas Piggin
597325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_user_rst_start, 1b)
59813799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
5999b69d48cSNicholas Piggin#endif
600e754f4d1SNicholas Piggin
601e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
602c59458b0SNicholas Piggininterrupt_return_\srr\()_kernel:
603c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
604e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
605e754f4d1SNicholas Piggin	bl	interrupt_exit_kernel_prepare
606e754f4d1SNicholas Piggin
60713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
60813799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_start:
60913799748SNicholas Piggin	ld	r11,SOFTE(r1)
61013799748SNicholas Piggin	cmpwi	r11,IRQS_ENABLED
61113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
61213799748SNicholas Piggin	bne	1f
6139b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
61413799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
61513799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
61613799748SNicholas Piggin	bne-	interrupt_return_\srr\()_kernel_restart
6179b69d48cSNicholas Piggin#endif
61813799748SNicholas Piggin	li	r11,0
61913799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
62013799748SNicholas Piggin1:
62113799748SNicholas Piggin
622e754f4d1SNicholas Piggin.Lfast_kernel_interrupt_return_\srr\():
623e754f4d1SNicholas Piggin	cmpdi	cr1,r3,0
624e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
625e754f4d1SNicholas Piggin	.ifc \srr,srr
626e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
627e754f4d1SNicholas Piggin	.else
628e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
629e754f4d1SNicholas Piggin	.endif
630e754f4d1SNicholas Piggin	cmpdi	r4,0
631e754f4d1SNicholas Piggin	li	r4,0
632e754f4d1SNicholas Piggin	bne	1f
633e754f4d1SNicholas Piggin#endif
634e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
635e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
636e754f4d1SNicholas Piggin	.ifc \srr,srr
637e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
638e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
639e754f4d1SNicholas Piggin1:
640e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
641e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
642e754f4d1SNicholas Piggin#endif
643e754f4d1SNicholas Piggin	.else
644e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
645e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
646e754f4d1SNicholas Piggin1:
647e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
648e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
649e754f4d1SNicholas Piggin#endif
650e754f4d1SNicholas Piggin	.endif
651e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
652e754f4d1SNicholas Piggin
653e754f4d1SNicholas PigginBEGIN_FTR_SECTION
654e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
655e754f4d1SNicholas PigginFTR_SECTION_ELSE
656e754f4d1SNicholas Piggin	ldarx	r0,0,r1
657e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
658e754f4d1SNicholas Piggin
659e754f4d1SNicholas Piggin	ld	r3,_LINK(r1)
660e754f4d1SNicholas Piggin	ld	r4,_CTR(r1)
661e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
662e754f4d1SNicholas Piggin	ld	r6,_CCR(r1)
663e754f4d1SNicholas Piggin	li	r0,0
664e754f4d1SNicholas Piggin
665e754f4d1SNicholas Piggin	REST_4GPRS(7, r1)
666e754f4d1SNicholas Piggin	REST_2GPRS(11, r1)
667e754f4d1SNicholas Piggin
668e754f4d1SNicholas Piggin	mtlr	r3
669e754f4d1SNicholas Piggin	mtctr	r4
670e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
671e754f4d1SNicholas Piggin
672e754f4d1SNicholas Piggin	/*
673e754f4d1SNicholas Piggin	 * Leaving a stale exception_marker on the stack can confuse
674e754f4d1SNicholas Piggin	 * the reliable stack unwinder later on. Clear it.
675e754f4d1SNicholas Piggin	 */
676e754f4d1SNicholas Piggin	std	r0,STACK_FRAME_OVERHEAD-16(r1)
677e754f4d1SNicholas Piggin
678e754f4d1SNicholas Piggin	REST_4GPRS(2, r1)
679e754f4d1SNicholas Piggin
680e754f4d1SNicholas Piggin	bne-	cr1,1f /* emulate stack store */
681e754f4d1SNicholas Piggin	mtcr	r6
682e754f4d1SNicholas Piggin	REST_GPR(6, r1)
683e754f4d1SNicholas Piggin	REST_GPR(0, r1)
684e754f4d1SNicholas Piggin	REST_GPR(1, r1)
685e754f4d1SNicholas Piggin	.ifc \srr,srr
686e754f4d1SNicholas Piggin	RFI_TO_KERNEL
687e754f4d1SNicholas Piggin	.else
688e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
689e754f4d1SNicholas Piggin	.endif
690e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
691e754f4d1SNicholas Piggin
692e754f4d1SNicholas Piggin1:	/*
693e754f4d1SNicholas Piggin	 * Emulate stack store with update. New r1 value was already calculated
694e754f4d1SNicholas Piggin	 * and updated in our interrupt regs by emulate_loadstore, but we can't
695e754f4d1SNicholas Piggin	 * store the previous value of r1 to the stack before re-loading our
696e754f4d1SNicholas Piggin	 * registers from it, otherwise they could be clobbered.  Use
697e754f4d1SNicholas Piggin	 * PACA_EXGEN as temporary storage to hold the store data, as
698e754f4d1SNicholas Piggin	 * interrupts are disabled here so it won't be clobbered.
699e754f4d1SNicholas Piggin	 */
700e754f4d1SNicholas Piggin	mtcr	r6
701e754f4d1SNicholas Piggin	std	r9,PACA_EXGEN+0(r13)
702e754f4d1SNicholas Piggin	addi	r9,r1,INT_FRAME_SIZE /* get original r1 */
703e754f4d1SNicholas Piggin	REST_GPR(6, r1)
704e754f4d1SNicholas Piggin	REST_GPR(0, r1)
705e754f4d1SNicholas Piggin	REST_GPR(1, r1)
706e754f4d1SNicholas Piggin	std	r9,0(r1) /* perform store component of stdu */
707e754f4d1SNicholas Piggin	ld	r9,PACA_EXGEN+0(r13)
708e754f4d1SNicholas Piggin
709e754f4d1SNicholas Piggin	.ifc \srr,srr
710e754f4d1SNicholas Piggin	RFI_TO_KERNEL
711e754f4d1SNicholas Piggin	.else
712e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
713e754f4d1SNicholas Piggin	.endif
714e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
71513799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_end:
71613799748SNicholas Piggin
7179b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
71813799748SNicholas Piggininterrupt_return_\srr\()_kernel_restart:
71998798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel_restart)
72013799748SNicholas Piggin	GET_PACA(r13)
72113799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
72213799748SNicholas Piggin	ld	r2,PACATOC(r13)
72313799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
72413799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
72513799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
72613799748SNicholas Piggin	bl	interrupt_exit_kernel_restart
72713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
72813799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_kernel_rst_start
729325678fdSNicholas Piggin1:
73013799748SNicholas Piggin
731325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, 1b)
73213799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
7339b69d48cSNicholas Piggin#endif
73413799748SNicholas Piggin
735e754f4d1SNicholas Piggin.endm
736e754f4d1SNicholas Piggin
737e754f4d1SNicholas Piggininterrupt_return_macro srr
738e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
739e754f4d1SNicholas Piggininterrupt_return_macro hsrr
7409d1988caSNicholas Piggin
7419d1988caSNicholas Piggin	.globl __end_soft_masked
7429d1988caSNicholas Piggin__end_soft_masked:
7439d1988caSNicholas PigginDEFINE_FIXED_SYMBOL(__end_soft_masked)
7449b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
745*91fc46ecSNicholas Piggin
746*91fc46ecSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
747*91fc46ecSNicholas Piggin_GLOBAL(ret_from_fork_scv)
748*91fc46ecSNicholas Piggin	bl	schedule_tail
749*91fc46ecSNicholas Piggin	REST_NVGPRS(r1)
750*91fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
751*91fc46ecSNicholas Piggin	b	.Lsyscall_vectored_common_exit
752*91fc46ecSNicholas Piggin#endif
753*91fc46ecSNicholas Piggin
754*91fc46ecSNicholas Piggin_GLOBAL(ret_from_fork)
755*91fc46ecSNicholas Piggin	bl	schedule_tail
756*91fc46ecSNicholas Piggin	REST_NVGPRS(r1)
757*91fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
758*91fc46ecSNicholas Piggin	b	.Lsyscall_exit
759*91fc46ecSNicholas Piggin
760*91fc46ecSNicholas Piggin_GLOBAL(ret_from_kernel_thread)
761*91fc46ecSNicholas Piggin	bl	schedule_tail
762*91fc46ecSNicholas Piggin	REST_NVGPRS(r1)
763*91fc46ecSNicholas Piggin	mtctr	r14
764*91fc46ecSNicholas Piggin	mr	r3,r15
765*91fc46ecSNicholas Piggin#ifdef PPC64_ELF_ABI_v2
766*91fc46ecSNicholas Piggin	mr	r12,r14
767*91fc46ecSNicholas Piggin#endif
768*91fc46ecSNicholas Piggin	bctrl
769*91fc46ecSNicholas Piggin	li	r3,0
770*91fc46ecSNicholas Piggin	b	.Lsyscall_exit
771