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

rtas_entry.S (4103B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2
      3#include <asm/asm-offsets.h>
      4#include <asm/bug.h>
      5#include <asm/page.h>
      6#include <asm/ppc_asm.h>
      7
      8/*
      9 * RTAS is called with MSR IR, DR, EE disabled, and LR in the return address.
     10 *
     11 * Note: r3 is an input parameter to rtas, so don't trash it...
     12 */
     13
     14#ifdef CONFIG_PPC32
     15_GLOBAL(enter_rtas)
     16	stwu	r1,-INT_FRAME_SIZE(r1)
     17	mflr	r0
     18	stw	r0,INT_FRAME_SIZE+4(r1)
     19	LOAD_REG_ADDR(r4, rtas)
     20	lis	r6,1f@ha	/* physical return address for rtas */
     21	addi	r6,r6,1f@l
     22	tophys(r6,r6)
     23	lwz	r8,RTASENTRY(r4)
     24	lwz	r4,RTASBASE(r4)
     25	mfmsr	r9
     26	stw	r9,8(r1)
     27	li	r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
     28	mtlr	r6
     29	stw	r1, THREAD + RTAS_SP(r2)
     30	mtspr	SPRN_SRR0,r8
     31	mtspr	SPRN_SRR1,r9
     32	rfi
     331:
     34	lis	r8, 1f@h
     35	ori	r8, r8, 1f@l
     36	LOAD_REG_IMMEDIATE(r9,MSR_KERNEL)
     37	mtspr	SPRN_SRR0,r8
     38	mtspr	SPRN_SRR1,r9
     39	rfi			/* Reactivate MMU translation */
     401:
     41	lwz	r8,INT_FRAME_SIZE+4(r1)	/* get return address */
     42	lwz	r9,8(r1)	/* original msr value */
     43	addi	r1,r1,INT_FRAME_SIZE
     44	li	r0,0
     45	stw	r0, THREAD + RTAS_SP(r2)
     46	mtlr	r8
     47	mtmsr	r9
     48	blr			/* return to caller */
     49_ASM_NOKPROBE_SYMBOL(enter_rtas)
     50
     51#else /* CONFIG_PPC32 */
     52#include <asm/exception-64s.h>
     53
     54/*
     55 * 32-bit rtas on 64-bit machines has the additional problem that RTAS may
     56 * not preserve the upper parts of registers it uses.
     57 */
     58_GLOBAL(enter_rtas)
     59	mflr	r0
     60	std	r0,16(r1)
     61	stdu	r1,-SWITCH_FRAME_SIZE(r1) /* Save SP and create stack space. */
     62
     63	/* Because RTAS is running in 32b mode, it clobbers the high order half
     64	 * of all registers that it saves.  We therefore save those registers
     65	 * RTAS might touch to the stack.  (r0, r3-r12 are caller saved)
     66	 */
     67	SAVE_GPR(2, r1)			/* Save the TOC */
     68	SAVE_NVGPRS(r1)			/* Save the non-volatiles */
     69
     70	mfcr	r4
     71	std	r4,_CCR(r1)
     72	mfctr	r5
     73	std	r5,_CTR(r1)
     74	mfspr	r6,SPRN_XER
     75	std	r6,_XER(r1)
     76	mfdar	r7
     77	std	r7,_DAR(r1)
     78	mfdsisr	r8
     79	std	r8,_DSISR(r1)
     80
     81	/* Temporary workaround to clear CR until RTAS can be modified to
     82	 * ignore all bits.
     83	 */
     84	li	r0,0
     85	mtcr	r0
     86
     87	mfmsr	r6
     88
     89	/* Unfortunately, the stack pointer and the MSR are also clobbered,
     90	 * so they are saved in the PACA which allows us to restore
     91	 * our original state after RTAS returns.
     92	 */
     93	std	r1,PACAR1(r13)
     94	std	r6,PACASAVEDMSR(r13)
     95
     96	/* Setup our real return addr */
     97	LOAD_REG_ADDR(r4,rtas_return_loc)
     98	clrldi	r4,r4,2			/* convert to realmode address */
     99	mtlr	r4
    100
    101__enter_rtas:
    102	LOAD_REG_ADDR(r4, rtas)
    103	ld	r5,RTASENTRY(r4)	/* get the rtas->entry value */
    104	ld	r4,RTASBASE(r4)		/* get the rtas->base value */
    105
    106	/*
    107	 * RTAS runs in 32-bit big endian real mode, but leave MSR[RI] on as we
    108	 * may hit NMI (SRESET or MCE) while in RTAS. RTAS should disable RI in
    109	 * its critical regions (as specified in PAPR+ section 7.2.1). MSR[S]
    110	 * is not impacted by RFI_TO_KERNEL (only urfid can unset it). So if
    111	 * MSR[S] is set, it will remain when entering RTAS.
    112	 */
    113	LOAD_REG_IMMEDIATE(r6, MSR_ME | MSR_RI)
    114
    115	li      r0,0
    116	mtmsrd  r0,1                    /* disable RI before using SRR0/1 */
    117	
    118	mtspr	SPRN_SRR0,r5
    119	mtspr	SPRN_SRR1,r6
    120	RFI_TO_KERNEL
    121	b	.	/* prevent speculative execution */
    122rtas_return_loc:
    123	FIXUP_ENDIAN
    124
    125	/* Set SF before anything. */
    126	LOAD_REG_IMMEDIATE(r6, MSR_KERNEL & ~(MSR_IR|MSR_DR))
    127	mtmsrd	r6
    128
    129	/* relocation is off at this point */
    130	GET_PACA(r13)
    131
    132	bcl	20,31,$+4
    1330:	mflr	r3
    134	ld	r3,(1f-0b)(r3)		/* get &rtas_restore_regs */
    135
    136	ld	r1,PACAR1(r13)		/* Restore our SP */
    137	ld	r4,PACASAVEDMSR(r13)	/* Restore our MSR */
    138
    139	mtspr	SPRN_SRR0,r3
    140	mtspr	SPRN_SRR1,r4
    141	RFI_TO_KERNEL
    142	b	.	/* prevent speculative execution */
    143_ASM_NOKPROBE_SYMBOL(enter_rtas)
    144_ASM_NOKPROBE_SYMBOL(__enter_rtas)
    145_ASM_NOKPROBE_SYMBOL(rtas_return_loc)
    146
    147	.align	3
    1481:	.8byte	rtas_restore_regs
    149
    150rtas_restore_regs:
    151	/* relocation is on at this point */
    152	REST_GPR(2, r1)			/* Restore the TOC */
    153	REST_NVGPRS(r1)			/* Restore the non-volatiles */
    154
    155	ld	r4,_CCR(r1)
    156	mtcr	r4
    157	ld	r5,_CTR(r1)
    158	mtctr	r5
    159	ld	r6,_XER(r1)
    160	mtspr	SPRN_XER,r6
    161	ld	r7,_DAR(r1)
    162	mtdar	r7
    163	ld	r8,_DSISR(r1)
    164	mtdsisr	r8
    165
    166	addi	r1,r1,SWITCH_FRAME_SIZE	/* Unstack our frame */
    167	ld	r0,16(r1)		/* get return address */
    168
    169	mtlr	r0
    170	blr				/* return to caller */
    171
    172#endif /* CONFIG_PPC32 */