xref: /openbmc/linux/arch/powerpc/kernel/interrupt_64.S (revision 3e7318584dfec11992f3ac45658c4bc1210b3778)
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)
84e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
85e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
86e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
87e754f4d1SNicholas Piggin
88e754f4d1SNicholas PigginBEGIN_FTR_SECTION
89e754f4d1SNicholas Piggin	HMT_MEDIUM
90e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
91e754f4d1SNicholas Piggin
92e754f4d1SNicholas Piggin	/*
93e754f4d1SNicholas Piggin	 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
94e754f4d1SNicholas Piggin	 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
95e754f4d1SNicholas Piggin	 * and interrupts may be masked and pending already.
96e754f4d1SNicholas Piggin	 * system_call_exception() will call trace_hardirqs_off() which means
97e754f4d1SNicholas Piggin	 * interrupts could already have been blocked before trace_hardirqs_off,
98e754f4d1SNicholas Piggin	 * but this is the best we can do.
99e754f4d1SNicholas Piggin	 */
100e754f4d1SNicholas Piggin
101e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
102e754f4d1SNicholas Piggin	mr	r9,r0
103e754f4d1SNicholas Piggin	bl	system_call_exception
104e754f4d1SNicholas Piggin
105e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_exit:
106e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
107e754f4d1SNicholas Piggin	li	r5,1 /* scv */
108e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
10913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
11013799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_start:
11113799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
11213799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
11313799748SNicholas Piggin	bne-	syscall_vectored_\name\()_restart
11413799748SNicholas Piggin	li	r11,IRQS_ENABLED
11513799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
11613799748SNicholas Piggin	li	r11,0
11713799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
118e754f4d1SNicholas Piggin
119e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
120e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
121e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
122e754f4d1SNicholas Piggin
123e754f4d1SNicholas PigginBEGIN_FTR_SECTION
124e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
125e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
126e754f4d1SNicholas Piggin
127e754f4d1SNicholas PigginBEGIN_FTR_SECTION
128e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
129e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
130e754f4d1SNicholas Piggin
131e754f4d1SNicholas Piggin	cmpdi	r3,0
132e754f4d1SNicholas Piggin	bne	.Lsyscall_vectored_\name\()_restore_regs
133e754f4d1SNicholas Piggin
134e754f4d1SNicholas Piggin	/* rfscv returns with LR->NIA and CTR->MSR */
135e754f4d1SNicholas Piggin	mtlr	r4
136e754f4d1SNicholas Piggin	mtctr	r5
137e754f4d1SNicholas Piggin
138e754f4d1SNicholas Piggin	/* Could zero these as per ABI, but we may consider a stricter ABI
139e754f4d1SNicholas Piggin	 * which preserves these if libc implementations can benefit, so
140e754f4d1SNicholas Piggin	 * restore them for now until further measurement is done. */
141e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
142e754f4d1SNicholas Piggin	ld	r4,GPR4(r1)
143e754f4d1SNicholas Piggin	ld	r5,GPR5(r1)
144e754f4d1SNicholas Piggin	ld	r6,GPR6(r1)
145e754f4d1SNicholas Piggin	ld	r7,GPR7(r1)
146e754f4d1SNicholas Piggin	ld	r8,GPR8(r1)
147e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
148e754f4d1SNicholas Piggin	li	r9,0
149e754f4d1SNicholas Piggin	li	r10,0
150e754f4d1SNicholas Piggin	li	r11,0
151e754f4d1SNicholas Piggin	li	r12,0
152e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
153e754f4d1SNicholas Piggin
154e754f4d1SNicholas Piggin	/*
155e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
156e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
157e754f4d1SNicholas Piggin	 */
158e754f4d1SNicholas Piggin	mtcr	r2
159aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
160aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
161aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
162e754f4d1SNicholas Piggin	RFSCV_TO_USER
163e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
164e754f4d1SNicholas Piggin
165e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_restore_regs:
166e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
167e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
168e754f4d1SNicholas Piggin
169e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
170e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
171e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
172e754f4d1SNicholas Piggin
173e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
174e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
175e754f4d1SNicholas Piggin	mtcr	r2
176e754f4d1SNicholas Piggin	mtctr	r3
177e754f4d1SNicholas Piggin	mtlr	r4
178e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
179aebd1fb4SNicholas Piggin	REST_GPRS(2, 13, r1)
180aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
181e754f4d1SNicholas Piggin	RFI_TO_USER
18213799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_end:
18313799748SNicholas Piggin
18413799748SNicholas Pigginsyscall_vectored_\name\()_restart:
18598798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart)
18613799748SNicholas Piggin	GET_PACA(r13)
18713799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
18813799748SNicholas Piggin	ld	r2,PACATOC(r13)
18913799748SNicholas Piggin	ld	r3,RESULT(r1)
19013799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
19113799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
19213799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
19313799748SNicholas Piggin	bl	syscall_exit_restart
19413799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
19513799748SNicholas Piggin	b	.Lsyscall_vectored_\name\()_rst_start
196325678fdSNicholas Piggin1:
19713799748SNicholas Piggin
198325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)
19913799748SNicholas PigginRESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
20013799748SNicholas Piggin
201e754f4d1SNicholas Piggin.endm
202e754f4d1SNicholas Piggin
203e754f4d1SNicholas Pigginsystem_call_vectored common 0x3000
20413799748SNicholas Piggin
205e754f4d1SNicholas Piggin/*
206e754f4d1SNicholas Piggin * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
207e754f4d1SNicholas Piggin * which is tested by system_call_exception when r0 is -1 (as set by vector
208e754f4d1SNicholas Piggin * entry code).
209e754f4d1SNicholas Piggin */
210e754f4d1SNicholas Pigginsystem_call_vectored sigill 0x7ff0
211e754f4d1SNicholas Piggin
2129b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
213e754f4d1SNicholas Piggin
214e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
215e754f4d1SNicholas Piggin	.globl system_call_common_real
216e754f4d1SNicholas Pigginsystem_call_common_real:
21798798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common_real)
218e754f4d1SNicholas Piggin	ld	r10,PACAKMSR(r13)	/* get MSR value for kernel */
219e754f4d1SNicholas Piggin	mtmsrd	r10
220e754f4d1SNicholas Piggin
221e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
222e754f4d1SNicholas Piggin	.globl system_call_common
223e754f4d1SNicholas Pigginsystem_call_common:
224e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common)
225e754f4d1SNicholas Piggin	mr	r10,r1
226e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
227e754f4d1SNicholas Piggin	std	r10,0(r1)
228e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
229e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
230e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
231e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
232e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
233*3e731858SChristophe Leroy#ifdef CONFIG_PPC_E500
234e754f4d1SNicholas PigginSTART_BTB_FLUSH_SECTION
235e754f4d1SNicholas Piggin	BTB_FLUSH(r10)
236e754f4d1SNicholas PigginEND_BTB_FLUSH_SECTION
237e754f4d1SNicholas Piggin#endif
238e754f4d1SNicholas Piggin	ld	r2,PACATOC(r13)
239e754f4d1SNicholas Piggin	mfcr	r12
240e754f4d1SNicholas Piggin	li	r11,0
241e754f4d1SNicholas Piggin	/* Can we avoid saving r3-r8 in common case? */
242e754f4d1SNicholas Piggin	std	r3,GPR3(r1)
243e754f4d1SNicholas Piggin	std	r4,GPR4(r1)
244e754f4d1SNicholas Piggin	std	r5,GPR5(r1)
245e754f4d1SNicholas Piggin	std	r6,GPR6(r1)
246e754f4d1SNicholas Piggin	std	r7,GPR7(r1)
247e754f4d1SNicholas Piggin	std	r8,GPR8(r1)
248e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
249e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
250e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
251e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
252e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
253e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
254e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
255e754f4d1SNicholas Piggin	std	r11,_XER(r1)
256e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
257e754f4d1SNicholas Piggin	mflr	r10
258e754f4d1SNicholas Piggin
259e754f4d1SNicholas Piggin	/*
260e754f4d1SNicholas Piggin	 * This clears CR0.SO (bit 28), which is the error indication on
261e754f4d1SNicholas Piggin	 * return from this system call.
262e754f4d1SNicholas Piggin	 */
263e754f4d1SNicholas Piggin	rldimi	r12,r11,28,(63-28)
264e754f4d1SNicholas Piggin	li	r11,0xc00
265e754f4d1SNicholas Piggin	std	r10,_LINK(r1)
266e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
267e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
268e754f4d1SNicholas Piggin	addi	r10,r1,STACK_FRAME_OVERHEAD
269e754f4d1SNicholas Piggin	ld	r11,exception_marker@toc(r2)
270e754f4d1SNicholas Piggin	std	r11,-16(r10)		/* "regshere" marker */
271e754f4d1SNicholas Piggin
272e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
273e754f4d1SNicholas Piggin	li	r11,1
274e754f4d1SNicholas Piggin	stb	r11,PACASRR_VALID(r13)
275e754f4d1SNicholas Piggin#endif
276e754f4d1SNicholas Piggin
277e754f4d1SNicholas Piggin	/*
278e754f4d1SNicholas Piggin	 * We always enter kernel from userspace with irq soft-mask enabled and
279e754f4d1SNicholas Piggin	 * nothing pending. system_call_exception() will call
280e754f4d1SNicholas Piggin	 * trace_hardirqs_off().
281e754f4d1SNicholas Piggin	 */
282e754f4d1SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
283e754f4d1SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
2841df3af6dSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
2851df3af6dSNicholas Piggin	li	r12,-1 /* Set MSR_EE and MSR_RI */
286dd152f70SNicholas Piggin	mtmsrd	r12,1
2871df3af6dSNicholas Piggin#else
2881df3af6dSNicholas Piggin	wrteei	1
2891df3af6dSNicholas Piggin#endif
290e754f4d1SNicholas Piggin
291e754f4d1SNicholas Piggin	/* Calling convention has r9 = orig r0, r10 = regs */
292e754f4d1SNicholas Piggin	mr	r9,r0
293e754f4d1SNicholas Piggin	bl	system_call_exception
294e754f4d1SNicholas Piggin
295e754f4d1SNicholas Piggin.Lsyscall_exit:
296e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
297e754f4d1SNicholas Piggin	li	r5,0 /* !scv */
298e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
29913799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
3009b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
30113799748SNicholas Piggin.Lsyscall_rst_start:
30213799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
30313799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
30413799748SNicholas Piggin	bne-	syscall_restart
3059b69d48cSNicholas Piggin#endif
30613799748SNicholas Piggin	li	r11,IRQS_ENABLED
30713799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
30813799748SNicholas Piggin	li	r11,0
30913799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
310e754f4d1SNicholas Piggin
311e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
312e754f4d1SNicholas Piggin	ld	r6,_LINK(r1)
313e754f4d1SNicholas Piggin	mtlr	r6
314e754f4d1SNicholas Piggin
315e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
316e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
317e754f4d1SNicholas Piggin	cmpdi	r4,0
318e754f4d1SNicholas Piggin	bne	1f
319e754f4d1SNicholas Piggin	li	r4,0
320e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
321e754f4d1SNicholas Piggin#endif
322e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
323e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
324e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
325e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
326e754f4d1SNicholas Piggin1:
327e754f4d1SNicholas Piggin	DEBUG_SRR_VALID srr
328e754f4d1SNicholas Piggin
329e754f4d1SNicholas PigginBEGIN_FTR_SECTION
330e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
331e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
332e754f4d1SNicholas Piggin
333e754f4d1SNicholas Piggin	cmpdi	r3,0
334e754f4d1SNicholas Piggin	bne	.Lsyscall_restore_regs
335e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
336e754f4d1SNicholas Piggin	li	r0,0
337e754f4d1SNicholas Piggin	li	r4,0
338e754f4d1SNicholas Piggin	li	r5,0
339e754f4d1SNicholas Piggin	li	r6,0
340e754f4d1SNicholas Piggin	li	r7,0
341e754f4d1SNicholas Piggin	li	r8,0
342e754f4d1SNicholas Piggin	li	r9,0
343e754f4d1SNicholas Piggin	li	r10,0
344e754f4d1SNicholas Piggin	li	r11,0
345e754f4d1SNicholas Piggin	li	r12,0
346e754f4d1SNicholas Piggin	mtctr	r0
347e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
348e754f4d1SNicholas Piggin.Lsyscall_restore_regs_cont:
349e754f4d1SNicholas Piggin
350e754f4d1SNicholas PigginBEGIN_FTR_SECTION
351e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
352e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
353e754f4d1SNicholas Piggin
354e754f4d1SNicholas Piggin	/*
355e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
356e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
357e754f4d1SNicholas Piggin	 */
358e754f4d1SNicholas Piggin	mtcr	r2
359aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
360aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
361aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
362e754f4d1SNicholas Piggin	RFI_TO_USER
363e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
364e754f4d1SNicholas Piggin
365e754f4d1SNicholas Piggin.Lsyscall_restore_regs:
366e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
367e754f4d1SNicholas Piggin	ld	r4,_XER(r1)
368e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
369e754f4d1SNicholas Piggin	mtctr	r3
370e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r4
371e754f4d1SNicholas Piggin	ld	r0,GPR0(r1)
372aebd1fb4SNicholas Piggin	REST_GPRS(4, 12, r1)
373e754f4d1SNicholas Piggin	b	.Lsyscall_restore_regs_cont
37413799748SNicholas Piggin.Lsyscall_rst_end:
37513799748SNicholas Piggin
3769b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
37713799748SNicholas Pigginsyscall_restart:
37898798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_restart)
37913799748SNicholas Piggin	GET_PACA(r13)
38013799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
38113799748SNicholas Piggin	ld	r2,PACATOC(r13)
38213799748SNicholas Piggin	ld	r3,RESULT(r1)
38313799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
38413799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
38513799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
38613799748SNicholas Piggin	bl	syscall_exit_restart
38713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
38813799748SNicholas Piggin	b	.Lsyscall_rst_start
389325678fdSNicholas Piggin1:
39013799748SNicholas Piggin
391325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
39213799748SNicholas PigginRESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
3939b69d48cSNicholas Piggin#endif
394e754f4d1SNicholas Piggin
395e754f4d1SNicholas Piggin	/*
396e754f4d1SNicholas Piggin	 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
397e754f4d1SNicholas Piggin	 * touched, no exit work created, then this can be used.
398e754f4d1SNicholas Piggin	 */
399e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
400e754f4d1SNicholas Piggin	.globl fast_interrupt_return_srr
401e754f4d1SNicholas Pigginfast_interrupt_return_srr:
402e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
403e754f4d1SNicholas Piggin	kuap_check_amr r3, r4
404e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
405e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_PR
406e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
40713799748SNicholas Piggin	beq	1f
40813799748SNicholas Piggin	kuap_user_restore r3, r4
40913799748SNicholas Piggin	b	.Lfast_user_interrupt_return_srr
41013799748SNicholas Piggin1:	kuap_kernel_restore r3, r4
411e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_RI
412e754f4d1SNicholas Piggin	li	r3,0 /* 0 return value, no EMULATE_STACK_STORE */
413e754f4d1SNicholas Piggin	bne+	.Lfast_kernel_interrupt_return_srr
414e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
415e754f4d1SNicholas Piggin	bl	unrecoverable_exception
416e754f4d1SNicholas Piggin	b	. /* should not get here */
417e754f4d1SNicholas Piggin#else
418e754f4d1SNicholas Piggin	bne	.Lfast_user_interrupt_return_srr
419e754f4d1SNicholas Piggin	b	.Lfast_kernel_interrupt_return_srr
420e754f4d1SNicholas Piggin#endif
421e754f4d1SNicholas Piggin
422e754f4d1SNicholas Piggin.macro interrupt_return_macro srr
423e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
424e754f4d1SNicholas Piggin	.globl interrupt_return_\srr
425e754f4d1SNicholas Piggininterrupt_return_\srr\():
426e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
427e754f4d1SNicholas Piggin	ld	r4,_MSR(r1)
428e754f4d1SNicholas Piggin	andi.	r0,r4,MSR_PR
429c59458b0SNicholas Piggin	beq	interrupt_return_\srr\()_kernel
430c59458b0SNicholas Piggininterrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */
431c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user)
432e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
433e754f4d1SNicholas Piggin	bl	interrupt_exit_user_prepare
434e754f4d1SNicholas Piggin	cmpdi	r3,0
435e754f4d1SNicholas Piggin	bne-	.Lrestore_nvgprs_\srr
43613799748SNicholas Piggin.Lrestore_nvgprs_\srr\()_cont:
43713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
4389b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
43913799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_start:
44013799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
44113799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
44213799748SNicholas Piggin	bne-	interrupt_return_\srr\()_user_restart
4439b69d48cSNicholas Piggin#endif
44413799748SNicholas Piggin	li	r11,IRQS_ENABLED
44513799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
44613799748SNicholas Piggin	li	r11,0
44713799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
448e754f4d1SNicholas Piggin
449e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_\srr\():
450e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
451e754f4d1SNicholas Piggin	.ifc \srr,srr
452e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
453e754f4d1SNicholas Piggin	.else
454e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
455e754f4d1SNicholas Piggin	.endif
456e754f4d1SNicholas Piggin	cmpdi	r4,0
457e754f4d1SNicholas Piggin	li	r4,0
458e754f4d1SNicholas Piggin	bne	1f
459e754f4d1SNicholas Piggin#endif
460e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
461e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
462e754f4d1SNicholas Piggin	.ifc \srr,srr
463e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
464e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
465e754f4d1SNicholas Piggin1:
466e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
467e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
468e754f4d1SNicholas Piggin#endif
469e754f4d1SNicholas Piggin	.else
470e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
471e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
472e754f4d1SNicholas Piggin1:
473e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
474e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
475e754f4d1SNicholas Piggin#endif
476e754f4d1SNicholas Piggin	.endif
477e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
478e754f4d1SNicholas Piggin
47913799748SNicholas Piggin#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
48013799748SNicholas Piggin	lbz	r4,PACAIRQSOFTMASK(r13)
48113799748SNicholas Piggin	tdnei	r4,IRQS_ENABLED
48213799748SNicholas Piggin#endif
48313799748SNicholas Piggin
48413799748SNicholas PigginBEGIN_FTR_SECTION
48513799748SNicholas Piggin	ld	r10,_PPR(r1)
48613799748SNicholas Piggin	mtspr	SPRN_PPR,r10
48713799748SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
48813799748SNicholas Piggin
489e754f4d1SNicholas PigginBEGIN_FTR_SECTION
490e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
491e754f4d1SNicholas PigginFTR_SECTION_ELSE
492e754f4d1SNicholas Piggin	ldarx	r0,0,r1
493e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
494e754f4d1SNicholas Piggin
495e754f4d1SNicholas Piggin	ld	r3,_CCR(r1)
496e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
497e754f4d1SNicholas Piggin	ld	r5,_CTR(r1)
498e754f4d1SNicholas Piggin	ld	r6,_XER(r1)
499e754f4d1SNicholas Piggin	li	r0,0
500e754f4d1SNicholas Piggin
501aebd1fb4SNicholas Piggin	REST_GPRS(7, 13, r1)
502e754f4d1SNicholas Piggin
503e754f4d1SNicholas Piggin	mtcr	r3
504e754f4d1SNicholas Piggin	mtlr	r4
505e754f4d1SNicholas Piggin	mtctr	r5
506e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r6
507e754f4d1SNicholas Piggin
508aebd1fb4SNicholas Piggin	REST_GPRS(2, 6, r1)
509e754f4d1SNicholas Piggin	REST_GPR(0, r1)
510e754f4d1SNicholas Piggin	REST_GPR(1, r1)
511e754f4d1SNicholas Piggin	.ifc \srr,srr
512e754f4d1SNicholas Piggin	RFI_TO_USER
513e754f4d1SNicholas Piggin	.else
514e754f4d1SNicholas Piggin	HRFI_TO_USER
515e754f4d1SNicholas Piggin	.endif
516e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
51713799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_end:
518e754f4d1SNicholas Piggin
519e754f4d1SNicholas Piggin.Lrestore_nvgprs_\srr\():
520e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
52113799748SNicholas Piggin	b	.Lrestore_nvgprs_\srr\()_cont
52213799748SNicholas Piggin
5239b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
52413799748SNicholas Piggininterrupt_return_\srr\()_user_restart:
52598798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user_restart)
52613799748SNicholas Piggin	GET_PACA(r13)
52713799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
52813799748SNicholas Piggin	ld	r2,PACATOC(r13)
52913799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
53013799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
53113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
53213799748SNicholas Piggin	bl	interrupt_exit_user_restart
53313799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
53413799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_user_rst_start
535325678fdSNicholas Piggin1:
53613799748SNicholas Piggin
537325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_user_rst_start, 1b)
53813799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
5399b69d48cSNicholas Piggin#endif
540e754f4d1SNicholas Piggin
541e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
542c59458b0SNicholas Piggininterrupt_return_\srr\()_kernel:
543c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
544e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
545e754f4d1SNicholas Piggin	bl	interrupt_exit_kernel_prepare
546e754f4d1SNicholas Piggin
54713799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
54813799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_start:
54913799748SNicholas Piggin	ld	r11,SOFTE(r1)
55013799748SNicholas Piggin	cmpwi	r11,IRQS_ENABLED
55113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
55213799748SNicholas Piggin	bne	1f
5539b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
55413799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
55513799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
55613799748SNicholas Piggin	bne-	interrupt_return_\srr\()_kernel_restart
5579b69d48cSNicholas Piggin#endif
55813799748SNicholas Piggin	li	r11,0
55913799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
56013799748SNicholas Piggin1:
56113799748SNicholas Piggin
562e754f4d1SNicholas Piggin.Lfast_kernel_interrupt_return_\srr\():
563e754f4d1SNicholas Piggin	cmpdi	cr1,r3,0
564e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
565e754f4d1SNicholas Piggin	.ifc \srr,srr
566e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
567e754f4d1SNicholas Piggin	.else
568e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
569e754f4d1SNicholas Piggin	.endif
570e754f4d1SNicholas Piggin	cmpdi	r4,0
571e754f4d1SNicholas Piggin	li	r4,0
572e754f4d1SNicholas Piggin	bne	1f
573e754f4d1SNicholas Piggin#endif
574e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
575e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
576e754f4d1SNicholas Piggin	.ifc \srr,srr
577e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
578e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
579e754f4d1SNicholas Piggin1:
580e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
581e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
582e754f4d1SNicholas Piggin#endif
583e754f4d1SNicholas Piggin	.else
584e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
585e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
586e754f4d1SNicholas Piggin1:
587e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
588e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
589e754f4d1SNicholas Piggin#endif
590e754f4d1SNicholas Piggin	.endif
591e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
592e754f4d1SNicholas Piggin
593e754f4d1SNicholas PigginBEGIN_FTR_SECTION
594e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
595e754f4d1SNicholas PigginFTR_SECTION_ELSE
596e754f4d1SNicholas Piggin	ldarx	r0,0,r1
597e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
598e754f4d1SNicholas Piggin
599e754f4d1SNicholas Piggin	ld	r3,_LINK(r1)
600e754f4d1SNicholas Piggin	ld	r4,_CTR(r1)
601e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
602e754f4d1SNicholas Piggin	ld	r6,_CCR(r1)
603e754f4d1SNicholas Piggin	li	r0,0
604e754f4d1SNicholas Piggin
605aebd1fb4SNicholas Piggin	REST_GPRS(7, 12, r1)
606e754f4d1SNicholas Piggin
607e754f4d1SNicholas Piggin	mtlr	r3
608e754f4d1SNicholas Piggin	mtctr	r4
609e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
610e754f4d1SNicholas Piggin
611e754f4d1SNicholas Piggin	/*
612e754f4d1SNicholas Piggin	 * Leaving a stale exception_marker on the stack can confuse
613e754f4d1SNicholas Piggin	 * the reliable stack unwinder later on. Clear it.
614e754f4d1SNicholas Piggin	 */
615e754f4d1SNicholas Piggin	std	r0,STACK_FRAME_OVERHEAD-16(r1)
616e754f4d1SNicholas Piggin
617aebd1fb4SNicholas Piggin	REST_GPRS(2, 5, r1)
618e754f4d1SNicholas Piggin
619e754f4d1SNicholas Piggin	bne-	cr1,1f /* emulate stack store */
620e754f4d1SNicholas Piggin	mtcr	r6
621e754f4d1SNicholas Piggin	REST_GPR(6, r1)
622e754f4d1SNicholas Piggin	REST_GPR(0, r1)
623e754f4d1SNicholas Piggin	REST_GPR(1, r1)
624e754f4d1SNicholas Piggin	.ifc \srr,srr
625e754f4d1SNicholas Piggin	RFI_TO_KERNEL
626e754f4d1SNicholas Piggin	.else
627e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
628e754f4d1SNicholas Piggin	.endif
629e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
630e754f4d1SNicholas Piggin
631e754f4d1SNicholas Piggin1:	/*
632e754f4d1SNicholas Piggin	 * Emulate stack store with update. New r1 value was already calculated
633e754f4d1SNicholas Piggin	 * and updated in our interrupt regs by emulate_loadstore, but we can't
634e754f4d1SNicholas Piggin	 * store the previous value of r1 to the stack before re-loading our
635e754f4d1SNicholas Piggin	 * registers from it, otherwise they could be clobbered.  Use
636e754f4d1SNicholas Piggin	 * PACA_EXGEN as temporary storage to hold the store data, as
637e754f4d1SNicholas Piggin	 * interrupts are disabled here so it won't be clobbered.
638e754f4d1SNicholas Piggin	 */
639e754f4d1SNicholas Piggin	mtcr	r6
640e754f4d1SNicholas Piggin	std	r9,PACA_EXGEN+0(r13)
641e754f4d1SNicholas Piggin	addi	r9,r1,INT_FRAME_SIZE /* get original r1 */
642e754f4d1SNicholas Piggin	REST_GPR(6, r1)
643e754f4d1SNicholas Piggin	REST_GPR(0, r1)
644e754f4d1SNicholas Piggin	REST_GPR(1, r1)
645e754f4d1SNicholas Piggin	std	r9,0(r1) /* perform store component of stdu */
646e754f4d1SNicholas Piggin	ld	r9,PACA_EXGEN+0(r13)
647e754f4d1SNicholas Piggin
648e754f4d1SNicholas Piggin	.ifc \srr,srr
649e754f4d1SNicholas Piggin	RFI_TO_KERNEL
650e754f4d1SNicholas Piggin	.else
651e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
652e754f4d1SNicholas Piggin	.endif
653e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
65413799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_end:
65513799748SNicholas Piggin
6569b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
65713799748SNicholas Piggininterrupt_return_\srr\()_kernel_restart:
65898798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel_restart)
65913799748SNicholas Piggin	GET_PACA(r13)
66013799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
66113799748SNicholas Piggin	ld	r2,PACATOC(r13)
66213799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
66313799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
66413799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
66513799748SNicholas Piggin	bl	interrupt_exit_kernel_restart
66613799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
66713799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_kernel_rst_start
668325678fdSNicholas Piggin1:
66913799748SNicholas Piggin
670325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, 1b)
67113799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
6729b69d48cSNicholas Piggin#endif
67313799748SNicholas Piggin
674e754f4d1SNicholas Piggin.endm
675e754f4d1SNicholas Piggin
676e754f4d1SNicholas Piggininterrupt_return_macro srr
677e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
678e754f4d1SNicholas Piggininterrupt_return_macro hsrr
6799d1988caSNicholas Piggin
6809d1988caSNicholas Piggin	.globl __end_soft_masked
6819d1988caSNicholas Piggin__end_soft_masked:
682d72c4a36SDaniel AxtensDEFINE_FIXED_SYMBOL(__end_soft_masked, text)
6839b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
68491fc46ecSNicholas Piggin
68591fc46ecSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
68691fc46ecSNicholas Piggin_GLOBAL(ret_from_fork_scv)
68791fc46ecSNicholas Piggin	bl	schedule_tail
68891fc46ecSNicholas Piggin	REST_NVGPRS(r1)
68991fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
69091fc46ecSNicholas Piggin	b	.Lsyscall_vectored_common_exit
69191fc46ecSNicholas Piggin#endif
69291fc46ecSNicholas Piggin
69391fc46ecSNicholas Piggin_GLOBAL(ret_from_fork)
69491fc46ecSNicholas Piggin	bl	schedule_tail
69591fc46ecSNicholas Piggin	REST_NVGPRS(r1)
69691fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
69791fc46ecSNicholas Piggin	b	.Lsyscall_exit
69891fc46ecSNicholas Piggin
69991fc46ecSNicholas Piggin_GLOBAL(ret_from_kernel_thread)
70091fc46ecSNicholas Piggin	bl	schedule_tail
70191fc46ecSNicholas Piggin	REST_NVGPRS(r1)
70291fc46ecSNicholas Piggin	mtctr	r14
70391fc46ecSNicholas Piggin	mr	r3,r15
7047d40aff8SChristophe Leroy#ifdef CONFIG_PPC64_ELF_ABI_V2
70591fc46ecSNicholas Piggin	mr	r12,r14
70691fc46ecSNicholas Piggin#endif
70791fc46ecSNicholas Piggin	bctrl
70891fc46ecSNicholas Piggin	li	r3,0
70991fc46ecSNicholas Piggin	b	.Lsyscall_exit
710