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

kexec_relocate.S (4488B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Copyright (C) 2019 FORTH-ICS/CARV
      4 *  Nick Kossifidis <mick@ics.forth.gr>
      5 */
      6
      7#include <asm/asm.h>	/* For RISCV_* and REG_* macros */
      8#include <asm/csr.h>	/* For CSR_* macros */
      9#include <asm/page.h>	/* For PAGE_SIZE */
     10#include <linux/linkage.h> /* For SYM_* macros */
     11
     12.section ".rodata"
     13SYM_CODE_START(riscv_kexec_relocate)
     14
     15	/*
     16	 * s0: Pointer to the current entry
     17	 * s1: (const) Phys address to jump to after relocation
     18	 * s2: (const) Phys address of the FDT image
     19	 * s3: (const) The hartid of the current hart
     20	 * s4: Pointer to the destination address for the relocation
     21	 * s5: (const) Number of words per page
     22	 * s6: (const) 1, used for subtraction
     23	 * s7: (const) kernel_map.va_pa_offset, used when switching MMU off
     24	 * s8: (const) Physical address of the main loop
     25	 * s9: (debug) indirection page counter
     26	 * s10: (debug) entry counter
     27	 * s11: (debug) copied words counter
     28	 */
     29	mv	s0, a0
     30	mv	s1, a1
     31	mv	s2, a2
     32	mv	s3, a3
     33	mv	s4, zero
     34	li	s5, (PAGE_SIZE / RISCV_SZPTR)
     35	li	s6, 1
     36	mv	s7, a4
     37	mv	s8, zero
     38	mv	s9, zero
     39	mv	s10, zero
     40	mv	s11, zero
     41
     42	/* Disable / cleanup interrupts */
     43	csrw	CSR_SIE, zero
     44	csrw	CSR_SIP, zero
     45
     46	/*
     47	 * When we switch SATP.MODE to "Bare" we'll only
     48	 * play with physical addresses. However the first time
     49	 * we try to jump somewhere, the offset on the jump
     50	 * will be relative to pc which will still be on VA. To
     51	 * deal with this we set stvec to the physical address at
     52	 * the start of the loop below so that we jump there in
     53	 * any case.
     54	 */
     55	la	s8, 1f
     56	sub	s8, s8, s7
     57	csrw	CSR_STVEC, s8
     58
     59	/* Process entries in a loop */
     60.align 2
     611:
     62	addi	s10, s10, 1
     63	REG_L	t0, 0(s0)		/* t0 = *image->entry */
     64	addi	s0, s0, RISCV_SZPTR	/* image->entry++ */
     65
     66	/* IND_DESTINATION entry ? -> save destination address */
     67	andi	t1, t0, 0x1
     68	beqz	t1, 2f
     69	andi	s4, t0, ~0x1
     70	j	1b
     71
     722:
     73	/* IND_INDIRECTION entry ? -> update next entry ptr (PA) */
     74	andi	t1, t0, 0x2
     75	beqz	t1, 2f
     76	andi	s0, t0, ~0x2
     77	addi	s9, s9, 1
     78	csrw	CSR_SATP, zero
     79	jalr	zero, s8, 0
     80
     812:
     82	/* IND_DONE entry ? -> jump to done label */
     83	andi	t1, t0, 0x4
     84	beqz	t1, 2f
     85	j	4f
     86
     872:
     88	/*
     89	 * IND_SOURCE entry ? -> copy page word by word to the
     90	 * destination address we got from IND_DESTINATION
     91	 */
     92	andi	t1, t0, 0x8
     93	beqz	t1, 1b		/* Unknown entry type, ignore it */
     94	andi	t0, t0, ~0x8
     95	mv	t3, s5		/* i = num words per page */
     963:	/* copy loop */
     97	REG_L	t1, (t0)	/* t1 = *src_ptr */
     98	REG_S	t1, (s4)	/* *dst_ptr = *src_ptr */
     99	addi	t0, t0, RISCV_SZPTR /* stc_ptr++ */
    100	addi	s4, s4, RISCV_SZPTR /* dst_ptr++ */
    101	sub	t3, t3, s6	/* i-- */
    102	addi	s11, s11, 1	/* c++ */
    103	beqz	t3, 1b		/* copy done ? */
    104	j	3b
    105
    1064:
    107	/* Pass the arguments to the next kernel  / Cleanup*/
    108	mv	a0, s3
    109	mv	a1, s2
    110	mv	a2, s1
    111
    112	/* Cleanup */
    113	mv	a3, zero
    114	mv	a4, zero
    115	mv	a5, zero
    116	mv	a6, zero
    117	mv	a7, zero
    118
    119	mv	s0, zero
    120	mv	s1, zero
    121	mv	s2, zero
    122	mv	s3, zero
    123	mv	s4, zero
    124	mv	s5, zero
    125	mv	s6, zero
    126	mv	s7, zero
    127	mv	s8, zero
    128	mv	s9, zero
    129	mv	s10, zero
    130	mv	s11, zero
    131
    132	mv	t0, zero
    133	mv	t1, zero
    134	mv	t2, zero
    135	mv	t3, zero
    136	mv	t4, zero
    137	mv	t5, zero
    138	mv	t6, zero
    139	csrw	CSR_SEPC, zero
    140	csrw	CSR_SCAUSE, zero
    141	csrw	CSR_SSCRATCH, zero
    142
    143	/*
    144	 * Make sure the relocated code is visible
    145	 * and jump to the new kernel
    146	 */
    147	fence.i
    148
    149	jalr	zero, a2, 0
    150
    151SYM_CODE_END(riscv_kexec_relocate)
    152riscv_kexec_relocate_end:
    153
    154
    155/* Used for jumping to crashkernel */
    156.section ".text"
    157SYM_CODE_START(riscv_kexec_norelocate)
    158	/*
    159	 * s0: (const) Phys address to jump to
    160	 * s1: (const) Phys address of the FDT image
    161	 * s2: (const) The hartid of the current hart
    162	 */
    163	mv	s0, a1
    164	mv	s1, a2
    165	mv	s2, a3
    166
    167	/* Disable / cleanup interrupts */
    168	csrw	CSR_SIE, zero
    169	csrw	CSR_SIP, zero
    170
    171	/* Pass the arguments to the next kernel  / Cleanup*/
    172	mv	a0, s2
    173	mv	a1, s1
    174	mv	a2, s0
    175
    176	/* Cleanup */
    177	mv	a3, zero
    178	mv	a4, zero
    179	mv	a5, zero
    180	mv	a6, zero
    181	mv	a7, zero
    182
    183	mv	s0, zero
    184	mv	s1, zero
    185	mv	s2, zero
    186	mv	s3, zero
    187	mv	s4, zero
    188	mv	s5, zero
    189	mv	s6, zero
    190	mv	s7, zero
    191	mv	s8, zero
    192	mv	s9, zero
    193	mv	s10, zero
    194	mv	s11, zero
    195
    196	mv	t0, zero
    197	mv	t1, zero
    198	mv	t2, zero
    199	mv	t3, zero
    200	mv	t4, zero
    201	mv	t5, zero
    202	mv	t6, zero
    203	csrw	CSR_SEPC, zero
    204	csrw	CSR_SCAUSE, zero
    205	csrw	CSR_SSCRATCH, zero
    206
    207	/*
    208	 * Switch to physical addressing
    209	 * This will also trigger a jump to CSR_STVEC
    210	 * which in this case is the address of the new
    211	 * kernel.
    212	 */
    213	csrw	CSR_STVEC, a2
    214	csrw	CSR_SATP, zero
    215
    216SYM_CODE_END(riscv_kexec_norelocate)
    217
    218.section ".rodata"
    219SYM_DATA(riscv_kexec_relocate_size,
    220	.long riscv_kexec_relocate_end - riscv_kexec_relocate)
    221