cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

interrupt_64.S (16510B)


      1#include <asm/asm-offsets.h>
      2#include <asm/bug.h>
      3#ifdef CONFIG_PPC_BOOK3S
      4#include <asm/exception-64s.h>
      5#else
      6#include <asm/exception-64e.h>
      7#endif
      8#include <asm/feature-fixups.h>
      9#include <asm/head-64.h>
     10#include <asm/hw_irq.h>
     11#include <asm/kup.h>
     12#include <asm/mmu.h>
     13#include <asm/ppc_asm.h>
     14#include <asm/ptrace.h>
     15
     16	.section	".toc","aw"
     17SYS_CALL_TABLE:
     18	.tc sys_call_table[TC],sys_call_table
     19
     20#ifdef CONFIG_COMPAT
     21COMPAT_SYS_CALL_TABLE:
     22	.tc compat_sys_call_table[TC],compat_sys_call_table
     23#endif
     24	.previous
     25
     26	.align 7
     27
     28.macro DEBUG_SRR_VALID srr
     29#ifdef CONFIG_PPC_RFI_SRR_DEBUG
     30	.ifc \srr,srr
     31	mfspr	r11,SPRN_SRR0
     32	ld	r12,_NIP(r1)
     33	clrrdi  r11,r11,2
     34	clrrdi  r12,r12,2
     35100:	tdne	r11,r12
     36	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
     37	mfspr	r11,SPRN_SRR1
     38	ld	r12,_MSR(r1)
     39100:	tdne	r11,r12
     40	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
     41	.else
     42	mfspr	r11,SPRN_HSRR0
     43	ld	r12,_NIP(r1)
     44	clrrdi  r11,r11,2
     45	clrrdi  r12,r12,2
     46100:	tdne	r11,r12
     47	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
     48	mfspr	r11,SPRN_HSRR1
     49	ld	r12,_MSR(r1)
     50100:	tdne	r11,r12
     51	EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE)
     52	.endif
     53#endif
     54.endm
     55
     56#ifdef CONFIG_PPC_BOOK3S
     57.macro system_call_vectored name trapnr
     58	.globl system_call_vectored_\name
     59system_call_vectored_\name:
     60_ASM_NOKPROBE_SYMBOL(system_call_vectored_\name)
     61	SCV_INTERRUPT_TO_KERNEL
     62	mr	r10,r1
     63	ld	r1,PACAKSAVE(r13)
     64	std	r10,0(r1)
     65	std	r11,_NIP(r1)
     66	std	r12,_MSR(r1)
     67	std	r0,GPR0(r1)
     68	std	r10,GPR1(r1)
     69	std	r2,GPR2(r1)
     70	ld	r2,PACATOC(r13)
     71	mfcr	r12
     72	li	r11,0
     73	/* Can we avoid saving r3-r8 in common case? */
     74	std	r3,GPR3(r1)
     75	std	r4,GPR4(r1)
     76	std	r5,GPR5(r1)
     77	std	r6,GPR6(r1)
     78	std	r7,GPR7(r1)
     79	std	r8,GPR8(r1)
     80	/* Zero r9-r12, this should only be required when restoring all GPRs */
     81	std	r11,GPR9(r1)
     82	std	r11,GPR10(r1)
     83	std	r11,GPR11(r1)
     84	std	r11,GPR12(r1)
     85	std	r9,GPR13(r1)
     86	SAVE_NVGPRS(r1)
     87	std	r11,_XER(r1)
     88	std	r11,_LINK(r1)
     89	std	r11,_CTR(r1)
     90
     91	li	r11,\trapnr
     92	std	r11,_TRAP(r1)
     93	std	r12,_CCR(r1)
     94	addi	r10,r1,STACK_FRAME_OVERHEAD
     95	ld	r11,exception_marker@toc(r2)
     96	std	r11,-16(r10)		/* "regshere" marker */
     97
     98BEGIN_FTR_SECTION
     99	HMT_MEDIUM
    100END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
    101
    102	/*
    103	 * scv enters with MSR[EE]=1 and is immediately considered soft-masked.
    104	 * The entry vector already sets PACAIRQSOFTMASK to IRQS_ALL_DISABLED,
    105	 * and interrupts may be masked and pending already.
    106	 * system_call_exception() will call trace_hardirqs_off() which means
    107	 * interrupts could already have been blocked before trace_hardirqs_off,
    108	 * but this is the best we can do.
    109	 */
    110
    111	/* Calling convention has r9 = orig r0, r10 = regs */
    112	mr	r9,r0
    113	bl	system_call_exception
    114
    115.Lsyscall_vectored_\name\()_exit:
    116	addi	r4,r1,STACK_FRAME_OVERHEAD
    117	li	r5,1 /* scv */
    118	bl	syscall_exit_prepare
    119	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    120.Lsyscall_vectored_\name\()_rst_start:
    121	lbz	r11,PACAIRQHAPPENED(r13)
    122	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
    123	bne-	syscall_vectored_\name\()_restart
    124	li	r11,IRQS_ENABLED
    125	stb	r11,PACAIRQSOFTMASK(r13)
    126	li	r11,0
    127	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
    128
    129	ld	r2,_CCR(r1)
    130	ld	r4,_NIP(r1)
    131	ld	r5,_MSR(r1)
    132
    133BEGIN_FTR_SECTION
    134	stdcx.	r0,0,r1			/* to clear the reservation */
    135END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
    136
    137BEGIN_FTR_SECTION
    138	HMT_MEDIUM_LOW
    139END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
    140
    141	cmpdi	r3,0
    142	bne	.Lsyscall_vectored_\name\()_restore_regs
    143
    144	/* rfscv returns with LR->NIA and CTR->MSR */
    145	mtlr	r4
    146	mtctr	r5
    147
    148	/* Could zero these as per ABI, but we may consider a stricter ABI
    149	 * which preserves these if libc implementations can benefit, so
    150	 * restore them for now until further measurement is done. */
    151	ld	r0,GPR0(r1)
    152	ld	r4,GPR4(r1)
    153	ld	r5,GPR5(r1)
    154	ld	r6,GPR6(r1)
    155	ld	r7,GPR7(r1)
    156	ld	r8,GPR8(r1)
    157	/* Zero volatile regs that may contain sensitive kernel data */
    158	li	r9,0
    159	li	r10,0
    160	li	r11,0
    161	li	r12,0
    162	mtspr	SPRN_XER,r0
    163
    164	/*
    165	 * We don't need to restore AMR on the way back to userspace for KUAP.
    166	 * The value of AMR only matters while we're in the kernel.
    167	 */
    168	mtcr	r2
    169	REST_GPRS(2, 3, r1)
    170	REST_GPR(13, r1)
    171	REST_GPR(1, r1)
    172	RFSCV_TO_USER
    173	b	.	/* prevent speculative execution */
    174
    175.Lsyscall_vectored_\name\()_restore_regs:
    176	mtspr	SPRN_SRR0,r4
    177	mtspr	SPRN_SRR1,r5
    178
    179	ld	r3,_CTR(r1)
    180	ld	r4,_LINK(r1)
    181	ld	r5,_XER(r1)
    182
    183	REST_NVGPRS(r1)
    184	ld	r0,GPR0(r1)
    185	mtcr	r2
    186	mtctr	r3
    187	mtlr	r4
    188	mtspr	SPRN_XER,r5
    189	REST_GPRS(2, 13, r1)
    190	REST_GPR(1, r1)
    191	RFI_TO_USER
    192.Lsyscall_vectored_\name\()_rst_end:
    193
    194syscall_vectored_\name\()_restart:
    195_ASM_NOKPROBE_SYMBOL(syscall_vectored_\name\()_restart)
    196	GET_PACA(r13)
    197	ld	r1,PACA_EXIT_SAVE_R1(r13)
    198	ld	r2,PACATOC(r13)
    199	ld	r3,RESULT(r1)
    200	addi	r4,r1,STACK_FRAME_OVERHEAD
    201	li	r11,IRQS_ALL_DISABLED
    202	stb	r11,PACAIRQSOFTMASK(r13)
    203	bl	syscall_exit_restart
    204	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    205	b	.Lsyscall_vectored_\name\()_rst_start
    2061:
    207
    208SOFT_MASK_TABLE(.Lsyscall_vectored_\name\()_rst_start, 1b)
    209RESTART_TABLE(.Lsyscall_vectored_\name\()_rst_start, .Lsyscall_vectored_\name\()_rst_end, syscall_vectored_\name\()_restart)
    210
    211.endm
    212
    213system_call_vectored common 0x3000
    214
    215/*
    216 * We instantiate another entry copy for the SIGILL variant, with TRAP=0x7ff0
    217 * which is tested by system_call_exception when r0 is -1 (as set by vector
    218 * entry code).
    219 */
    220system_call_vectored sigill 0x7ff0
    221
    222#endif /* CONFIG_PPC_BOOK3S */
    223
    224	.balign IFETCH_ALIGN_BYTES
    225	.globl system_call_common_real
    226system_call_common_real:
    227_ASM_NOKPROBE_SYMBOL(system_call_common_real)
    228	ld	r10,PACAKMSR(r13)	/* get MSR value for kernel */
    229	mtmsrd	r10
    230
    231	.balign IFETCH_ALIGN_BYTES
    232	.globl system_call_common
    233system_call_common:
    234_ASM_NOKPROBE_SYMBOL(system_call_common)
    235	mr	r10,r1
    236	ld	r1,PACAKSAVE(r13)
    237	std	r10,0(r1)
    238	std	r11,_NIP(r1)
    239	std	r12,_MSR(r1)
    240	std	r0,GPR0(r1)
    241	std	r10,GPR1(r1)
    242	std	r2,GPR2(r1)
    243#ifdef CONFIG_PPC_FSL_BOOK3E
    244START_BTB_FLUSH_SECTION
    245	BTB_FLUSH(r10)
    246END_BTB_FLUSH_SECTION
    247#endif
    248	ld	r2,PACATOC(r13)
    249	mfcr	r12
    250	li	r11,0
    251	/* Can we avoid saving r3-r8 in common case? */
    252	std	r3,GPR3(r1)
    253	std	r4,GPR4(r1)
    254	std	r5,GPR5(r1)
    255	std	r6,GPR6(r1)
    256	std	r7,GPR7(r1)
    257	std	r8,GPR8(r1)
    258	/* Zero r9-r12, this should only be required when restoring all GPRs */
    259	std	r11,GPR9(r1)
    260	std	r11,GPR10(r1)
    261	std	r11,GPR11(r1)
    262	std	r11,GPR12(r1)
    263	std	r9,GPR13(r1)
    264	SAVE_NVGPRS(r1)
    265	std	r11,_XER(r1)
    266	std	r11,_CTR(r1)
    267	mflr	r10
    268
    269	/*
    270	 * This clears CR0.SO (bit 28), which is the error indication on
    271	 * return from this system call.
    272	 */
    273	rldimi	r12,r11,28,(63-28)
    274	li	r11,0xc00
    275	std	r10,_LINK(r1)
    276	std	r11,_TRAP(r1)
    277	std	r12,_CCR(r1)
    278	addi	r10,r1,STACK_FRAME_OVERHEAD
    279	ld	r11,exception_marker@toc(r2)
    280	std	r11,-16(r10)		/* "regshere" marker */
    281
    282#ifdef CONFIG_PPC_BOOK3S
    283	li	r11,1
    284	stb	r11,PACASRR_VALID(r13)
    285#endif
    286
    287	/*
    288	 * We always enter kernel from userspace with irq soft-mask enabled and
    289	 * nothing pending. system_call_exception() will call
    290	 * trace_hardirqs_off().
    291	 */
    292	li	r11,IRQS_ALL_DISABLED
    293	stb	r11,PACAIRQSOFTMASK(r13)
    294#ifdef CONFIG_PPC_BOOK3S
    295	li	r12,-1 /* Set MSR_EE and MSR_RI */
    296	mtmsrd	r12,1
    297#else
    298	wrteei	1
    299#endif
    300
    301	/* Calling convention has r9 = orig r0, r10 = regs */
    302	mr	r9,r0
    303	bl	system_call_exception
    304
    305.Lsyscall_exit:
    306	addi	r4,r1,STACK_FRAME_OVERHEAD
    307	li	r5,0 /* !scv */
    308	bl	syscall_exit_prepare
    309	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    310#ifdef CONFIG_PPC_BOOK3S
    311.Lsyscall_rst_start:
    312	lbz	r11,PACAIRQHAPPENED(r13)
    313	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
    314	bne-	syscall_restart
    315#endif
    316	li	r11,IRQS_ENABLED
    317	stb	r11,PACAIRQSOFTMASK(r13)
    318	li	r11,0
    319	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
    320
    321	ld	r2,_CCR(r1)
    322	ld	r6,_LINK(r1)
    323	mtlr	r6
    324
    325#ifdef CONFIG_PPC_BOOK3S
    326	lbz	r4,PACASRR_VALID(r13)
    327	cmpdi	r4,0
    328	bne	1f
    329	li	r4,0
    330	stb	r4,PACASRR_VALID(r13)
    331#endif
    332	ld	r4,_NIP(r1)
    333	ld	r5,_MSR(r1)
    334	mtspr	SPRN_SRR0,r4
    335	mtspr	SPRN_SRR1,r5
    3361:
    337	DEBUG_SRR_VALID srr
    338
    339BEGIN_FTR_SECTION
    340	stdcx.	r0,0,r1			/* to clear the reservation */
    341END_FTR_SECTION_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
    342
    343	cmpdi	r3,0
    344	bne	.Lsyscall_restore_regs
    345	/* Zero volatile regs that may contain sensitive kernel data */
    346	li	r0,0
    347	li	r4,0
    348	li	r5,0
    349	li	r6,0
    350	li	r7,0
    351	li	r8,0
    352	li	r9,0
    353	li	r10,0
    354	li	r11,0
    355	li	r12,0
    356	mtctr	r0
    357	mtspr	SPRN_XER,r0
    358.Lsyscall_restore_regs_cont:
    359
    360BEGIN_FTR_SECTION
    361	HMT_MEDIUM_LOW
    362END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
    363
    364	/*
    365	 * We don't need to restore AMR on the way back to userspace for KUAP.
    366	 * The value of AMR only matters while we're in the kernel.
    367	 */
    368	mtcr	r2
    369	REST_GPRS(2, 3, r1)
    370	REST_GPR(13, r1)
    371	REST_GPR(1, r1)
    372	RFI_TO_USER
    373	b	.	/* prevent speculative execution */
    374
    375.Lsyscall_restore_regs:
    376	ld	r3,_CTR(r1)
    377	ld	r4,_XER(r1)
    378	REST_NVGPRS(r1)
    379	mtctr	r3
    380	mtspr	SPRN_XER,r4
    381	ld	r0,GPR0(r1)
    382	REST_GPRS(4, 12, r1)
    383	b	.Lsyscall_restore_regs_cont
    384.Lsyscall_rst_end:
    385
    386#ifdef CONFIG_PPC_BOOK3S
    387syscall_restart:
    388_ASM_NOKPROBE_SYMBOL(syscall_restart)
    389	GET_PACA(r13)
    390	ld	r1,PACA_EXIT_SAVE_R1(r13)
    391	ld	r2,PACATOC(r13)
    392	ld	r3,RESULT(r1)
    393	addi	r4,r1,STACK_FRAME_OVERHEAD
    394	li	r11,IRQS_ALL_DISABLED
    395	stb	r11,PACAIRQSOFTMASK(r13)
    396	bl	syscall_exit_restart
    397	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    398	b	.Lsyscall_rst_start
    3991:
    400
    401SOFT_MASK_TABLE(.Lsyscall_rst_start, 1b)
    402RESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
    403#endif
    404
    405	/*
    406	 * If MSR EE/RI was never enabled, IRQs not reconciled, NVGPRs not
    407	 * touched, no exit work created, then this can be used.
    408	 */
    409	.balign IFETCH_ALIGN_BYTES
    410	.globl fast_interrupt_return_srr
    411fast_interrupt_return_srr:
    412_ASM_NOKPROBE_SYMBOL(fast_interrupt_return_srr)
    413	kuap_check_amr r3, r4
    414	ld	r5,_MSR(r1)
    415	andi.	r0,r5,MSR_PR
    416#ifdef CONFIG_PPC_BOOK3S
    417	beq	1f
    418	kuap_user_restore r3, r4
    419	b	.Lfast_user_interrupt_return_srr
    4201:	kuap_kernel_restore r3, r4
    421	andi.	r0,r5,MSR_RI
    422	li	r3,0 /* 0 return value, no EMULATE_STACK_STORE */
    423	bne+	.Lfast_kernel_interrupt_return_srr
    424	addi	r3,r1,STACK_FRAME_OVERHEAD
    425	bl	unrecoverable_exception
    426	b	. /* should not get here */
    427#else
    428	bne	.Lfast_user_interrupt_return_srr
    429	b	.Lfast_kernel_interrupt_return_srr
    430#endif
    431
    432.macro interrupt_return_macro srr
    433	.balign IFETCH_ALIGN_BYTES
    434	.globl interrupt_return_\srr
    435interrupt_return_\srr\():
    436_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\())
    437	ld	r4,_MSR(r1)
    438	andi.	r0,r4,MSR_PR
    439	beq	interrupt_return_\srr\()_kernel
    440interrupt_return_\srr\()_user: /* make backtraces match the _kernel variant */
    441_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user)
    442	addi	r3,r1,STACK_FRAME_OVERHEAD
    443	bl	interrupt_exit_user_prepare
    444	cmpdi	r3,0
    445	bne-	.Lrestore_nvgprs_\srr
    446.Lrestore_nvgprs_\srr\()_cont:
    447	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    448#ifdef CONFIG_PPC_BOOK3S
    449.Linterrupt_return_\srr\()_user_rst_start:
    450	lbz	r11,PACAIRQHAPPENED(r13)
    451	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
    452	bne-	interrupt_return_\srr\()_user_restart
    453#endif
    454	li	r11,IRQS_ENABLED
    455	stb	r11,PACAIRQSOFTMASK(r13)
    456	li	r11,0
    457	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
    458
    459.Lfast_user_interrupt_return_\srr\():
    460#ifdef CONFIG_PPC_BOOK3S
    461	.ifc \srr,srr
    462	lbz	r4,PACASRR_VALID(r13)
    463	.else
    464	lbz	r4,PACAHSRR_VALID(r13)
    465	.endif
    466	cmpdi	r4,0
    467	li	r4,0
    468	bne	1f
    469#endif
    470	ld	r11,_NIP(r1)
    471	ld	r12,_MSR(r1)
    472	.ifc \srr,srr
    473	mtspr	SPRN_SRR0,r11
    474	mtspr	SPRN_SRR1,r12
    4751:
    476#ifdef CONFIG_PPC_BOOK3S
    477	stb	r4,PACASRR_VALID(r13)
    478#endif
    479	.else
    480	mtspr	SPRN_HSRR0,r11
    481	mtspr	SPRN_HSRR1,r12
    4821:
    483#ifdef CONFIG_PPC_BOOK3S
    484	stb	r4,PACAHSRR_VALID(r13)
    485#endif
    486	.endif
    487	DEBUG_SRR_VALID \srr
    488
    489#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
    490	lbz	r4,PACAIRQSOFTMASK(r13)
    491	tdnei	r4,IRQS_ENABLED
    492#endif
    493
    494BEGIN_FTR_SECTION
    495	ld	r10,_PPR(r1)
    496	mtspr	SPRN_PPR,r10
    497END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
    498
    499BEGIN_FTR_SECTION
    500	stdcx.	r0,0,r1		/* to clear the reservation */
    501FTR_SECTION_ELSE
    502	ldarx	r0,0,r1
    503ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
    504
    505	ld	r3,_CCR(r1)
    506	ld	r4,_LINK(r1)
    507	ld	r5,_CTR(r1)
    508	ld	r6,_XER(r1)
    509	li	r0,0
    510
    511	REST_GPRS(7, 13, r1)
    512
    513	mtcr	r3
    514	mtlr	r4
    515	mtctr	r5
    516	mtspr	SPRN_XER,r6
    517
    518	REST_GPRS(2, 6, r1)
    519	REST_GPR(0, r1)
    520	REST_GPR(1, r1)
    521	.ifc \srr,srr
    522	RFI_TO_USER
    523	.else
    524	HRFI_TO_USER
    525	.endif
    526	b	.	/* prevent speculative execution */
    527.Linterrupt_return_\srr\()_user_rst_end:
    528
    529.Lrestore_nvgprs_\srr\():
    530	REST_NVGPRS(r1)
    531	b	.Lrestore_nvgprs_\srr\()_cont
    532
    533#ifdef CONFIG_PPC_BOOK3S
    534interrupt_return_\srr\()_user_restart:
    535_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_user_restart)
    536	GET_PACA(r13)
    537	ld	r1,PACA_EXIT_SAVE_R1(r13)
    538	ld	r2,PACATOC(r13)
    539	addi	r3,r1,STACK_FRAME_OVERHEAD
    540	li	r11,IRQS_ALL_DISABLED
    541	stb	r11,PACAIRQSOFTMASK(r13)
    542	bl	interrupt_exit_user_restart
    543	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    544	b	.Linterrupt_return_\srr\()_user_rst_start
    5451:
    546
    547SOFT_MASK_TABLE(.Linterrupt_return_\srr\()_user_rst_start, 1b)
    548RESTART_TABLE(.Linterrupt_return_\srr\()_user_rst_start, .Linterrupt_return_\srr\()_user_rst_end, interrupt_return_\srr\()_user_restart)
    549#endif
    550
    551	.balign IFETCH_ALIGN_BYTES
    552interrupt_return_\srr\()_kernel:
    553_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel)
    554	addi	r3,r1,STACK_FRAME_OVERHEAD
    555	bl	interrupt_exit_kernel_prepare
    556
    557	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    558.Linterrupt_return_\srr\()_kernel_rst_start:
    559	ld	r11,SOFTE(r1)
    560	cmpwi	r11,IRQS_ENABLED
    561	stb	r11,PACAIRQSOFTMASK(r13)
    562	bne	1f
    563#ifdef CONFIG_PPC_BOOK3S
    564	lbz	r11,PACAIRQHAPPENED(r13)
    565	andi.	r11,r11,(~PACA_IRQ_HARD_DIS)@l
    566	bne-	interrupt_return_\srr\()_kernel_restart
    567#endif
    568	li	r11,0
    569	stb	r11,PACAIRQHAPPENED(r13) # clear out possible HARD_DIS
    5701:
    571
    572.Lfast_kernel_interrupt_return_\srr\():
    573	cmpdi	cr1,r3,0
    574#ifdef CONFIG_PPC_BOOK3S
    575	.ifc \srr,srr
    576	lbz	r4,PACASRR_VALID(r13)
    577	.else
    578	lbz	r4,PACAHSRR_VALID(r13)
    579	.endif
    580	cmpdi	r4,0
    581	li	r4,0
    582	bne	1f
    583#endif
    584	ld	r11,_NIP(r1)
    585	ld	r12,_MSR(r1)
    586	.ifc \srr,srr
    587	mtspr	SPRN_SRR0,r11
    588	mtspr	SPRN_SRR1,r12
    5891:
    590#ifdef CONFIG_PPC_BOOK3S
    591	stb	r4,PACASRR_VALID(r13)
    592#endif
    593	.else
    594	mtspr	SPRN_HSRR0,r11
    595	mtspr	SPRN_HSRR1,r12
    5961:
    597#ifdef CONFIG_PPC_BOOK3S
    598	stb	r4,PACAHSRR_VALID(r13)
    599#endif
    600	.endif
    601	DEBUG_SRR_VALID \srr
    602
    603BEGIN_FTR_SECTION
    604	stdcx.	r0,0,r1		/* to clear the reservation */
    605FTR_SECTION_ELSE
    606	ldarx	r0,0,r1
    607ALT_FTR_SECTION_END_IFCLR(CPU_FTR_STCX_CHECKS_ADDRESS)
    608
    609	ld	r3,_LINK(r1)
    610	ld	r4,_CTR(r1)
    611	ld	r5,_XER(r1)
    612	ld	r6,_CCR(r1)
    613	li	r0,0
    614
    615	REST_GPRS(7, 12, r1)
    616
    617	mtlr	r3
    618	mtctr	r4
    619	mtspr	SPRN_XER,r5
    620
    621	/*
    622	 * Leaving a stale exception_marker on the stack can confuse
    623	 * the reliable stack unwinder later on. Clear it.
    624	 */
    625	std	r0,STACK_FRAME_OVERHEAD-16(r1)
    626
    627	REST_GPRS(2, 5, r1)
    628
    629	bne-	cr1,1f /* emulate stack store */
    630	mtcr	r6
    631	REST_GPR(6, r1)
    632	REST_GPR(0, r1)
    633	REST_GPR(1, r1)
    634	.ifc \srr,srr
    635	RFI_TO_KERNEL
    636	.else
    637	HRFI_TO_KERNEL
    638	.endif
    639	b	.	/* prevent speculative execution */
    640
    6411:	/*
    642	 * Emulate stack store with update. New r1 value was already calculated
    643	 * and updated in our interrupt regs by emulate_loadstore, but we can't
    644	 * store the previous value of r1 to the stack before re-loading our
    645	 * registers from it, otherwise they could be clobbered.  Use
    646	 * PACA_EXGEN as temporary storage to hold the store data, as
    647	 * interrupts are disabled here so it won't be clobbered.
    648	 */
    649	mtcr	r6
    650	std	r9,PACA_EXGEN+0(r13)
    651	addi	r9,r1,INT_FRAME_SIZE /* get original r1 */
    652	REST_GPR(6, r1)
    653	REST_GPR(0, r1)
    654	REST_GPR(1, r1)
    655	std	r9,0(r1) /* perform store component of stdu */
    656	ld	r9,PACA_EXGEN+0(r13)
    657
    658	.ifc \srr,srr
    659	RFI_TO_KERNEL
    660	.else
    661	HRFI_TO_KERNEL
    662	.endif
    663	b	.	/* prevent speculative execution */
    664.Linterrupt_return_\srr\()_kernel_rst_end:
    665
    666#ifdef CONFIG_PPC_BOOK3S
    667interrupt_return_\srr\()_kernel_restart:
    668_ASM_NOKPROBE_SYMBOL(interrupt_return_\srr\()_kernel_restart)
    669	GET_PACA(r13)
    670	ld	r1,PACA_EXIT_SAVE_R1(r13)
    671	ld	r2,PACATOC(r13)
    672	addi	r3,r1,STACK_FRAME_OVERHEAD
    673	li	r11,IRQS_ALL_DISABLED
    674	stb	r11,PACAIRQSOFTMASK(r13)
    675	bl	interrupt_exit_kernel_restart
    676	std	r1,PACA_EXIT_SAVE_R1(r13) /* save r1 for restart */
    677	b	.Linterrupt_return_\srr\()_kernel_rst_start
    6781:
    679
    680SOFT_MASK_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, 1b)
    681RESTART_TABLE(.Linterrupt_return_\srr\()_kernel_rst_start, .Linterrupt_return_\srr\()_kernel_rst_end, interrupt_return_\srr\()_kernel_restart)
    682#endif
    683
    684.endm
    685
    686interrupt_return_macro srr
    687#ifdef CONFIG_PPC_BOOK3S
    688interrupt_return_macro hsrr
    689
    690	.globl __end_soft_masked
    691__end_soft_masked:
    692DEFINE_FIXED_SYMBOL(__end_soft_masked, text)
    693#endif /* CONFIG_PPC_BOOK3S */
    694
    695#ifdef CONFIG_PPC_BOOK3S
    696_GLOBAL(ret_from_fork_scv)
    697	bl	schedule_tail
    698	REST_NVGPRS(r1)
    699	li	r3,0	/* fork() return value */
    700	b	.Lsyscall_vectored_common_exit
    701#endif
    702
    703_GLOBAL(ret_from_fork)
    704	bl	schedule_tail
    705	REST_NVGPRS(r1)
    706	li	r3,0	/* fork() return value */
    707	b	.Lsyscall_exit
    708
    709_GLOBAL(ret_from_kernel_thread)
    710	bl	schedule_tail
    711	REST_NVGPRS(r1)
    712	mtctr	r14
    713	mr	r3,r15
    714#ifdef CONFIG_PPC64_ELF_ABI_V2
    715	mr	r12,r14
    716#endif
    717	bctrl
    718	li	r3,0
    719	b	.Lsyscall_exit