xref: /openbmc/linux/arch/powerpc/kernel/interrupt_64.S (revision 2c27d4a419f627636b8c6038e55acb26df05c391)
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	.align 7
17e754f4d1SNicholas Piggin
18e754f4d1SNicholas Piggin.macro DEBUG_SRR_VALID srr
19e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_RFI_SRR_DEBUG
20e754f4d1SNicholas Piggin	.ifc \srr,srr
21e754f4d1SNicholas Piggin	mfspr	r11,SPRN_SRR0
22e754f4d1SNicholas Piggin	ld	r12,_NIP(r1)
23aee101d7SNicholas Piggin	clrrdi  r11,r11,2
24314f6c23SMichael Ellerman	clrrdi  r12,r12,2
25e754f4d1SNicholas Piggin100:	tdne	r11,r12
26fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
27e754f4d1SNicholas Piggin	mfspr	r11,SPRN_SRR1
28e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
29e754f4d1SNicholas Piggin100:	tdne	r11,r12
30fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
31e754f4d1SNicholas Piggin	.else
32e754f4d1SNicholas Piggin	mfspr	r11,SPRN_HSRR0
33e754f4d1SNicholas Piggin	ld	r12,_NIP(r1)
34aee101d7SNicholas Piggin	clrrdi  r11,r11,2
35314f6c23SMichael Ellerman	clrrdi  r12,r12,2
36e754f4d1SNicholas Piggin100:	tdne	r11,r12
37fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
38e754f4d1SNicholas Piggin	mfspr	r11,SPRN_HSRR1
39e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
40e754f4d1SNicholas Piggin100:	tdne	r11,r12
41fd1eaaaaSMichael Ellerman	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
42e754f4d1SNicholas Piggin	.endif
43e754f4d1SNicholas Piggin#endif
44e754f4d1SNicholas Piggin.endm
45e754f4d1SNicholas Piggin
46e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
47e754f4d1SNicholas Piggin.macro system_call_vectored name trapnr
48e754f4d1SNicholas Piggin	.globl system_call_vectored_\name
49e754f4d1SNicholas Pigginsystem_call_vectored_\name:
50e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
51e754f4d1SNicholas Piggin	SCV_INTERRUPT_TO_KERNEL
52e754f4d1SNicholas Piggin	mr	r10,r1
53e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
54e754f4d1SNicholas Piggin	std	r10,0(r1)
55e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
56e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
57e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
58e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
59e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
60e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
61e754f4d1SNicholas Piggin	mfcr	r12
62e754f4d1SNicholas Piggin	li	r11,0
63e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
64e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
65e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
66e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
67e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
68e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
69e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
70e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
71e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
72e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
73e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
74e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
75e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
76e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
77e754f4d1SNicholas Piggin	std	r11,_XER(r1)
78e754f4d1SNicholas Piggin	std	r11,_LINK(r1)
79e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
80e754f4d1SNicholas Piggin
81e754f4d1SNicholas Piggin	li	r11,\trapnr
82e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
83e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
84*2c27d4a4SRohan McLure	std	r3,ORIG_GPR3(r1)
85e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
86e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
87e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
88e754f4d1SNicholas Piggin
89e754f4d1SNicholas PigginBEGIN_FTR_SECTION
90e754f4d1SNicholas Piggin	HMT_MEDIUM
91e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
92e754f4d1SNicholas Piggin
93e754f4d1SNicholas Piggin	/*
94e754f4d1SNicholas Piggin	 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
95e754f4d1SNicholas Piggin	 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
96e754f4d1SNicholas Piggin	 * and interrupts may be masked and pending already.
97e754f4d1SNicholas Piggin	 * system_call_exception() will call trace_hardirqs_off() which means
98e754f4d1SNicholas Piggin	 * interrupts could already have been blocked before trace_hardirqs_off,
99e754f4d1SNicholas Piggin	 * but this is the best we can do.
100e754f4d1SNicholas Piggin	 */
101e754f4d1SNicholas Piggin
102e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
103e754f4d1SNicholas Piggin	mr	r9,r0
104e754f4d1SNicholas Piggin	bl	system_call_exception
105e754f4d1SNicholas Piggin
106e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_exit:
107e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
108e754f4d1SNicholas Piggin	li	r5,1 /* scv */
109e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
11013799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
11113799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_start:
11213799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
11313799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
11413799748SNicholas Piggin	bne-	syscall_vectored_\name\()_restart
11513799748SNicholas Piggin	li	r11,IRQS_ENABLED
11613799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
11713799748SNicholas Piggin	li	r11,0
11813799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
119e754f4d1SNicholas Piggin
120e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
121e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
122e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
123e754f4d1SNicholas Piggin
124e754f4d1SNicholas PigginBEGIN_FTR_SECTION
125e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
126e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
127e754f4d1SNicholas Piggin
128e754f4d1SNicholas PigginBEGIN_FTR_SECTION
129e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
130e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
131e754f4d1SNicholas Piggin
132e754f4d1SNicholas Piggin	cmpdi	r3,0
133e754f4d1SNicholas Piggin	bne	.Lsyscall_vectored_\name\()_restore_regs
134e754f4d1SNicholas Piggin
135e754f4d1SNicholas Piggin	/* rfscv returns with LR->NIA and CTR->MSR */
136e754f4d1SNicholas Piggin	mtlr	r4
137e754f4d1SNicholas Piggin	mtctr	r5
138e754f4d1SNicholas Piggin
139e754f4d1SNicholas Piggin	/* Could zero these as per ABI, but we may consider a stricter ABI
140e754f4d1SNicholas Piggin	 * which preserves these if libc implementations can benefit, so
141e754f4d1SNicholas Piggin	 * restore them for now until further measurement is done. */
142e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
143e754f4d1SNicholas Piggin	ld	r4,GPR4(r1)
144e754f4d1SNicholas Piggin	ld	r5,GPR5(r1)
145e754f4d1SNicholas Piggin	ld	r6,GPR6(r1)
146e754f4d1SNicholas Piggin	ld	r7,GPR7(r1)
147e754f4d1SNicholas Piggin	ld	r8,GPR8(r1)
148e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
149e754f4d1SNicholas Piggin	li	r9,0
150e754f4d1SNicholas Piggin	li	r10,0
151e754f4d1SNicholas Piggin	li	r11,0
152e754f4d1SNicholas Piggin	li	r12,0
153e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
154e754f4d1SNicholas Piggin
155e754f4d1SNicholas Piggin	/*
156e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
157e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
158e754f4d1SNicholas Piggin	 */
159e754f4d1SNicholas Piggin	mtcr	r2
160aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
161aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
162aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
163e754f4d1SNicholas Piggin	RFSCV_TO_USER
164e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
165e754f4d1SNicholas Piggin
166e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_restore_regs:
167e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
168e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
169e754f4d1SNicholas Piggin
170e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
171e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
172e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
173e754f4d1SNicholas Piggin
174e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
175e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
176e754f4d1SNicholas Piggin	mtcr	r2
177e754f4d1SNicholas Piggin	mtctr	r3
178e754f4d1SNicholas Piggin	mtlr	r4
179e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
180aebd1fb4SNicholas Piggin	REST_GPRS(2, 13, r1)
181aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
182e754f4d1SNicholas Piggin	RFI_TO_USER
18313799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_end:
18413799748SNicholas Piggin
18513799748SNicholas Pigginsyscall_vectored_\name\()_restart:
18698798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart)
18713799748SNicholas Piggin	GET_PACA(r13)
18813799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
18913799748SNicholas Piggin	ld	r2,PACATOC(r13)
19013799748SNicholas Piggin	ld	r3,RESULT(r1)
19113799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
19213799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
19313799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
19413799748SNicholas Piggin	bl	syscall_exit_restart
19513799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
19613799748SNicholas Piggin	b	.Lsyscall_vectored_\name\()_rst_start
197325678fdSNicholas Piggin1:
19813799748SNicholas Piggin
199325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)
20013799748SNicholas PigginRESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
20113799748SNicholas Piggin
202e754f4d1SNicholas Piggin.endm
203e754f4d1SNicholas Piggin
204e754f4d1SNicholas Pigginsystem_call_vectored common 0x3000
20513799748SNicholas Piggin
206e754f4d1SNicholas Piggin/*
207e754f4d1SNicholas Piggin * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
208e754f4d1SNicholas Piggin * which is tested by system_call_exception when r0 is -1 (as set by vector
209e754f4d1SNicholas Piggin * entry code).
210e754f4d1SNicholas Piggin */
211e754f4d1SNicholas Pigginsystem_call_vectored sigill 0x7ff0
212e754f4d1SNicholas Piggin
2139b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
214e754f4d1SNicholas Piggin
215e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
216e754f4d1SNicholas Piggin	.globl system_call_common_real
217e754f4d1SNicholas Pigginsystem_call_common_real:
21898798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common_real)
219e754f4d1SNicholas Piggin	ld	r10,PACAKMSR(r13)	/* get MSR value for kernel */
220e754f4d1SNicholas Piggin	mtmsrd	r10
221e754f4d1SNicholas Piggin
222e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
223e754f4d1SNicholas Piggin	.globl system_call_common
224e754f4d1SNicholas Pigginsystem_call_common:
225e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common)
226e754f4d1SNicholas Piggin	mr	r10,r1
227e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
228e754f4d1SNicholas Piggin	std	r10,0(r1)
229e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
230e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
231e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
232e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
233e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
2343e731858SChristophe Leroy#ifdef CONFIG_PPC_E500
235e754f4d1SNicholas PigginSTART_BTB_FLUSH_SECTION
236e754f4d1SNicholas Piggin	BTB_FLUSH(r10)
237e754f4d1SNicholas PigginEND_BTB_FLUSH_SECTION
238e754f4d1SNicholas Piggin#endif
239e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
240e754f4d1SNicholas Piggin	mfcr	r12
241e754f4d1SNicholas Piggin	li	r11,0
242e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
243e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
244e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
245e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
246e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
247e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
248e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
249e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
250e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
251e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
252e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
253e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
254e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
255e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
256e754f4d1SNicholas Piggin	std	r11,_XER(r1)
257e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
258e754f4d1SNicholas Piggin	mflr	r10
259e754f4d1SNicholas Piggin
260e754f4d1SNicholas Piggin	/*
261e754f4d1SNicholas Piggin	 * This clears CR0.SO (bit 28), which is the error indication on
262e754f4d1SNicholas Piggin	 * return from this system call.
263e754f4d1SNicholas Piggin	 */
264e754f4d1SNicholas Piggin	rldimi	r12,r11,28,(63-28)
265e754f4d1SNicholas Piggin	li	r11,0xc00
266e754f4d1SNicholas Piggin	std	r10,_LINK(r1)
267e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
268e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
269*2c27d4a4SRohan McLure	std	r3,ORIG_GPR3(r1)
270e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
271e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
272e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
273e754f4d1SNicholas Piggin
274e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
275e754f4d1SNicholas Piggin	li	r11,1
276e754f4d1SNicholas Piggin	stb	r11,PACASRR_VALID(r13)
277e754f4d1SNicholas Piggin#endif
278e754f4d1SNicholas Piggin
279e754f4d1SNicholas Piggin	/*
280e754f4d1SNicholas Piggin	 * We always enter kernel from userspace with irq soft-mask enabled and
281e754f4d1SNicholas Piggin	 * nothing pending. system_call_exception() will call
282e754f4d1SNicholas Piggin	 * trace_hardirqs_off().
283e754f4d1SNicholas Piggin	 */
284e754f4d1SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
285e754f4d1SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
2861df3af6dSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
2871df3af6dSNicholas Piggin	li	r12,-1 /* Set MSR_EE and MSR_RI */
288dd152f70SNicholas Piggin	mtmsrd	r12,1
2891df3af6dSNicholas Piggin#else
2901df3af6dSNicholas Piggin	wrteei	1
2911df3af6dSNicholas Piggin#endif
292e754f4d1SNicholas Piggin
293e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
294e754f4d1SNicholas Piggin	mr	r9,r0
295e754f4d1SNicholas Piggin	bl	system_call_exception
296e754f4d1SNicholas Piggin
297e754f4d1SNicholas Piggin.Lsyscall_exit:
298e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
299e754f4d1SNicholas Piggin	li	r5,0 /* !scv */
300e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
30113799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
3029b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
30313799748SNicholas Piggin.Lsyscall_rst_start:
30413799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
30513799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
30613799748SNicholas Piggin	bne-	syscall_restart
3079b69d48cSNicholas Piggin#endif
30813799748SNicholas Piggin	li	r11,IRQS_ENABLED
30913799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
31013799748SNicholas Piggin	li	r11,0
31113799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
312e754f4d1SNicholas Piggin
313e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
314e754f4d1SNicholas Piggin	ld	r6,_LINK(r1)
315e754f4d1SNicholas Piggin	mtlr	r6
316e754f4d1SNicholas Piggin
317e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
318e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
319e754f4d1SNicholas Piggin	cmpdi	r4,0
320e754f4d1SNicholas Piggin	bne	1f
321e754f4d1SNicholas Piggin	li	r4,0
322e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
323e754f4d1SNicholas Piggin#endif
324e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
325e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
326e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
327e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
328e754f4d1SNicholas Piggin1:
329e754f4d1SNicholas Piggin	DEBUG_SRR_VALID srr
330e754f4d1SNicholas Piggin
331e754f4d1SNicholas PigginBEGIN_FTR_SECTION
332e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
333e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
334e754f4d1SNicholas Piggin
335e754f4d1SNicholas Piggin	cmpdi	r3,0
336e754f4d1SNicholas Piggin	bne	.Lsyscall_restore_regs
337e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
338e754f4d1SNicholas Piggin	li	r0,0
339e754f4d1SNicholas Piggin	li	r4,0
340e754f4d1SNicholas Piggin	li	r5,0
341e754f4d1SNicholas Piggin	li	r6,0
342e754f4d1SNicholas Piggin	li	r7,0
343e754f4d1SNicholas Piggin	li	r8,0
344e754f4d1SNicholas Piggin	li	r9,0
345e754f4d1SNicholas Piggin	li	r10,0
346e754f4d1SNicholas Piggin	li	r11,0
347e754f4d1SNicholas Piggin	li	r12,0
348e754f4d1SNicholas Piggin	mtctr	r0
349e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
350e754f4d1SNicholas Piggin.Lsyscall_restore_regs_cont:
351e754f4d1SNicholas Piggin
352e754f4d1SNicholas PigginBEGIN_FTR_SECTION
353e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
354e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
355e754f4d1SNicholas Piggin
356e754f4d1SNicholas Piggin	/*
357e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
358e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
359e754f4d1SNicholas Piggin	 */
360e754f4d1SNicholas Piggin	mtcr	r2
361aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
362aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
363aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
364e754f4d1SNicholas Piggin	RFI_TO_USER
365e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
366e754f4d1SNicholas Piggin
367e754f4d1SNicholas Piggin.Lsyscall_restore_regs:
368e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
369e754f4d1SNicholas Piggin	ld	r4,_XER(r1)
370e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
371e754f4d1SNicholas Piggin	mtctr	r3
372e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r4
373e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
374aebd1fb4SNicholas Piggin	REST_GPRS(4, 12, r1)
375e754f4d1SNicholas Piggin	b	.Lsyscall_restore_regs_cont
37613799748SNicholas Piggin.Lsyscall_rst_end:
37713799748SNicholas Piggin
3789b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
37913799748SNicholas Pigginsyscall_restart:
38098798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_restart)
38113799748SNicholas Piggin	GET_PACA(r13)
38213799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
38313799748SNicholas Piggin	ld	r2,PACATOC(r13)
38413799748SNicholas Piggin	ld	r3,RESULT(r1)
38513799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
38613799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
38713799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
38813799748SNicholas Piggin	bl	syscall_exit_restart
38913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
39013799748SNicholas Piggin	b	.Lsyscall_rst_start
391325678fdSNicholas Piggin1:
39213799748SNicholas Piggin
393325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
39413799748SNicholas PigginRESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
3959b69d48cSNicholas Piggin#endif
396e754f4d1SNicholas Piggin
397e754f4d1SNicholas Piggin	/*
398e754f4d1SNicholas Piggin	 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
399e754f4d1SNicholas Piggin	 * touched, no exit work created, then this can be used.
400e754f4d1SNicholas Piggin	 */
401e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
402e754f4d1SNicholas Piggin	.globl fast_interrupt_return_srr
403e754f4d1SNicholas Pigginfast_interrupt_return_srr:
404e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
405e754f4d1SNicholas Piggin	kuap_check_amr r3, r4
406e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
407e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_PR
408e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
40913799748SNicholas Piggin	beq	1f
41013799748SNicholas Piggin	kuap_user_restore r3, r4
41113799748SNicholas Piggin	b	.Lfast_user_interrupt_return_srr
41213799748SNicholas Piggin1:	kuap_kernel_restore r3, r4
413e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_RI
414e754f4d1SNicholas Piggin	li	r3,0 /* 0 return value, no EMULATE_STACK_STORE */
415e754f4d1SNicholas Piggin	bne+	.Lfast_kernel_interrupt_return_srr
416e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
417e754f4d1SNicholas Piggin	bl	unrecoverable_exception
418e754f4d1SNicholas Piggin	b	. /* should not get here */
419e754f4d1SNicholas Piggin#else
420e754f4d1SNicholas Piggin	bne	.Lfast_user_interrupt_return_srr
421e754f4d1SNicholas Piggin	b	.Lfast_kernel_interrupt_return_srr
422e754f4d1SNicholas Piggin#endif
423e754f4d1SNicholas Piggin
424e754f4d1SNicholas Piggin.macro interrupt_return_macro srr
425e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
426e754f4d1SNicholas Piggin	.globl interrupt_return_\srr
427e754f4d1SNicholas Piggininterrupt_return_\srr\():
428e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
429e754f4d1SNicholas Piggin	ld	r4,_MSR(r1)
430e754f4d1SNicholas Piggin	andi.	r0,r4,MSR_PR
431c59458b0SNicholas Piggin	beq	interrupt_return_\srr\()_kernel
432c59458b0SNicholas Piggininterrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */
433c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user)
434e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
435e754f4d1SNicholas Piggin	bl	interrupt_exit_user_prepare
436e754f4d1SNicholas Piggin	cmpdi	r3,0
437e754f4d1SNicholas Piggin	bne-	.Lrestore_nvgprs_\srr
43813799748SNicholas Piggin.Lrestore_nvgprs_\srr\()_cont:
43913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
4409b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
44113799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_start:
44213799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
44313799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
44413799748SNicholas Piggin	bne-	interrupt_return_\srr\()_user_restart
4459b69d48cSNicholas Piggin#endif
44613799748SNicholas Piggin	li	r11,IRQS_ENABLED
44713799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
44813799748SNicholas Piggin	li	r11,0
44913799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
450e754f4d1SNicholas Piggin
451e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_\srr\():
452e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
453e754f4d1SNicholas Piggin	.ifc \srr,srr
454e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
455e754f4d1SNicholas Piggin	.else
456e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
457e754f4d1SNicholas Piggin	.endif
458e754f4d1SNicholas Piggin	cmpdi	r4,0
459e754f4d1SNicholas Piggin	li	r4,0
460e754f4d1SNicholas Piggin	bne	1f
461e754f4d1SNicholas Piggin#endif
462e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
463e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
464e754f4d1SNicholas Piggin	.ifc \srr,srr
465e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
466e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
467e754f4d1SNicholas Piggin1:
468e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
469e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
470e754f4d1SNicholas Piggin#endif
471e754f4d1SNicholas Piggin	.else
472e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
473e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
474e754f4d1SNicholas Piggin1:
475e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
476e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
477e754f4d1SNicholas Piggin#endif
478e754f4d1SNicholas Piggin	.endif
479e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
480e754f4d1SNicholas Piggin
48113799748SNicholas Piggin#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
48213799748SNicholas Piggin	lbz	r4,PACAIRQSOFTMASK(r13)
48313799748SNicholas Piggin	tdnei	r4,IRQS_ENABLED
48413799748SNicholas Piggin#endif
48513799748SNicholas Piggin
48613799748SNicholas PigginBEGIN_FTR_SECTION
48713799748SNicholas Piggin	ld	r10,_PPR(r1)
48813799748SNicholas Piggin	mtspr	SPRN_PPR,r10
48913799748SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
49013799748SNicholas Piggin
491e754f4d1SNicholas PigginBEGIN_FTR_SECTION
492e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
493e754f4d1SNicholas PigginFTR_SECTION_ELSE
494e754f4d1SNicholas Piggin	ldarx	r0,0,r1
495e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
496e754f4d1SNicholas Piggin
497e754f4d1SNicholas Piggin	ld	r3,_CCR(r1)
498e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
499e754f4d1SNicholas Piggin	ld	r5,_CTR(r1)
500e754f4d1SNicholas Piggin	ld	r6,_XER(r1)
501e754f4d1SNicholas Piggin	li	r0,0
502e754f4d1SNicholas Piggin
503aebd1fb4SNicholas Piggin	REST_GPRS(7, 13, r1)
504e754f4d1SNicholas Piggin
505e754f4d1SNicholas Piggin	mtcr	r3
506e754f4d1SNicholas Piggin	mtlr	r4
507e754f4d1SNicholas Piggin	mtctr	r5
508e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r6
509e754f4d1SNicholas Piggin
510aebd1fb4SNicholas Piggin	REST_GPRS(2, 6, r1)
511e754f4d1SNicholas Piggin	REST_GPR(0, r1)
512e754f4d1SNicholas Piggin	REST_GPR(1, r1)
513e754f4d1SNicholas Piggin	.ifc \srr,srr
514e754f4d1SNicholas Piggin	RFI_TO_USER
515e754f4d1SNicholas Piggin	.else
516e754f4d1SNicholas Piggin	HRFI_TO_USER
517e754f4d1SNicholas Piggin	.endif
518e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
51913799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_end:
520e754f4d1SNicholas Piggin
521e754f4d1SNicholas Piggin.Lrestore_nvgprs_\srr\():
522e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
52313799748SNicholas Piggin	b	.Lrestore_nvgprs_\srr\()_cont
52413799748SNicholas Piggin
5259b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
52613799748SNicholas Piggininterrupt_return_\srr\()_user_restart:
52798798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user_restart)
52813799748SNicholas Piggin	GET_PACA(r13)
52913799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
53013799748SNicholas Piggin	ld	r2,PACATOC(r13)
53113799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
53213799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
53313799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
53413799748SNicholas Piggin	bl	interrupt_exit_user_restart
53513799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
53613799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_user_rst_start
537325678fdSNicholas Piggin1:
53813799748SNicholas Piggin
539325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_user_rst_start, 1b)
54013799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
5419b69d48cSNicholas Piggin#endif
542e754f4d1SNicholas Piggin
543e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
544c59458b0SNicholas Piggininterrupt_return_\srr\()_kernel:
545c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
546e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
547e754f4d1SNicholas Piggin	bl	interrupt_exit_kernel_prepare
548e754f4d1SNicholas Piggin
54913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
55013799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_start:
55113799748SNicholas Piggin	ld	r11,SOFTE(r1)
55213799748SNicholas Piggin	cmpwi	r11,IRQS_ENABLED
55313799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
55413799748SNicholas Piggin	bne	1f
5559b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
55613799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
55713799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
55813799748SNicholas Piggin	bne-	interrupt_return_\srr\()_kernel_restart
5599b69d48cSNicholas Piggin#endif
56013799748SNicholas Piggin	li	r11,0
56113799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
56213799748SNicholas Piggin1:
56313799748SNicholas Piggin
564e754f4d1SNicholas Piggin.Lfast_kernel_interrupt_return_\srr\():
565e754f4d1SNicholas Piggin	cmpdi	cr1,r3,0
566e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
567e754f4d1SNicholas Piggin	.ifc \srr,srr
568e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
569e754f4d1SNicholas Piggin	.else
570e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
571e754f4d1SNicholas Piggin	.endif
572e754f4d1SNicholas Piggin	cmpdi	r4,0
573e754f4d1SNicholas Piggin	li	r4,0
574e754f4d1SNicholas Piggin	bne	1f
575e754f4d1SNicholas Piggin#endif
576e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
577e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
578e754f4d1SNicholas Piggin	.ifc \srr,srr
579e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
580e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
581e754f4d1SNicholas Piggin1:
582e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
583e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
584e754f4d1SNicholas Piggin#endif
585e754f4d1SNicholas Piggin	.else
586e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
587e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
588e754f4d1SNicholas Piggin1:
589e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
590e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
591e754f4d1SNicholas Piggin#endif
592e754f4d1SNicholas Piggin	.endif
593e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
594e754f4d1SNicholas Piggin
595e754f4d1SNicholas PigginBEGIN_FTR_SECTION
596e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
597e754f4d1SNicholas PigginFTR_SECTION_ELSE
598e754f4d1SNicholas Piggin	ldarx	r0,0,r1
599e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
600e754f4d1SNicholas Piggin
601e754f4d1SNicholas Piggin	ld	r3,_LINK(r1)
602e754f4d1SNicholas Piggin	ld	r4,_CTR(r1)
603e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
604e754f4d1SNicholas Piggin	ld	r6,_CCR(r1)
605e754f4d1SNicholas Piggin	li	r0,0
606e754f4d1SNicholas Piggin
607aebd1fb4SNicholas Piggin	REST_GPRS(7, 12, r1)
608e754f4d1SNicholas Piggin
609e754f4d1SNicholas Piggin	mtlr	r3
610e754f4d1SNicholas Piggin	mtctr	r4
611e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
612e754f4d1SNicholas Piggin
613e754f4d1SNicholas Piggin	/*
614e754f4d1SNicholas Piggin	 * Leaving a stale exception_marker on the stack can confuse
615e754f4d1SNicholas Piggin	 * the reliable stack unwinder later on. Clear it.
616e754f4d1SNicholas Piggin	 */
617e754f4d1SNicholas Piggin	std	r0,STACK_FRAME_OVERHEAD-16(r1)
618e754f4d1SNicholas Piggin
619aebd1fb4SNicholas Piggin	REST_GPRS(2, 5, r1)
620e754f4d1SNicholas Piggin
621e754f4d1SNicholas Piggin	bne-	cr1,1f /* emulate stack store */
622e754f4d1SNicholas Piggin	mtcr	r6
623e754f4d1SNicholas Piggin	REST_GPR(6, r1)
624e754f4d1SNicholas Piggin	REST_GPR(0, r1)
625e754f4d1SNicholas Piggin	REST_GPR(1, r1)
626e754f4d1SNicholas Piggin	.ifc \srr,srr
627e754f4d1SNicholas Piggin	RFI_TO_KERNEL
628e754f4d1SNicholas Piggin	.else
629e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
630e754f4d1SNicholas Piggin	.endif
631e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
632e754f4d1SNicholas Piggin
633e754f4d1SNicholas Piggin1:	/*
634e754f4d1SNicholas Piggin	 * Emulate stack store with update. New r1 value was already calculated
635e754f4d1SNicholas Piggin	 * and updated in our interrupt regs by emulate_loadstore, but we can't
636e754f4d1SNicholas Piggin	 * store the previous value of r1 to the stack before re-loading our
637e754f4d1SNicholas Piggin	 * registers from it, otherwise they could be clobbered.  Use
638e754f4d1SNicholas Piggin	 * PACA_EXGEN as temporary storage to hold the store data, as
639e754f4d1SNicholas Piggin	 * interrupts are disabled here so it won't be clobbered.
640e754f4d1SNicholas Piggin	 */
641e754f4d1SNicholas Piggin	mtcr	r6
642e754f4d1SNicholas Piggin	std	r9,PACA_EXGEN+0(r13)
643e754f4d1SNicholas Piggin	addi	r9,r1,INT_FRAME_SIZE /* get original r1 */
644e754f4d1SNicholas Piggin	REST_GPR(6, r1)
645e754f4d1SNicholas Piggin	REST_GPR(0, r1)
646e754f4d1SNicholas Piggin	REST_GPR(1, r1)
647e754f4d1SNicholas Piggin	std	r9,0(r1) /* perform store component of stdu */
648e754f4d1SNicholas Piggin	ld	r9,PACA_EXGEN+0(r13)
649e754f4d1SNicholas Piggin
650e754f4d1SNicholas Piggin	.ifc \srr,srr
651e754f4d1SNicholas Piggin	RFI_TO_KERNEL
652e754f4d1SNicholas Piggin	.else
653e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
654e754f4d1SNicholas Piggin	.endif
655e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
65613799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_end:
65713799748SNicholas Piggin
6589b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
65913799748SNicholas Piggininterrupt_return_\srr\()_kernel_restart:
66098798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel_restart)
66113799748SNicholas Piggin	GET_PACA(r13)
66213799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
66313799748SNicholas Piggin	ld	r2,PACATOC(r13)
66413799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
66513799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
66613799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
66713799748SNicholas Piggin	bl	interrupt_exit_kernel_restart
66813799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
66913799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_kernel_rst_start
670325678fdSNicholas Piggin1:
67113799748SNicholas Piggin
672325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, 1b)
67313799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
6749b69d48cSNicholas Piggin#endif
67513799748SNicholas Piggin
676e754f4d1SNicholas Piggin.endm
677e754f4d1SNicholas Piggin
678e754f4d1SNicholas Piggininterrupt_return_macro srr
679e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
680e754f4d1SNicholas Piggininterrupt_return_macro hsrr
6819d1988caSNicholas Piggin
6829d1988caSNicholas Piggin	.globl __end_soft_masked
6839d1988caSNicholas Piggin__end_soft_masked:
684d72c4a36SDaniel AxtensDEFINE_FIXED_SYMBOL(__end_soft_masked, text)
6859b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
68691fc46ecSNicholas Piggin
68791fc46ecSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
68891fc46ecSNicholas Piggin_GLOBAL(ret_from_fork_scv)
68991fc46ecSNicholas Piggin	bl	schedule_tail
69091fc46ecSNicholas Piggin	REST_NVGPRS(r1)
69191fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
69291fc46ecSNicholas Piggin	b	.Lsyscall_vectored_common_exit
69391fc46ecSNicholas Piggin#endif
69491fc46ecSNicholas Piggin
69591fc46ecSNicholas Piggin_GLOBAL(ret_from_fork)
69691fc46ecSNicholas Piggin	bl	schedule_tail
69791fc46ecSNicholas Piggin	REST_NVGPRS(r1)
69891fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
69991fc46ecSNicholas Piggin	b	.Lsyscall_exit
70091fc46ecSNicholas Piggin
70191fc46ecSNicholas Piggin_GLOBAL(ret_from_kernel_thread)
70291fc46ecSNicholas Piggin	bl	schedule_tail
70391fc46ecSNicholas Piggin	REST_NVGPRS(r1)
70491fc46ecSNicholas Piggin	mtctr	r14
70591fc46ecSNicholas Piggin	mr	r3,r15
7067d40aff8SChristophe Leroy#ifdef CONFIG_PPC64_ELF_ABI_V2
70791fc46ecSNicholas Piggin	mr	r12,r14
70891fc46ecSNicholas Piggin#endif
70991fc46ecSNicholas Piggin	bctrl
71091fc46ecSNicholas Piggin	li	r3,0
71191fc46ecSNicholas Piggin	b	.Lsyscall_exit
712