Skip to content

Commit

Permalink
riscv: libstub: Implement KASLR by using generic functions
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Alexandre Ghiti authored and Palmer Dabbelt committed Sep 6, 2023
1 parent 3c35d1a commit b7ac4b8
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 19 deletions.
2 changes: 2 additions & 0 deletions arch/riscv/include/asm/efi.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,6 @@ void efi_virtmap_unload(void);

unsigned long stext_offset(void);

void efi_icache_sync(unsigned long start, unsigned long end);

#endif /* _ASM_EFI_H */
1 change: 1 addition & 0 deletions arch/riscv/kernel/image-vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ __efistub__start = _start;
__efistub__start_kernel = _start_kernel;
__efistub__end = _end;
__efistub__edata = _edata;
__efistub___init_text_end = __init_text_end;
__efistub_screen_info = screen_info;

#endif
Expand Down
2 changes: 1 addition & 1 deletion drivers/firmware/efi/libstub/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB) += efi-stub.o string.o intrinsics.o systable.o \
lib-$(CONFIG_ARM) += arm32-stub.o
lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o
lib-$(CONFIG_X86) += x86-stub.o
lib-$(CONFIG_RISCV) += riscv.o riscv-stub.o
lib-$(CONFIG_RISCV) += kaslr.o riscv.o riscv-stub.o
lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o

CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
Expand Down
33 changes: 15 additions & 18 deletions drivers/firmware/efi/libstub/riscv-stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,29 @@ efi_status_t handle_kernel_image(unsigned long *image_addr,
efi_loaded_image_t *image,
efi_handle_t image_handle)
{
unsigned long kernel_size = 0;
unsigned long preferred_addr;
unsigned long kernel_size, kernel_codesize, kernel_memsize;
efi_status_t status;

kernel_size = _edata - _start;
kernel_codesize = __init_text_end - _start;
kernel_memsize = kernel_size + (_end - _edata);
*image_addr = (unsigned long)_start;
*image_size = kernel_size + (_end - _edata);

/*
* RISC-V kernel maps PAGE_OFFSET virtual address to the same physical
* address where kernel is booted. That's why kernel should boot from
* as low as possible to avoid wastage of memory. Currently, dram_base
* is occupied by the firmware. So the preferred address for kernel to
* boot is next aligned address. If preferred address is not available,
* relocate_kernel will fall back to efi_low_alloc_above to allocate
* lowest possible memory region as long as the address and size meets
* the alignment constraints.
*/
preferred_addr = EFI_KIMG_PREFERRED_ADDRESS;
status = efi_relocate_kernel(image_addr, kernel_size, *image_size,
preferred_addr, efi_get_kimg_min_align(),
0x0);
*image_size = kernel_memsize;
*reserve_size = *image_size;

status = efi_kaslr_relocate_kernel(image_addr,
reserve_addr, reserve_size,
kernel_size, kernel_codesize, kernel_memsize,
efi_kaslr_get_phys_seed(image_handle));
if (status != EFI_SUCCESS) {
efi_err("Failed to relocate kernel\n");
*image_size = 0;
}

return status;
}

void efi_icache_sync(unsigned long start, unsigned long end)
{
asm volatile ("fence.i" ::: "memory");
}

0 comments on commit b7ac4b8

Please sign in to comment.