Skip to content

Commit b7ac4b8

Browse files
Alexandre Ghitipalmer-dabbelt
authored andcommitted
riscv: libstub: Implement KASLR by using generic functions
We can now use arm64 functions to handle the move of the kernel physical mapping: if KASLR is enabled, we will try to get a random seed from the firmware, if not possible, the kernel will be moved to a location that suits its alignment constraints. Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com> Tested-by: Conor Dooley <conor.dooley@microchip.com> Tested-by: Song Shuai <songshuaishuai@tinylab.org> Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Tested-by: Sami Tolvanen <samitolvanen@google.com> Link: https://lore.kernel.org/r/20230722123850.634544-6-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent 3c35d1a commit b7ac4b8

File tree

4 files changed

+19
-19
lines changed

4 files changed

+19
-19
lines changed

arch/riscv/include/asm/efi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,6 @@ void efi_virtmap_unload(void);
5151

5252
unsigned long stext_offset(void);
5353

54+
void efi_icache_sync(unsigned long start, unsigned long end);
55+
5456
#endif /* _ASM_EFI_H */

arch/riscv/kernel/image-vars.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ __efistub__start = _start;
2727
__efistub__start_kernel = _start_kernel;
2828
__efistub__end = _end;
2929
__efistub__edata = _edata;
30+
__efistub___init_text_end = __init_text_end;
3031
__efistub_screen_info = screen_info;
3132

3233
#endif

drivers/firmware/efi/libstub/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \
8888
lib-$(CONFIG_ARM) += arm32-stub.o
8989
lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o
9090
lib-$(CONFIG_X86) += x86-stub.o
91-
lib-$(CONFIG_RISCV) += riscv.o riscv-stub.o
91+
lib-$(CONFIG_RISCV) += kaslr.o riscv.o riscv-stub.o
9292
lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o
9393

9494
CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)

drivers/firmware/efi/libstub/riscv-stub.c

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,29 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
3030
efi_loaded_image_t *image,
3131
efi_handle_t image_handle)
3232
{
33-
unsigned long kernel_size = 0;
34-
unsigned long preferred_addr;
33+
unsigned long kernel_size, kernel_codesize, kernel_memsize;
3534
efi_status_t status;
3635

3736
kernel_size = _edata - _start;
37+
kernel_codesize = __init_text_end - _start;
38+
kernel_memsize = kernel_size + (_end - _edata);
3839
*image_addr = (unsigned long)_start;
39-
*image_size = kernel_size + (_end - _edata);
40-
41-
/*
42-
* RISC-V kernel maps PAGE_OFFSET virtual address to the same physical
43-
* address where kernel is booted. That's why kernel should boot from
44-
* as low as possible to avoid wastage of memory. Currently, dram_base
45-
* is occupied by the firmware. So the preferred address for kernel to
46-
* boot is next aligned address. If preferred address is not available,
47-
* relocate_kernel will fall back to efi_low_alloc_above to allocate
48-
* lowest possible memory region as long as the address and size meets
49-
* the alignment constraints.
50-
*/
51-
preferred_addr = EFI_KIMG_PREFERRED_ADDRESS;
52-
status = efi_relocate_kernel(image_addr, kernel_size, *image_size,
53-
preferred_addr, efi_get_kimg_min_align(),
54-
0x0);
40+
*image_size = kernel_memsize;
41+
*reserve_size = *image_size;
5542

43+
status = efi_kaslr_relocate_kernel(image_addr,
44+
reserve_addr, reserve_size,
45+
kernel_size, kernel_codesize, kernel_memsize,
46+
efi_kaslr_get_phys_seed(image_handle));
5647
if (status != EFI_SUCCESS) {
5748
efi_err("Failed to relocate kernel\n");
5849
*image_size = 0;
5950
}
51+
6052
return status;
6153
}
54+
55+
void efi_icache_sync(unsigned long start, unsigned long end)
56+
{
57+
asm volatile ("fence.i" ::: "memory");
58+
}

0 commit comments

Comments
 (0)