xref: /openbmc/linux/arch/powerpc/kernel/interrupt_64.S (revision 65722736c3baf29e02e964a09e85c9ef71c48e8d)
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)
608e93fb33SNicholas Piggin	LOAD_PACA_TOC()
61e754f4d1SNicholas Piggin	mfcr	r12
62e754f4d1SNicholas Piggin	li	r11,0
63f8971c62SRohan McLure	/* Save syscall parameters in r3-r8 */
642b1dac4bSRohan McLure	SAVE_GPRS(3, 8, r1)
65e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
66e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
67e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
68e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
69e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
70e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
71e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
72e754f4d1SNicholas Piggin	std	r11,_XER(r1)
73e754f4d1SNicholas Piggin	std	r11,_LINK(r1)
74e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
75e754f4d1SNicholas Piggin
76e754f4d1SNicholas Piggin	li	r11,\trapnr
77e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
78e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
792c27d4a4SRohan McLure	std	r3,ORIG_GPR3(r1)
80f8971c62SRohan McLure	/* Calling convention has r3 = regs, r4 = orig r0 */
81f8971c62SRohan McLure	addi	r3,r1,STACK_FRAME_OVERHEAD
82f8971c62SRohan McLure	mr	r4,r0
8317773afdSNicholas Piggin	LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER)
84f8971c62SRohan McLure	std	r11,-16(r3)		/* "regshere" marker */
85e754f4d1SNicholas Piggin
86e754f4d1SNicholas PigginBEGIN_FTR_SECTION
87e754f4d1SNicholas Piggin	HMT_MEDIUM
88e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
89e754f4d1SNicholas Piggin
90e754f4d1SNicholas Piggin	/*
91e754f4d1SNicholas Piggin	 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
92e754f4d1SNicholas Piggin	 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
93e754f4d1SNicholas Piggin	 * and interrupts may be masked and pending already.
94e754f4d1SNicholas Piggin	 * system_call_exception() will call trace_hardirqs_off() which means
95e754f4d1SNicholas Piggin	 * interrupts could already have been blocked before trace_hardirqs_off,
96e754f4d1SNicholas Piggin	 * but this is the best we can do.
97e754f4d1SNicholas Piggin	 */
98e754f4d1SNicholas Piggin
99e754f4d1SNicholas Piggin	bl	system_call_exception
100e754f4d1SNicholas Piggin
101e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_exit:
102e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
103e754f4d1SNicholas Piggin	li	r5,1 /* scv */
104e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
10513799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
10613799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_start:
10713799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
10813799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
10913799748SNicholas Piggin	bne-	syscall_vectored_\name\()_restart
11013799748SNicholas Piggin	li	r11,IRQS_ENABLED
11113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
11213799748SNicholas Piggin	li	r11,0
11313799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
114e754f4d1SNicholas Piggin
115e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
116e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
117e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
118e754f4d1SNicholas Piggin
119e754f4d1SNicholas PigginBEGIN_FTR_SECTION
120e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
121e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
122e754f4d1SNicholas Piggin
123e754f4d1SNicholas PigginBEGIN_FTR_SECTION
124e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
125e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
126e754f4d1SNicholas Piggin
127e754f4d1SNicholas Piggin	cmpdi	r3,0
128e754f4d1SNicholas Piggin	bne	.Lsyscall_vectored_\name\()_restore_regs
129e754f4d1SNicholas Piggin
130e754f4d1SNicholas Piggin	/* rfscv returns with LR->NIA and CTR->MSR */
131e754f4d1SNicholas Piggin	mtlr	r4
132e754f4d1SNicholas Piggin	mtctr	r5
133e754f4d1SNicholas Piggin
134e754f4d1SNicholas Piggin	/* Could zero these as per ABI, but we may consider a stricter ABI
135e754f4d1SNicholas Piggin	 * which preserves these if libc implementations can benefit, so
136e754f4d1SNicholas Piggin	 * restore them for now until further measurement is done. */
1372b1dac4bSRohan McLure	REST_GPR(0, r1)
1382b1dac4bSRohan McLure	REST_GPRS(4, 8, r1)
139e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
1402b1dac4bSRohan McLure	ZEROIZE_GPRS(9, 12)
141e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
142e754f4d1SNicholas Piggin
143e754f4d1SNicholas Piggin	/*
144e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
145e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
146e754f4d1SNicholas Piggin	 */
147e754f4d1SNicholas Piggin	mtcr	r2
148aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
149aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
150aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
151e754f4d1SNicholas Piggin	RFSCV_TO_USER
152e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
153e754f4d1SNicholas Piggin
154e754f4d1SNicholas Piggin.Lsyscall_vectored_\name\()_restore_regs:
155e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
156e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
157e754f4d1SNicholas Piggin
158e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
159e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
160e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
161e754f4d1SNicholas Piggin
162e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
1632b1dac4bSRohan McLure	REST_GPR(0, r1)
164e754f4d1SNicholas Piggin	mtcr	r2
165e754f4d1SNicholas Piggin	mtctr	r3
166e754f4d1SNicholas Piggin	mtlr	r4
167e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
168aebd1fb4SNicholas Piggin	REST_GPRS(2, 13, r1)
169aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
170e754f4d1SNicholas Piggin	RFI_TO_USER
17113799748SNicholas Piggin.Lsyscall_vectored_\name\()_rst_end:
17213799748SNicholas Piggin
17313799748SNicholas Pigginsyscall_vectored_\name\()_restart:
17498798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart)
17513799748SNicholas Piggin	GET_PACA(r13)
17613799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
1778e93fb33SNicholas Piggin	LOAD_PACA_TOC()
17813799748SNicholas Piggin	ld	r3,RESULT(r1)
17913799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
18013799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
18113799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
18213799748SNicholas Piggin	bl	syscall_exit_restart
18313799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
18413799748SNicholas Piggin	b	.Lsyscall_vectored_\name\()_rst_start
185325678fdSNicholas Piggin1:
18613799748SNicholas Piggin
187325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)
18813799748SNicholas PigginRESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
18913799748SNicholas Piggin
190e754f4d1SNicholas Piggin.endm
191e754f4d1SNicholas Piggin
192e754f4d1SNicholas Pigginsystem_call_vectored common 0x3000
19313799748SNicholas Piggin
194e754f4d1SNicholas Piggin/*
195e754f4d1SNicholas Piggin * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
196e754f4d1SNicholas Piggin * which is tested by system_call_exception when r0 is -1 (as set by vector
197e754f4d1SNicholas Piggin * entry code).
198e754f4d1SNicholas Piggin */
199e754f4d1SNicholas Pigginsystem_call_vectored sigill 0x7ff0
200e754f4d1SNicholas Piggin
2019b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
202e754f4d1SNicholas Piggin
203e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
204e754f4d1SNicholas Piggin	.globl system_call_common_real
205e754f4d1SNicholas Pigginsystem_call_common_real:
20698798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common_real)
207e754f4d1SNicholas Piggin	ld	r10,PACAKMSR(r13)	/* get MSR value for kernel */
208e754f4d1SNicholas Piggin	mtmsrd	r10
209e754f4d1SNicholas Piggin
210e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
211e754f4d1SNicholas Piggin	.globl system_call_common
212e754f4d1SNicholas Pigginsystem_call_common:
213e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(system_call_common)
214e754f4d1SNicholas Piggin	mr	r10,r1
215e754f4d1SNicholas Piggin	ld	r1,PACAKSAVE(r13)
216e754f4d1SNicholas Piggin	std	r10,0(r1)
217e754f4d1SNicholas Piggin	std	r11,_NIP(r1)
218e754f4d1SNicholas Piggin	std	r12,_MSR(r1)
219e754f4d1SNicholas Piggin	std	r0,GPR0(r1)
220e754f4d1SNicholas Piggin	std	r10,GPR1(r1)
221e754f4d1SNicholas Piggin	std	r2,GPR2(r1)
2223e731858SChristophe Leroy#ifdef CONFIG_PPC_E500
223e754f4d1SNicholas PigginSTART_BTB_FLUSH_SECTION
224e754f4d1SNicholas Piggin	BTB_FLUSH(r10)
225e754f4d1SNicholas PigginEND_BTB_FLUSH_SECTION
226e754f4d1SNicholas Piggin#endif
2278e93fb33SNicholas Piggin	LOAD_PACA_TOC()
228e754f4d1SNicholas Piggin	mfcr	r12
229e754f4d1SNicholas Piggin	li	r11,0
230f8971c62SRohan McLure	/* Save syscall parameters in r3-r8 */
2312b1dac4bSRohan McLure	SAVE_GPRS(3, 8, r1)
232e754f4d1SNicholas Piggin	/* Zero r9-r12, this should only be required when restoring all GPRs */
233e754f4d1SNicholas Piggin	std	r11,GPR9(r1)
234e754f4d1SNicholas Piggin	std	r11,GPR10(r1)
235e754f4d1SNicholas Piggin	std	r11,GPR11(r1)
236e754f4d1SNicholas Piggin	std	r11,GPR12(r1)
237e754f4d1SNicholas Piggin	std	r9,GPR13(r1)
238e754f4d1SNicholas Piggin	SAVE_NVGPRS(r1)
239e754f4d1SNicholas Piggin	std	r11,_XER(r1)
240e754f4d1SNicholas Piggin	std	r11,_CTR(r1)
241e754f4d1SNicholas Piggin	mflr	r10
242e754f4d1SNicholas Piggin
243e754f4d1SNicholas Piggin	/*
244e754f4d1SNicholas Piggin	 * This clears CR0.SO (bit 28), which is the error indication on
245e754f4d1SNicholas Piggin	 * return from this system call.
246e754f4d1SNicholas Piggin	 */
247e754f4d1SNicholas Piggin	rldimi	r12,r11,28,(63-28)
248e754f4d1SNicholas Piggin	li	r11,0xc00
249e754f4d1SNicholas Piggin	std	r10,_LINK(r1)
250e754f4d1SNicholas Piggin	std	r11,_TRAP(r1)
251e754f4d1SNicholas Piggin	std	r12,_CCR(r1)
2522c27d4a4SRohan McLure	std	r3,ORIG_GPR3(r1)
253f8971c62SRohan McLure	/* Calling convention has r3 = regs, r4 = orig r0 */
254f8971c62SRohan McLure	addi	r3,r1,STACK_FRAME_OVERHEAD
255f8971c62SRohan McLure	mr	r4,r0
25617773afdSNicholas Piggin	LOAD_REG_IMMEDIATE(r11, STACK_FRAME_REGS_MARKER)
257f8971c62SRohan McLure	std	r11,-16(r3)		/* "regshere" marker */
258e754f4d1SNicholas Piggin
259e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
260e754f4d1SNicholas Piggin	li	r11,1
261e754f4d1SNicholas Piggin	stb	r11,PACASRR_VALID(r13)
262e754f4d1SNicholas Piggin#endif
263e754f4d1SNicholas Piggin
264e754f4d1SNicholas Piggin	/*
265e754f4d1SNicholas Piggin	 * We always enter kernel from userspace with irq soft-mask enabled and
266e754f4d1SNicholas Piggin	 * nothing pending. system_call_exception() will call
267e754f4d1SNicholas Piggin	 * trace_hardirqs_off().
268e754f4d1SNicholas Piggin	 */
269e754f4d1SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
270e754f4d1SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
2711df3af6dSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
2721df3af6dSNicholas Piggin	li	r12,-1 /* Set MSR_EE and MSR_RI */
273dd152f70SNicholas Piggin	mtmsrd	r12,1
2741df3af6dSNicholas Piggin#else
2751df3af6dSNicholas Piggin	wrteei	1
2761df3af6dSNicholas Piggin#endif
277e754f4d1SNicholas Piggin
278e754f4d1SNicholas Piggin	bl	system_call_exception
279e754f4d1SNicholas Piggin
280e754f4d1SNicholas Piggin.Lsyscall_exit:
281e754f4d1SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
282e754f4d1SNicholas Piggin	li	r5,0 /* !scv */
283e754f4d1SNicholas Piggin	bl	syscall_exit_prepare
28413799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
2859b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
28613799748SNicholas Piggin.Lsyscall_rst_start:
28713799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
28813799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
28913799748SNicholas Piggin	bne-	syscall_restart
2909b69d48cSNicholas Piggin#endif
29113799748SNicholas Piggin	li	r11,IRQS_ENABLED
29213799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
29313799748SNicholas Piggin	li	r11,0
29413799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
295e754f4d1SNicholas Piggin
296e754f4d1SNicholas Piggin	ld	r2,_CCR(r1)
297e754f4d1SNicholas Piggin	ld	r6,_LINK(r1)
298e754f4d1SNicholas Piggin	mtlr	r6
299e754f4d1SNicholas Piggin
300e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
301e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
302e754f4d1SNicholas Piggin	cmpdi	r4,0
303e754f4d1SNicholas Piggin	bne	1f
304e754f4d1SNicholas Piggin	li	r4,0
305e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
306e754f4d1SNicholas Piggin#endif
307e754f4d1SNicholas Piggin	ld	r4,_NIP(r1)
308e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
309e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r4
310e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r5
311e754f4d1SNicholas Piggin1:
312e754f4d1SNicholas Piggin	DEBUG_SRR_VALID srr
313e754f4d1SNicholas Piggin
314e754f4d1SNicholas PigginBEGIN_FTR_SECTION
315e754f4d1SNicholas Piggin	stdcx.	r0,0,r1			/* to clear the reservation */
316e754f4d1SNicholas PigginEND_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
317e754f4d1SNicholas Piggin
318e754f4d1SNicholas Piggin	cmpdi	r3,0
319e754f4d1SNicholas Piggin	bne	.Lsyscall_restore_regs
320e754f4d1SNicholas Piggin	/* Zero volatile regs that may contain sensitive kernel data */
3212b1dac4bSRohan McLure	ZEROIZE_GPR(0)
3222b1dac4bSRohan McLure	ZEROIZE_GPRS(4, 12)
323e754f4d1SNicholas Piggin	mtctr	r0
324e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r0
325e754f4d1SNicholas Piggin.Lsyscall_restore_regs_cont:
326e754f4d1SNicholas Piggin
327e754f4d1SNicholas PigginBEGIN_FTR_SECTION
328e754f4d1SNicholas Piggin	HMT_MEDIUM_LOW
329e754f4d1SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
330e754f4d1SNicholas Piggin
331e754f4d1SNicholas Piggin	/*
332e754f4d1SNicholas Piggin	 * We don't need to restore AMR on the way back to userspace for KUAP.
333e754f4d1SNicholas Piggin	 * The value of AMR only matters while we're in the kernel.
334e754f4d1SNicholas Piggin	 */
335e754f4d1SNicholas Piggin	mtcr	r2
336aebd1fb4SNicholas Piggin	REST_GPRS(2, 3, r1)
337aebd1fb4SNicholas Piggin	REST_GPR(13, r1)
338aebd1fb4SNicholas Piggin	REST_GPR(1, r1)
339e754f4d1SNicholas Piggin	RFI_TO_USER
340e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
341e754f4d1SNicholas Piggin
342e754f4d1SNicholas Piggin.Lsyscall_restore_regs:
343e754f4d1SNicholas Piggin	ld	r3,_CTR(r1)
344e754f4d1SNicholas Piggin	ld	r4,_XER(r1)
345e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
346e754f4d1SNicholas Piggin	mtctr	r3
347e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r4
3482b1dac4bSRohan McLure	REST_GPR(0, r1)
349aebd1fb4SNicholas Piggin	REST_GPRS(4, 12, r1)
350e754f4d1SNicholas Piggin	b	.Lsyscall_restore_regs_cont
35113799748SNicholas Piggin.Lsyscall_rst_end:
35213799748SNicholas Piggin
3539b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
35413799748SNicholas Pigginsyscall_restart:
35598798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(syscall_restart)
35613799748SNicholas Piggin	GET_PACA(r13)
35713799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
3588e93fb33SNicholas Piggin	LOAD_PACA_TOC()
35913799748SNicholas Piggin	ld	r3,RESULT(r1)
36013799748SNicholas Piggin	addi	r4,r1,STACK_FRAME_OVERHEAD
36113799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
36213799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
36313799748SNicholas Piggin	bl	syscall_exit_restart
36413799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
36513799748SNicholas Piggin	b	.Lsyscall_rst_start
366325678fdSNicholas Piggin1:
36713799748SNicholas Piggin
368325678fdSNicholas PigginSOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
36913799748SNicholas PigginRESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
3709b69d48cSNicholas Piggin#endif
371e754f4d1SNicholas Piggin
372e754f4d1SNicholas Piggin	/*
373e754f4d1SNicholas Piggin	 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
374e754f4d1SNicholas Piggin	 * touched, no exit work created, then this can be used.
375e754f4d1SNicholas Piggin	 */
376e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
377e754f4d1SNicholas Piggin	.globl fast_interrupt_return_srr
378e754f4d1SNicholas Pigginfast_interrupt_return_srr:
379e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
380e754f4d1SNicholas Piggin	kuap_check_amr r3, r4
381e754f4d1SNicholas Piggin	ld	r5,_MSR(r1)
382e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_PR
383e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
38413799748SNicholas Piggin	beq	1f
38513799748SNicholas Piggin	kuap_user_restore r3, r4
38613799748SNicholas Piggin	b	.Lfast_user_interrupt_return_srr
38713799748SNicholas Piggin1:	kuap_kernel_restore r3, r4
388e754f4d1SNicholas Piggin	andi.	r0,r5,MSR_RI
389e754f4d1SNicholas Piggin	li	r3,0 /* 0 return value, no EMULATE_STACK_STORE */
390e754f4d1SNicholas Piggin	bne+	.Lfast_kernel_interrupt_return_srr
391e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
392e754f4d1SNicholas Piggin	bl	unrecoverable_exception
393e754f4d1SNicholas Piggin	b	. /* should not get here */
394e754f4d1SNicholas Piggin#else
395e754f4d1SNicholas Piggin	bne	.Lfast_user_interrupt_return_srr
396e754f4d1SNicholas Piggin	b	.Lfast_kernel_interrupt_return_srr
397e754f4d1SNicholas Piggin#endif
398e754f4d1SNicholas Piggin
399e754f4d1SNicholas Piggin.macro interrupt_return_macro srr
400e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
401e754f4d1SNicholas Piggin	.globl interrupt_return_\srr
402e754f4d1SNicholas Piggininterrupt_return_\srr\():
403e754f4d1SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
404e754f4d1SNicholas Piggin	ld	r4,_MSR(r1)
405e754f4d1SNicholas Piggin	andi.	r0,r4,MSR_PR
406c59458b0SNicholas Piggin	beq	interrupt_return_\srr\()_kernel
407c59458b0SNicholas Piggininterrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */
408c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user)
409e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
410e754f4d1SNicholas Piggin	bl	interrupt_exit_user_prepare
411e754f4d1SNicholas Piggin	cmpdi	r3,0
412e754f4d1SNicholas Piggin	bne-	.Lrestore_nvgprs_\srr
41313799748SNicholas Piggin.Lrestore_nvgprs_\srr\()_cont:
41413799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
4159b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
41613799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_start:
41713799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
41813799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
41913799748SNicholas Piggin	bne-	interrupt_return_\srr\()_user_restart
4209b69d48cSNicholas Piggin#endif
42113799748SNicholas Piggin	li	r11,IRQS_ENABLED
42213799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
42313799748SNicholas Piggin	li	r11,0
42413799748SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
425e754f4d1SNicholas Piggin
426e754f4d1SNicholas Piggin.Lfast_user_interrupt_return_\srr\():
427e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
428e754f4d1SNicholas Piggin	.ifc \srr,srr
429e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
430e754f4d1SNicholas Piggin	.else
431e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
432e754f4d1SNicholas Piggin	.endif
433e754f4d1SNicholas Piggin	cmpdi	r4,0
434e754f4d1SNicholas Piggin	li	r4,0
435e754f4d1SNicholas Piggin	bne	1f
436e754f4d1SNicholas Piggin#endif
437e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
438e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
439e754f4d1SNicholas Piggin	.ifc \srr,srr
440e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
441e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
442e754f4d1SNicholas Piggin1:
443e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
444e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
445e754f4d1SNicholas Piggin#endif
446e754f4d1SNicholas Piggin	.else
447e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
448e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
449e754f4d1SNicholas Piggin1:
450e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
451e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
452e754f4d1SNicholas Piggin#endif
453e754f4d1SNicholas Piggin	.endif
454e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
455e754f4d1SNicholas Piggin
45613799748SNicholas Piggin#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
45713799748SNicholas Piggin	lbz	r4,PACAIRQSOFTMASK(r13)
45813799748SNicholas Piggin	tdnei	r4,IRQS_ENABLED
45913799748SNicholas Piggin#endif
46013799748SNicholas Piggin
46113799748SNicholas PigginBEGIN_FTR_SECTION
46213799748SNicholas Piggin	ld	r10,_PPR(r1)
46313799748SNicholas Piggin	mtspr	SPRN_PPR,r10
46413799748SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
46513799748SNicholas Piggin
466e754f4d1SNicholas PigginBEGIN_FTR_SECTION
467e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
468e754f4d1SNicholas PigginFTR_SECTION_ELSE
469e754f4d1SNicholas Piggin	ldarx	r0,0,r1
470e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
471e754f4d1SNicholas Piggin
472e754f4d1SNicholas Piggin	ld	r3,_CCR(r1)
473e754f4d1SNicholas Piggin	ld	r4,_LINK(r1)
474e754f4d1SNicholas Piggin	ld	r5,_CTR(r1)
475e754f4d1SNicholas Piggin	ld	r6,_XER(r1)
476e754f4d1SNicholas Piggin	li	r0,0
477e754f4d1SNicholas Piggin
478aebd1fb4SNicholas Piggin	REST_GPRS(7, 13, r1)
479e754f4d1SNicholas Piggin
480e754f4d1SNicholas Piggin	mtcr	r3
481e754f4d1SNicholas Piggin	mtlr	r4
482e754f4d1SNicholas Piggin	mtctr	r5
483e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r6
484e754f4d1SNicholas Piggin
485aebd1fb4SNicholas Piggin	REST_GPRS(2, 6, r1)
486e754f4d1SNicholas Piggin	REST_GPR(0, r1)
487e754f4d1SNicholas Piggin	REST_GPR(1, r1)
488e754f4d1SNicholas Piggin	.ifc \srr,srr
489e754f4d1SNicholas Piggin	RFI_TO_USER
490e754f4d1SNicholas Piggin	.else
491e754f4d1SNicholas Piggin	HRFI_TO_USER
492e754f4d1SNicholas Piggin	.endif
493e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
49413799748SNicholas Piggin.Linterrupt_return_\srr\()_user_rst_end:
495e754f4d1SNicholas Piggin
496e754f4d1SNicholas Piggin.Lrestore_nvgprs_\srr\():
497e754f4d1SNicholas Piggin	REST_NVGPRS(r1)
49813799748SNicholas Piggin	b	.Lrestore_nvgprs_\srr\()_cont
49913799748SNicholas Piggin
5009b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
50113799748SNicholas Piggininterrupt_return_\srr\()_user_restart:
50298798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user_restart)
50313799748SNicholas Piggin	GET_PACA(r13)
50413799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
5058e93fb33SNicholas Piggin	LOAD_PACA_TOC()
50613799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
50713799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
50813799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
50913799748SNicholas Piggin	bl	interrupt_exit_user_restart
51013799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
51113799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_user_rst_start
512325678fdSNicholas Piggin1:
51313799748SNicholas Piggin
514325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_user_rst_start, 1b)
51513799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
5169b69d48cSNicholas Piggin#endif
517e754f4d1SNicholas Piggin
518e754f4d1SNicholas Piggin	.balign IFETCH_ALIGN_BYTES
519c59458b0SNicholas Piggininterrupt_return_\srr\()_kernel:
520c59458b0SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
521e754f4d1SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
522e754f4d1SNicholas Piggin	bl	interrupt_exit_kernel_prepare
523e754f4d1SNicholas Piggin
52413799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
52513799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_start:
52613799748SNicholas Piggin	ld	r11,SOFTE(r1)
52713799748SNicholas Piggin	cmpwi	r11,IRQS_ENABLED
52813799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
529e485f6c7SNicholas Piggin	beq	.Linterrupt_return_\srr\()_soft_enabled
530e485f6c7SNicholas Piggin
531e485f6c7SNicholas Piggin	/*
532e485f6c7SNicholas Piggin	 * Returning to soft-disabled context.
533e485f6c7SNicholas Piggin	 * Check if a MUST_HARD_MASK interrupt has become pending, in which
534e485f6c7SNicholas Piggin	 * case we need to disable MSR[EE] in the return context.
535*65722736SNicholas Piggin	 *
536*65722736SNicholas Piggin	 * The MSR[EE] check catches among other things the short incoherency
537*65722736SNicholas Piggin	 * in hard_irq_disable() between clearing MSR[EE] and setting
538*65722736SNicholas Piggin	 * PACA_IRQ_HARD_DIS.
539e485f6c7SNicholas Piggin	 */
540e485f6c7SNicholas Piggin	ld	r12,_MSR(r1)
541e485f6c7SNicholas Piggin	andi.	r10,r12,MSR_EE
542e485f6c7SNicholas Piggin	beq	.Lfast_kernel_interrupt_return_\srr\() // EE already disabled
543e485f6c7SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
544e485f6c7SNicholas Piggin	andi.	r10,r11,PACA_IRQ_MUST_HARD_MASK
545*65722736SNicholas Piggin	bne	1f // HARD_MASK is pending
546*65722736SNicholas Piggin	// No HARD_MASK pending, clear possible HARD_DIS set by interrupt
547*65722736SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
548*65722736SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13)
549*65722736SNicholas Piggin	b	.Lfast_kernel_interrupt_return_\srr\()
550e485f6c7SNicholas Piggin
551*65722736SNicholas Piggin
552*65722736SNicholas Piggin1:	/* Must clear MSR_EE from _MSR */
553e485f6c7SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
554e485f6c7SNicholas Piggin	li	r10,0
555e485f6c7SNicholas Piggin	/* Clear valid before changing _MSR */
556e485f6c7SNicholas Piggin	.ifc \srr,srr
557e485f6c7SNicholas Piggin	stb	r10,PACASRR_VALID(r13)
558e485f6c7SNicholas Piggin	.else
559e485f6c7SNicholas Piggin	stb	r10,PACAHSRR_VALID(r13)
560e485f6c7SNicholas Piggin	.endif
561e485f6c7SNicholas Piggin#endif
562e485f6c7SNicholas Piggin	xori	r12,r12,MSR_EE
563e485f6c7SNicholas Piggin	std	r12,_MSR(r1)
564e485f6c7SNicholas Piggin	b	.Lfast_kernel_interrupt_return_\srr\()
565e485f6c7SNicholas Piggin
566e485f6c7SNicholas Piggin.Linterrupt_return_\srr\()_soft_enabled:
567a4cb3651SNicholas Piggin	/*
568a4cb3651SNicholas Piggin	 * In the soft-enabled case, need to double-check that we have no
569a4cb3651SNicholas Piggin	 * pending interrupts that might have come in before we reached the
570a4cb3651SNicholas Piggin	 * restart section of code, and restart the exit so those can be
571a4cb3651SNicholas Piggin	 * handled.
572a4cb3651SNicholas Piggin	 *
573a4cb3651SNicholas Piggin	 * If there are none, it is be possible that the interrupt still
574a4cb3651SNicholas Piggin	 * has PACA_IRQ_HARD_DIS set, which needs to be cleared for the
575a4cb3651SNicholas Piggin	 * interrupted context. This clear will not clobber a new pending
576a4cb3651SNicholas Piggin	 * interrupt coming in, because we're in the restart section, so
577a4cb3651SNicholas Piggin	 * such would return to the restart location.
578a4cb3651SNicholas Piggin	 */
5799b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
58013799748SNicholas Piggin	lbz	r11,PACAIRQHAPPENED(r13)
58113799748SNicholas Piggin	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
58213799748SNicholas Piggin	bne-	interrupt_return_\srr\()_kernel_restart
5839b69d48cSNicholas Piggin#endif
584e485f6c7SNicholas Piggin	li	r11,0
585e485f6c7SNicholas Piggin	stb	r11,PACAIRQHAPPENED(r13) // clear the possible HARD_DIS
58613799748SNicholas Piggin
587e754f4d1SNicholas Piggin.Lfast_kernel_interrupt_return_\srr\():
588e754f4d1SNicholas Piggin	cmpdi	cr1,r3,0
589e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
590e754f4d1SNicholas Piggin	.ifc \srr,srr
591e754f4d1SNicholas Piggin	lbz	r4,PACASRR_VALID(r13)
592e754f4d1SNicholas Piggin	.else
593e754f4d1SNicholas Piggin	lbz	r4,PACAHSRR_VALID(r13)
594e754f4d1SNicholas Piggin	.endif
595e754f4d1SNicholas Piggin	cmpdi	r4,0
596e754f4d1SNicholas Piggin	li	r4,0
597e754f4d1SNicholas Piggin	bne	1f
598e754f4d1SNicholas Piggin#endif
599e754f4d1SNicholas Piggin	ld	r11,_NIP(r1)
600e754f4d1SNicholas Piggin	ld	r12,_MSR(r1)
601e754f4d1SNicholas Piggin	.ifc \srr,srr
602e754f4d1SNicholas Piggin	mtspr	SPRN_SRR0,r11
603e754f4d1SNicholas Piggin	mtspr	SPRN_SRR1,r12
604e754f4d1SNicholas Piggin1:
605e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
606e754f4d1SNicholas Piggin	stb	r4,PACASRR_VALID(r13)
607e754f4d1SNicholas Piggin#endif
608e754f4d1SNicholas Piggin	.else
609e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR0,r11
610e754f4d1SNicholas Piggin	mtspr	SPRN_HSRR1,r12
611e754f4d1SNicholas Piggin1:
612e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
613e754f4d1SNicholas Piggin	stb	r4,PACAHSRR_VALID(r13)
614e754f4d1SNicholas Piggin#endif
615e754f4d1SNicholas Piggin	.endif
616e754f4d1SNicholas Piggin	DEBUG_SRR_VALID \srr
617e754f4d1SNicholas Piggin
618e754f4d1SNicholas PigginBEGIN_FTR_SECTION
619e754f4d1SNicholas Piggin	stdcx.	r0,0,r1		/* to clear the reservation */
620e754f4d1SNicholas PigginFTR_SECTION_ELSE
621e754f4d1SNicholas Piggin	ldarx	r0,0,r1
622e754f4d1SNicholas PigginALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
623e754f4d1SNicholas Piggin
624e754f4d1SNicholas Piggin	ld	r3,_LINK(r1)
625e754f4d1SNicholas Piggin	ld	r4,_CTR(r1)
626e754f4d1SNicholas Piggin	ld	r5,_XER(r1)
627e754f4d1SNicholas Piggin	ld	r6,_CCR(r1)
628e754f4d1SNicholas Piggin	li	r0,0
629e754f4d1SNicholas Piggin
630aebd1fb4SNicholas Piggin	REST_GPRS(7, 12, r1)
631e754f4d1SNicholas Piggin
632e754f4d1SNicholas Piggin	mtlr	r3
633e754f4d1SNicholas Piggin	mtctr	r4
634e754f4d1SNicholas Piggin	mtspr	SPRN_XER,r5
635e754f4d1SNicholas Piggin
636e754f4d1SNicholas Piggin	/*
63717773afdSNicholas Piggin	 * Leaving a stale STACK_FRAME_REGS_MARKER on the stack can confuse
638e754f4d1SNicholas Piggin	 * the reliable stack unwinder later on. Clear it.
639e754f4d1SNicholas Piggin	 */
640e754f4d1SNicholas Piggin	std	r0,STACK_FRAME_OVERHEAD-16(r1)
641e754f4d1SNicholas Piggin
642aebd1fb4SNicholas Piggin	REST_GPRS(2, 5, r1)
643e754f4d1SNicholas Piggin
644e754f4d1SNicholas Piggin	bne-	cr1,1f /* emulate stack store */
645e754f4d1SNicholas Piggin	mtcr	r6
646e754f4d1SNicholas Piggin	REST_GPR(6, r1)
647e754f4d1SNicholas Piggin	REST_GPR(0, r1)
648e754f4d1SNicholas Piggin	REST_GPR(1, r1)
649e754f4d1SNicholas Piggin	.ifc \srr,srr
650e754f4d1SNicholas Piggin	RFI_TO_KERNEL
651e754f4d1SNicholas Piggin	.else
652e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
653e754f4d1SNicholas Piggin	.endif
654e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
655e754f4d1SNicholas Piggin
656e754f4d1SNicholas Piggin1:	/*
657e754f4d1SNicholas Piggin	 * Emulate stack store with update. New r1 value was already calculated
658e754f4d1SNicholas Piggin	 * and updated in our interrupt regs by emulate_loadstore, but we can't
659e754f4d1SNicholas Piggin	 * store the previous value of r1 to the stack before re-loading our
660e754f4d1SNicholas Piggin	 * registers from it, otherwise they could be clobbered.  Use
661e754f4d1SNicholas Piggin	 * PACA_EXGEN as temporary storage to hold the store data, as
662e754f4d1SNicholas Piggin	 * interrupts are disabled here so it won't be clobbered.
663e754f4d1SNicholas Piggin	 */
664e754f4d1SNicholas Piggin	mtcr	r6
665e754f4d1SNicholas Piggin	std	r9,PACA_EXGEN+0(r13)
666e754f4d1SNicholas Piggin	addi	r9,r1,INT_FRAME_SIZE /* get original r1 */
667e754f4d1SNicholas Piggin	REST_GPR(6, r1)
668e754f4d1SNicholas Piggin	REST_GPR(0, r1)
669e754f4d1SNicholas Piggin	REST_GPR(1, r1)
670e754f4d1SNicholas Piggin	std	r9,0(r1) /* perform store component of stdu */
671e754f4d1SNicholas Piggin	ld	r9,PACA_EXGEN+0(r13)
672e754f4d1SNicholas Piggin
673e754f4d1SNicholas Piggin	.ifc \srr,srr
674e754f4d1SNicholas Piggin	RFI_TO_KERNEL
675e754f4d1SNicholas Piggin	.else
676e754f4d1SNicholas Piggin	HRFI_TO_KERNEL
677e754f4d1SNicholas Piggin	.endif
678e754f4d1SNicholas Piggin	b	.	/* prevent speculative execution */
67913799748SNicholas Piggin.Linterrupt_return_\srr\()_kernel_rst_end:
68013799748SNicholas Piggin
6819b69d48cSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
68213799748SNicholas Piggininterrupt_return_\srr\()_kernel_restart:
68398798f33SNicholas Piggin_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel_restart)
68413799748SNicholas Piggin	GET_PACA(r13)
68513799748SNicholas Piggin	ld	r1,PACA_EXIT_SAVE_R1(r13)
6868e93fb33SNicholas Piggin	LOAD_PACA_TOC()
68713799748SNicholas Piggin	addi	r3,r1,STACK_FRAME_OVERHEAD
68813799748SNicholas Piggin	li	r11,IRQS_ALL_DISABLED
68913799748SNicholas Piggin	stb	r11,PACAIRQSOFTMASK(r13)
69013799748SNicholas Piggin	bl	interrupt_exit_kernel_restart
69113799748SNicholas Piggin	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
69213799748SNicholas Piggin	b	.Linterrupt_return_\srr\()_kernel_rst_start
693325678fdSNicholas Piggin1:
69413799748SNicholas Piggin
695325678fdSNicholas PigginSOFT_MASK_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, 1b)
69613799748SNicholas PigginRESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
6979b69d48cSNicholas Piggin#endif
69813799748SNicholas Piggin
699e754f4d1SNicholas Piggin.endm
700e754f4d1SNicholas Piggin
701e754f4d1SNicholas Piggininterrupt_return_macro srr
702e754f4d1SNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
703e754f4d1SNicholas Piggininterrupt_return_macro hsrr
7049d1988caSNicholas Piggin
7059d1988caSNicholas Piggin	.globl __end_soft_masked
7069d1988caSNicholas Piggin__end_soft_masked:
707d72c4a36SDaniel AxtensDEFINE_FIXED_SYMBOL(__end_soft_masked, text)
7089b69d48cSNicholas Piggin#endif /* CONFIG_PPC_BOOK3S */
70991fc46ecSNicholas Piggin
71091fc46ecSNicholas Piggin#ifdef CONFIG_PPC_BOOK3S
71191fc46ecSNicholas Piggin_GLOBAL(ret_from_fork_scv)
71291fc46ecSNicholas Piggin	bl	schedule_tail
71391fc46ecSNicholas Piggin	REST_NVGPRS(r1)
71491fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
71591fc46ecSNicholas Piggin	b	.Lsyscall_vectored_common_exit
71691fc46ecSNicholas Piggin#endif
71791fc46ecSNicholas Piggin
71891fc46ecSNicholas Piggin_GLOBAL(ret_from_fork)
71991fc46ecSNicholas Piggin	bl	schedule_tail
72091fc46ecSNicholas Piggin	REST_NVGPRS(r1)
72191fc46ecSNicholas Piggin	li	r3,0	/* fork() return value */
72291fc46ecSNicholas Piggin	b	.Lsyscall_exit
72391fc46ecSNicholas Piggin
72491fc46ecSNicholas Piggin_GLOBAL(ret_from_kernel_thread)
72591fc46ecSNicholas Piggin	bl	schedule_tail
72691fc46ecSNicholas Piggin	REST_NVGPRS(r1)
72791fc46ecSNicholas Piggin	mtctr	r14
72891fc46ecSNicholas Piggin	mr	r3,r15
7297d40aff8SChristophe Leroy#ifdef CONFIG_PPC64_ELF_ABI_V2
73091fc46ecSNicholas Piggin	mr	r12,r14
73191fc46ecSNicholas Piggin#endif
73291fc46ecSNicholas Piggin	bctrl
73391fc46ecSNicholas Piggin	li	r3,0
73491fc46ecSNicholas Piggin	b	.Lsyscall_exit
735