xref: /openbmc/linux/arch/powerpc/kernel/interrupt_64.S (revision 7d40aff8213c92e64a1576ba9dfebcd201c0564d)
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
16e754f4d1SNicholas Piggin	.section	".toc","aw"
17e754f4d1SNicholas PigginSYS_CALL_TABLE:
18e754f4d1SNicholas Piggin	.tc sys_call_table[TC],sys_call_table
19e754f4d1SNicholas Piggin
20e754f4d1SNicholas Piggin#ifdef CONFIG_COMPAT
21e754f4d1SNicholas PigginCOMPAT_SYS_CALL_TABLE:
22e754f4d1SNicholas Piggin	.tc compat_sys_call_table[TC],compat_sys_call_table
23e754f4d1SNicholas Piggin#endif
24e754f4d1SNicholas Piggin	.previous
25e754f4d1SNicholas Piggin
26e754f4d1SNicholas Piggin	.align 7
27e754f4d1SNicholas Piggin
28e754f4d1SNicholas Piggin.macro DEBUG_SRR_VALID srr
29e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_RFI_SRR_DEBUG
30e754f4d1SNicholas Piggin	.ifc \srr,srr
31e754f4d1SNicholas Piggin	mfspr	r11,SPRN_SRR0
32e754f4d1SNicholas Piggin	ld	r12,_NIP(r1)
33aee101d7SNicholas Piggin	clrrdi  r11,r11,2
34314f6c23SMichael Ellerman	clrrdi  r12,r12,2
35e754f4d1SNicholas Piggin100:	tdne	r11,r12
36fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
37e754f4d1SNicholas Piggin	mfspr	r11,SPRN_SRR1
38e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
39e754f4d1SNicholas Piggin100:	tdne	r11,r12
40fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
41e754f4d1SNicholas Piggin	.else
42e754f4d1SNicholas Piggin	mfspr	r11,SPRN_HSRR0
43e754f4d1SNicholas Piggin	ld	r12,_NIP(r1)
44aee101d7SNicholas Piggin	clrrdi  r11,r11,2
45314f6c23SMichael Ellerman	clrrdi  r12,r12,2
46e754f4d1SNicholas Piggin100:	tdne	r11,r12
47fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
48e754f4d1SNicholas Piggin	mfspr	r11,SPRN_HSRR1
49e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
50e754f4d1SNicholas Piggin100:	tdne	r11,r12
51fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
52e754f4d1SNicholas Piggin	.endif
53e754f4d1SNicholas Piggin#endif
54e754f4d1SNicholas Piggin.endm
55e754f4d1SNicholas Piggin
56e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
57e754f4d1SNicholas Piggin.macro system_call_vectored name trapnr
58e754f4d1SNicholas Piggin	.globl system_call_vectored_\name
59e754f4d1SNicholas Pigginsystem_call_vectored_\name:
60e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
61e754f4d1SNicholas Piggin	SCV_INTERRUPT_TO_KERNEL
62e754f4d1SNicholas Piggin	mr	r10,r1
63e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
64e754f4d1SNicholas Piggin	std	r10,0(r1)
65e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
66e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
67e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
68e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
69e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
70e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
71e754f4d1SNicholas Piggin	mfcr	r12
72e754f4d1SNicholas Piggin	li	r11,0
73e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
74e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
75e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
76e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
77e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
78e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
79e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
80e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
81e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
82e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
83e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
84e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
85e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
86e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
87e754f4d1SNicholas Piggin	std	r11,_XER(r1)
88e754f4d1SNicholas Piggin	std	r11,_LINK(r1)
89e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
90e754f4d1SNicholas Piggin
91e754f4d1SNicholas Piggin	li	r11,\trapnr
92e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
93e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
94e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
95e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
96e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
97e754f4d1SNicholas Piggin
98e754f4d1SNicholas PigginBEGIN_FTR_SECTION
99e754f4d1SNicholas Piggin	HMT_MEDIUM
100e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
101e754f4d1SNicholas Piggin
102e754f4d1SNicholas Piggin	/*
103e754f4d1SNicholas Piggin	 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
104e754f4d1SNicholas Piggin	 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
105e754f4d1SNicholas Piggin	 * and interrupts may be masked and pending already.
106e754f4d1SNicholas Piggin	 * system_call_exception() will call trace_hardirqs_off() which means
107e754f4d1SNicholas Piggin	 * interrupts could already have been blocked before trace_hardirqs_off,
108e754f4d1SNicholas Piggin	 * but this is the best we can do.
109e754f4d1SNicholas Piggin	 */
110e754f4d1SNicholas Piggin
111e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
112e754f4d1SNicholas Piggin	mr	r9,r0
113e754f4d1SNicholas Piggin	bl	system_call_exception
114e754f4d1SNicholas Piggin
115e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_exit:
116e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
117e754f4d1SNicholas Piggin	li	r5,1 /* scv */
118e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
11913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
12013799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_start:
12113799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
12213799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
12313799748SNicholas Piggin	bne-	syscall_vectored_\name\()_restart
12413799748SNicholas Piggin	li	r11,IRQS_ENABLED
12513799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
12613799748SNicholas Piggin	li	r11,0
12713799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
128e754f4d1SNicholas Piggin
129e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
130e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
131e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
132e754f4d1SNicholas Piggin
133e754f4d1SNicholas PigginBEGIN_FTR_SECTION
134e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
135e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
136e754f4d1SNicholas Piggin
137e754f4d1SNicholas PigginBEGIN_FTR_SECTION
138e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
139e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
140e754f4d1SNicholas Piggin
141e754f4d1SNicholas Piggin	cmpdi	r3,0
142e754f4d1SNicholas Piggin	bne	.Lsyscall_vectored_\name\()_restore_regs
143e754f4d1SNicholas Piggin
144e754f4d1SNicholas Piggin	/* rfscv returns with LR->NIA and CTR->MSR */
145e754f4d1SNicholas Piggin	mtlr	r4
146e754f4d1SNicholas Piggin	mtctr	r5
147e754f4d1SNicholas Piggin
148e754f4d1SNicholas Piggin	/* Could zero these as per ABI, but we may consider a stricter ABI
149e754f4d1SNicholas Piggin	 * which preserves these if libc implementations can benefit, so
150e754f4d1SNicholas Piggin	 * restore them for now until further measurement is done. */
151e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
152e754f4d1SNicholas Piggin	ld	r4,GPR4(r1)
153e754f4d1SNicholas Piggin	ld	r5,GPR5(r1)
154e754f4d1SNicholas Piggin	ld	r6,GPR6(r1)
155e754f4d1SNicholas Piggin	ld	r7,GPR7(r1)
156e754f4d1SNicholas Piggin	ld	r8,GPR8(r1)
157e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
158e754f4d1SNicholas Piggin	li	r9,0
159e754f4d1SNicholas Piggin	li	r10,0
160e754f4d1SNicholas Piggin	li	r11,0
161e754f4d1SNicholas Piggin	li	r12,0
162e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
163e754f4d1SNicholas Piggin
164e754f4d1SNicholas Piggin	/*
165e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
166e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
167e754f4d1SNicholas Piggin	 */
168e754f4d1SNicholas Piggin	mtcr	r2
169aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
170aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
171aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
172e754f4d1SNicholas Piggin	RFSCV_TO_USER
173e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
174e754f4d1SNicholas Piggin
175e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_restore_regs:
176e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
177e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
178e754f4d1SNicholas Piggin
179e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
180e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
181e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
182e754f4d1SNicholas Piggin
183e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
184e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
185e754f4d1SNicholas Piggin	mtcr	r2
186e754f4d1SNicholas Piggin	mtctr	r3
187e754f4d1SNicholas Piggin	mtlr	r4
188e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
189aebd1fb4SNicholas Piggin	REST_GPRS(2, 13, r1)
190aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
191e754f4d1SNicholas Piggin	RFI_TO_USER
19213799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_end:
19313799748SNicholas Piggin
19413799748SNicholas Pigginsyscall_vectored_\name\()_restart:
19598798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart)
19613799748SNicholas Piggin	GET_PACA(r13)
19713799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
19813799748SNicholas Piggin	ld	r2,PACATOC(r13)
19913799748SNicholas Piggin	ld	r3,RESULT(r1)
20013799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
20113799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
20213799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
20313799748SNicholas Piggin	bl	syscall_exit_restart
20413799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
20513799748SNicholas Piggin	b	.Lsyscall_vectored_\name\()_rst_start
206325678fdSNicholas Piggin1:
20713799748SNicholas Piggin
208325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)
20913799748SNicholas PigginRESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
21013799748SNicholas Piggin
211e754f4d1SNicholas Piggin.endm
212e754f4d1SNicholas Piggin
213e754f4d1SNicholas Pigginsystem_call_vectored common 0x3000
21413799748SNicholas Piggin
215e754f4d1SNicholas Piggin/*
216e754f4d1SNicholas Piggin * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
217e754f4d1SNicholas Piggin * which is tested by system_call_exception when r0 is -1 (as set by vector
218e754f4d1SNicholas Piggin * entry code).
219e754f4d1SNicholas Piggin */
220e754f4d1SNicholas Pigginsystem_call_vectored sigill 0x7ff0
221e754f4d1SNicholas Piggin
2229b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
223e754f4d1SNicholas Piggin
224e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
225e754f4d1SNicholas Piggin	.globl system_call_common_real
226e754f4d1SNicholas Pigginsystem_call_common_real:
22798798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common_real)
228e754f4d1SNicholas Piggin	ld	r10,PACAKMSR(r13)	/* get MSR value for kernel */
229e754f4d1SNicholas Piggin	mtmsrd	r10
230e754f4d1SNicholas Piggin
231e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
232e754f4d1SNicholas Piggin	.globl system_call_common
233e754f4d1SNicholas Pigginsystem_call_common:
234e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common)
235e754f4d1SNicholas Piggin	mr	r10,r1
236e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
237e754f4d1SNicholas Piggin	std	r10,0(r1)
238e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
239e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
240e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
241e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
242e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
243e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_FSL_BOOK3E
244e754f4d1SNicholas PigginSTART_BTB_FLUSH_SECTION
245e754f4d1SNicholas Piggin	BTB_FLUSH(r10)
246e754f4d1SNicholas PigginEND_BTB_FLUSH_SECTION
247e754f4d1SNicholas Piggin#endif
248e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
249e754f4d1SNicholas Piggin	mfcr	r12
250e754f4d1SNicholas Piggin	li	r11,0
251e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
252e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
253e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
254e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
255e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
256e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
257e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
258e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
259e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
260e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
261e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
262e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
263e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
264e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
265e754f4d1SNicholas Piggin	std	r11,_XER(r1)
266e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
267e754f4d1SNicholas Piggin	mflr	r10
268e754f4d1SNicholas Piggin
269e754f4d1SNicholas Piggin	/*
270e754f4d1SNicholas Piggin	 * This clears CR0.SO (bit 28), which is the error indication on
271e754f4d1SNicholas Piggin	 * return from this system call.
272e754f4d1SNicholas Piggin	 */
273e754f4d1SNicholas Piggin	rldimi	r12,r11,28,(63-28)
274e754f4d1SNicholas Piggin	li	r11,0xc00
275e754f4d1SNicholas Piggin	std	r10,_LINK(r1)
276e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
277e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
278e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
279e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
280e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
281e754f4d1SNicholas Piggin
282e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
283e754f4d1SNicholas Piggin	li	r11,1
284e754f4d1SNicholas Piggin	stb	r11,PACASRR_VALID(r13)
285e754f4d1SNicholas Piggin#endif
286e754f4d1SNicholas Piggin
287e754f4d1SNicholas Piggin	/*
288e754f4d1SNicholas Piggin	 * We always enter kernel from userspace with irq soft-mask enabled and
289e754f4d1SNicholas Piggin	 * nothing pending. system_call_exception() will call
290e754f4d1SNicholas Piggin	 * trace_hardirqs_off().
291e754f4d1SNicholas Piggin	 */
292e754f4d1SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
293e754f4d1SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
2941df3af6dSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
2951df3af6dSNicholas Piggin	li	r12,-1 /* Set MSR_EE and MSR_RI */
296dd152f70SNicholas Piggin	mtmsrd	r12,1
2971df3af6dSNicholas Piggin#else
2981df3af6dSNicholas Piggin	wrteei	1
2991df3af6dSNicholas Piggin#endif
300e754f4d1SNicholas Piggin
301e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
302e754f4d1SNicholas Piggin	mr	r9,r0
303e754f4d1SNicholas Piggin	bl	system_call_exception
304e754f4d1SNicholas Piggin
305e754f4d1SNicholas Piggin.Lsyscall_exit:
306e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
307e754f4d1SNicholas Piggin	li	r5,0 /* !scv */
308e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
30913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
3109b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
31113799748SNicholas Piggin.Lsyscall_rst_start:
31213799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
31313799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
31413799748SNicholas Piggin	bne-	syscall_restart
3159b69d48cSNicholas Piggin#endif
31613799748SNicholas Piggin	li	r11,IRQS_ENABLED
31713799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
31813799748SNicholas Piggin	li	r11,0
31913799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
320e754f4d1SNicholas Piggin
321e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
322e754f4d1SNicholas Piggin	ld	r6,_LINK(r1)
323e754f4d1SNicholas Piggin	mtlr	r6
324e754f4d1SNicholas Piggin
325e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
326e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
327e754f4d1SNicholas Piggin	cmpdi	r4,0
328e754f4d1SNicholas Piggin	bne	1f
329e754f4d1SNicholas Piggin	li	r4,0
330e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
331e754f4d1SNicholas Piggin#endif
332e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
333e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
334e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
335e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
336e754f4d1SNicholas Piggin1:
337e754f4d1SNicholas Piggin	DEBUG_SRR_VALID srr
338e754f4d1SNicholas Piggin
339e754f4d1SNicholas PigginBEGIN_FTR_SECTION
340e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
341e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
342e754f4d1SNicholas Piggin
343e754f4d1SNicholas Piggin	cmpdi	r3,0
344e754f4d1SNicholas Piggin	bne	.Lsyscall_restore_regs
345e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
346e754f4d1SNicholas Piggin	li	r0,0
347e754f4d1SNicholas Piggin	li	r4,0
348e754f4d1SNicholas Piggin	li	r5,0
349e754f4d1SNicholas Piggin	li	r6,0
350e754f4d1SNicholas Piggin	li	r7,0
351e754f4d1SNicholas Piggin	li	r8,0
352e754f4d1SNicholas Piggin	li	r9,0
353e754f4d1SNicholas Piggin	li	r10,0
354e754f4d1SNicholas Piggin	li	r11,0
355e754f4d1SNicholas Piggin	li	r12,0
356e754f4d1SNicholas Piggin	mtctr	r0
357e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
358e754f4d1SNicholas Piggin.Lsyscall_restore_regs_cont:
359e754f4d1SNicholas Piggin
360e754f4d1SNicholas PigginBEGIN_FTR_SECTION
361e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
362e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
363e754f4d1SNicholas Piggin
364e754f4d1SNicholas Piggin	/*
365e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
366e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
367e754f4d1SNicholas Piggin	 */
368e754f4d1SNicholas Piggin	mtcr	r2
369aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
370aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
371aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
372e754f4d1SNicholas Piggin	RFI_TO_USER
373e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
374e754f4d1SNicholas Piggin
375e754f4d1SNicholas Piggin.Lsyscall_restore_regs:
376e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
377e754f4d1SNicholas Piggin	ld	r4,_XER(r1)
378e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
379e754f4d1SNicholas Piggin	mtctr	r3
380e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r4
381e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
382aebd1fb4SNicholas Piggin	REST_GPRS(4, 12, r1)
383e754f4d1SNicholas Piggin	b	.Lsyscall_restore_regs_cont
38413799748SNicholas Piggin.Lsyscall_rst_end:
38513799748SNicholas Piggin
3869b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
38713799748SNicholas Pigginsyscall_restart:
38898798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_restart)
38913799748SNicholas Piggin	GET_PACA(r13)
39013799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
39113799748SNicholas Piggin	ld	r2,PACATOC(r13)
39213799748SNicholas Piggin	ld	r3,RESULT(r1)
39313799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
39413799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
39513799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
39613799748SNicholas Piggin	bl	syscall_exit_restart
39713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
39813799748SNicholas Piggin	b	.Lsyscall_rst_start
399325678fdSNicholas Piggin1:
40013799748SNicholas Piggin
401325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
40213799748SNicholas PigginRESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
4039b69d48cSNicholas Piggin#endif
404e754f4d1SNicholas Piggin
405e754f4d1SNicholas Piggin	/*
406e754f4d1SNicholas Piggin	 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
407e754f4d1SNicholas Piggin	 * touched, no exit work created, then this can be used.
408e754f4d1SNicholas Piggin	 */
409e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
410e754f4d1SNicholas Piggin	.globl fast_interrupt_return_srr
411e754f4d1SNicholas Pigginfast_interrupt_return_srr:
412e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
413e754f4d1SNicholas Piggin	kuap_check_amr r3, r4
414e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
415e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_PR
416e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
41713799748SNicholas Piggin	beq	1f
41813799748SNicholas Piggin	kuap_user_restore r3, r4
41913799748SNicholas Piggin	b	.Lfast_user_interrupt_return_srr
42013799748SNicholas Piggin1:	kuap_kernel_restore r3, r4
421e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_RI
422e754f4d1SNicholas Piggin	li	r3,0 /* 0 return value, no EMULATE_STACK_STORE */
423e754f4d1SNicholas Piggin	bne+	.Lfast_kernel_interrupt_return_srr
424e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
425e754f4d1SNicholas Piggin	bl	unrecoverable_exception
426e754f4d1SNicholas Piggin	b	. /* should not get here */
427e754f4d1SNicholas Piggin#else
428e754f4d1SNicholas Piggin	bne	.Lfast_user_interrupt_return_srr
429e754f4d1SNicholas Piggin	b	.Lfast_kernel_interrupt_return_srr
430e754f4d1SNicholas Piggin#endif
431e754f4d1SNicholas Piggin
432e754f4d1SNicholas Piggin.macro interrupt_return_macro srr
433e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
434e754f4d1SNicholas Piggin	.globl interrupt_return_\srr
435e754f4d1SNicholas Piggininterrupt_return_\srr\():
436e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
437e754f4d1SNicholas Piggin	ld	r4,_MSR(r1)
438e754f4d1SNicholas Piggin	andi.	r0,r4,MSR_PR
439c59458b0SNicholas Piggin	beq	interrupt_return_\srr\()_kernel
440c59458b0SNicholas Piggininterrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */
441c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user)
442e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
443e754f4d1SNicholas Piggin	bl	interrupt_exit_user_prepare
444e754f4d1SNicholas Piggin	cmpdi	r3,0
445e754f4d1SNicholas Piggin	bne-	.Lrestore_nvgprs_\srr
44613799748SNicholas Piggin.Lrestore_nvgprs_\srr\()_cont:
44713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
4489b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
44913799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_start:
45013799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
45113799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
45213799748SNicholas Piggin	bne-	interrupt_return_\srr\()_user_restart
4539b69d48cSNicholas Piggin#endif
45413799748SNicholas Piggin	li	r11,IRQS_ENABLED
45513799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
45613799748SNicholas Piggin	li	r11,0
45713799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
458e754f4d1SNicholas Piggin
459e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_\srr\():
460e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
461e754f4d1SNicholas Piggin	.ifc \srr,srr
462e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
463e754f4d1SNicholas Piggin	.else
464e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
465e754f4d1SNicholas Piggin	.endif
466e754f4d1SNicholas Piggin	cmpdi	r4,0
467e754f4d1SNicholas Piggin	li	r4,0
468e754f4d1SNicholas Piggin	bne	1f
469e754f4d1SNicholas Piggin#endif
470e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
471e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
472e754f4d1SNicholas Piggin	.ifc \srr,srr
473e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
474e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
475e754f4d1SNicholas Piggin1:
476e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
477e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
478e754f4d1SNicholas Piggin#endif
479e754f4d1SNicholas Piggin	.else
480e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
481e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
482e754f4d1SNicholas Piggin1:
483e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
484e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
485e754f4d1SNicholas Piggin#endif
486e754f4d1SNicholas Piggin	.endif
487e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
488e754f4d1SNicholas Piggin
48913799748SNicholas Piggin#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
49013799748SNicholas Piggin	lbz	r4,PACAIRQSOFTMASK(r13)
49113799748SNicholas Piggin	tdnei	r4,IRQS_ENABLED
49213799748SNicholas Piggin#endif
49313799748SNicholas Piggin
49413799748SNicholas PigginBEGIN_FTR_SECTION
49513799748SNicholas Piggin	ld	r10,_PPR(r1)
49613799748SNicholas Piggin	mtspr	SPRN_PPR,r10
49713799748SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
49813799748SNicholas Piggin
499e754f4d1SNicholas PigginBEGIN_FTR_SECTION
500e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
501e754f4d1SNicholas PigginFTR_SECTION_ELSE
502e754f4d1SNicholas Piggin	ldarx	r0,0,r1
503e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
504e754f4d1SNicholas Piggin
505e754f4d1SNicholas Piggin	ld	r3,_CCR(r1)
506e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
507e754f4d1SNicholas Piggin	ld	r5,_CTR(r1)
508e754f4d1SNicholas Piggin	ld	r6,_XER(r1)
509e754f4d1SNicholas Piggin	li	r0,0
510e754f4d1SNicholas Piggin
511aebd1fb4SNicholas Piggin	REST_GPRS(7, 13, r1)
512e754f4d1SNicholas Piggin
513e754f4d1SNicholas Piggin	mtcr	r3
514e754f4d1SNicholas Piggin	mtlr	r4
515e754f4d1SNicholas Piggin	mtctr	r5
516e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r6
517e754f4d1SNicholas Piggin
518aebd1fb4SNicholas Piggin	REST_GPRS(2, 6, r1)
519e754f4d1SNicholas Piggin	REST_GPR(0, r1)
520e754f4d1SNicholas Piggin	REST_GPR(1, r1)
521e754f4d1SNicholas Piggin	.ifc \srr,srr
522e754f4d1SNicholas Piggin	RFI_TO_USER
523e754f4d1SNicholas Piggin	.else
524e754f4d1SNicholas Piggin	HRFI_TO_USER
525e754f4d1SNicholas Piggin	.endif
526e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
52713799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_end:
528e754f4d1SNicholas Piggin
529e754f4d1SNicholas Piggin.Lrestore_nvgprs_\srr\():
530e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
53113799748SNicholas Piggin	b	.Lrestore_nvgprs_\srr\()_cont
53213799748SNicholas Piggin
5339b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
53413799748SNicholas Piggininterrupt_return_\srr\()_user_restart:
53598798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user_restart)
53613799748SNicholas Piggin	GET_PACA(r13)
53713799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
53813799748SNicholas Piggin	ld	r2,PACATOC(r13)
53913799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
54013799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
54113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
54213799748SNicholas Piggin	bl	interrupt_exit_user_restart
54313799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
54413799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_user_rst_start
545325678fdSNicholas Piggin1:
54613799748SNicholas Piggin
547325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_user_rst_start, 1b)
54813799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
5499b69d48cSNicholas Piggin#endif
550e754f4d1SNicholas Piggin
551e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
552c59458b0SNicholas Piggininterrupt_return_\srr\()_kernel:
553c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
554e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
555e754f4d1SNicholas Piggin	bl	interrupt_exit_kernel_prepare
556e754f4d1SNicholas Piggin
55713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
55813799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_start:
55913799748SNicholas Piggin	ld	r11,SOFTE(r1)
56013799748SNicholas Piggin	cmpwi	r11,IRQS_ENABLED
56113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
56213799748SNicholas Piggin	bne	1f
5639b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
56413799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
56513799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
56613799748SNicholas Piggin	bne-	interrupt_return_\srr\()_kernel_restart
5679b69d48cSNicholas Piggin#endif
56813799748SNicholas Piggin	li	r11,0
56913799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
57013799748SNicholas Piggin1:
57113799748SNicholas Piggin
572e754f4d1SNicholas Piggin.Lfast_kernel_interrupt_return_\srr\():
573e754f4d1SNicholas Piggin	cmpdi	cr1,r3,0
574e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
575e754f4d1SNicholas Piggin	.ifc \srr,srr
576e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
577e754f4d1SNicholas Piggin	.else
578e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
579e754f4d1SNicholas Piggin	.endif
580e754f4d1SNicholas Piggin	cmpdi	r4,0
581e754f4d1SNicholas Piggin	li	r4,0
582e754f4d1SNicholas Piggin	bne	1f
583e754f4d1SNicholas Piggin#endif
584e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
585e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
586e754f4d1SNicholas Piggin	.ifc \srr,srr
587e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
588e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
589e754f4d1SNicholas Piggin1:
590e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
591e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
592e754f4d1SNicholas Piggin#endif
593e754f4d1SNicholas Piggin	.else
594e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
595e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
596e754f4d1SNicholas Piggin1:
597e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
598e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
599e754f4d1SNicholas Piggin#endif
600e754f4d1SNicholas Piggin	.endif
601e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
602e754f4d1SNicholas Piggin
603e754f4d1SNicholas PigginBEGIN_FTR_SECTION
604e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
605e754f4d1SNicholas PigginFTR_SECTION_ELSE
606e754f4d1SNicholas Piggin	ldarx	r0,0,r1
607e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
608e754f4d1SNicholas Piggin
609e754f4d1SNicholas Piggin	ld	r3,_LINK(r1)
610e754f4d1SNicholas Piggin	ld	r4,_CTR(r1)
611e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
612e754f4d1SNicholas Piggin	ld	r6,_CCR(r1)
613e754f4d1SNicholas Piggin	li	r0,0
614e754f4d1SNicholas Piggin
615aebd1fb4SNicholas Piggin	REST_GPRS(7, 12, r1)
616e754f4d1SNicholas Piggin
617e754f4d1SNicholas Piggin	mtlr	r3
618e754f4d1SNicholas Piggin	mtctr	r4
619e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
620e754f4d1SNicholas Piggin
621e754f4d1SNicholas Piggin	/*
622e754f4d1SNicholas Piggin	 * Leaving a stale exception_marker on the stack can confuse
623e754f4d1SNicholas Piggin	 * the reliable stack unwinder later on. Clear it.
624e754f4d1SNicholas Piggin	 */
625e754f4d1SNicholas Piggin	std	r0,STACK_FRAME_OVERHEAD-16(r1)
626e754f4d1SNicholas Piggin
627aebd1fb4SNicholas Piggin	REST_GPRS(2, 5, r1)
628e754f4d1SNicholas Piggin
629e754f4d1SNicholas Piggin	bne-	cr1,1f /* emulate stack store */
630e754f4d1SNicholas Piggin	mtcr	r6
631e754f4d1SNicholas Piggin	REST_GPR(6, r1)
632e754f4d1SNicholas Piggin	REST_GPR(0, r1)
633e754f4d1SNicholas Piggin	REST_GPR(1, r1)
634e754f4d1SNicholas Piggin	.ifc \srr,srr
635e754f4d1SNicholas Piggin	RFI_TO_KERNEL
636e754f4d1SNicholas Piggin	.else
637e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
638e754f4d1SNicholas Piggin	.endif
639e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
640e754f4d1SNicholas Piggin
641e754f4d1SNicholas Piggin1:	/*
642e754f4d1SNicholas Piggin	 * Emulate stack store with update. New r1 value was already calculated
643e754f4d1SNicholas Piggin	 * and updated in our interrupt regs by emulate_loadstore, but we can't
644e754f4d1SNicholas Piggin	 * store the previous value of r1 to the stack before re-loading our
645e754f4d1SNicholas Piggin	 * registers from it, otherwise they could be clobbered.  Use
646e754f4d1SNicholas Piggin	 * PACA_EXGEN as temporary storage to hold the store data, as
647e754f4d1SNicholas Piggin	 * interrupts are disabled here so it won't be clobbered.
648e754f4d1SNicholas Piggin	 */
649e754f4d1SNicholas Piggin	mtcr	r6
650e754f4d1SNicholas Piggin	std	r9,PACA_EXGEN+0(r13)
651e754f4d1SNicholas Piggin	addi	r9,r1,INT_FRAME_SIZE /* get original r1 */
652e754f4d1SNicholas Piggin	REST_GPR(6, r1)
653e754f4d1SNicholas Piggin	REST_GPR(0, r1)
654e754f4d1SNicholas Piggin	REST_GPR(1, r1)
655e754f4d1SNicholas Piggin	std	r9,0(r1) /* perform store component of stdu */
656e754f4d1SNicholas Piggin	ld	r9,PACA_EXGEN+0(r13)
657e754f4d1SNicholas Piggin
658e754f4d1SNicholas Piggin	.ifc \srr,srr
659e754f4d1SNicholas Piggin	RFI_TO_KERNEL
660e754f4d1SNicholas Piggin	.else
661e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
662e754f4d1SNicholas Piggin	.endif
663e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
66413799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_end:
66513799748SNicholas Piggin
6669b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
66713799748SNicholas Piggininterrupt_return_\srr\()_kernel_restart:
66898798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel_restart)
66913799748SNicholas Piggin	GET_PACA(r13)
67013799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
67113799748SNicholas Piggin	ld	r2,PACATOC(r13)
67213799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
67313799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
67413799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
67513799748SNicholas Piggin	bl	interrupt_exit_kernel_restart
67613799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
67713799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_kernel_rst_start
678325678fdSNicholas Piggin1:
67913799748SNicholas Piggin
680325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, 1b)
68113799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
6829b69d48cSNicholas Piggin#endif
68313799748SNicholas Piggin
684e754f4d1SNicholas Piggin.endm
685e754f4d1SNicholas Piggin
686e754f4d1SNicholas Piggininterrupt_return_macro srr
687e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
688e754f4d1SNicholas Piggininterrupt_return_macro hsrr
6899d1988caSNicholas Piggin
6909d1988caSNicholas Piggin	.globl __end_soft_masked
6919d1988caSNicholas Piggin__end_soft_masked:
692d72c4a36SDaniel AxtensDEFINE_FIXED_SYMBOL(__end_soft_masked, text)
6939b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
69491fc46ecSNicholas Piggin
69591fc46ecSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
69691fc46ecSNicholas Piggin_GLOBAL(ret_from_fork_scv)
69791fc46ecSNicholas Piggin	bl	schedule_tail
69891fc46ecSNicholas Piggin	REST_NVGPRS(r1)
69991fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
70091fc46ecSNicholas Piggin	b	.Lsyscall_vectored_common_exit
70191fc46ecSNicholas Piggin#endif
70291fc46ecSNicholas Piggin
70391fc46ecSNicholas Piggin_GLOBAL(ret_from_fork)
70491fc46ecSNicholas Piggin	bl	schedule_tail
70591fc46ecSNicholas Piggin	REST_NVGPRS(r1)
70691fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
70791fc46ecSNicholas Piggin	b	.Lsyscall_exit
70891fc46ecSNicholas Piggin
70991fc46ecSNicholas Piggin_GLOBAL(ret_from_kernel_thread)
71091fc46ecSNicholas Piggin	bl	schedule_tail
71191fc46ecSNicholas Piggin	REST_NVGPRS(r1)
71291fc46ecSNicholas Piggin	mtctr	r14
71391fc46ecSNicholas Piggin	mr	r3,r15
714*7d40aff8SChristophe Leroy#ifdef CONFIG_PPC64_ELF_ABI_V2
71591fc46ecSNicholas Piggin	mr	r12,r14
71691fc46ecSNicholas Piggin#endif
71791fc46ecSNicholas Piggin	bctrl
71891fc46ecSNicholas Piggin	li	r3,0
71991fc46ecSNicholas Piggin	b	.Lsyscall_exit
720