diff mbox series

[5/6] riscv: Support CONFIG_RELOCATABLE on riscv32

Message ID 20241026171441.3047904-6-samuel.holland@sifive.com (mailing list archive)
State New
Headers show
Series riscv: Relocatable NOMMU kernels | expand

Checks

Context Check Description
conchuod/vmtest-for-next-PR success PR summary
conchuod/patch-5-test-1 success .github/scripts/patches/tests/build_rv32_defconfig.sh took 142.54s
conchuod/patch-5-test-2 success .github/scripts/patches/tests/build_rv64_clang_allmodconfig.sh took 1353.23s
conchuod/patch-5-test-3 success .github/scripts/patches/tests/build_rv64_gcc_allmodconfig.sh took 1579.08s
conchuod/patch-5-test-4 success .github/scripts/patches/tests/build_rv64_nommu_k210_defconfig.sh took 21.05s
conchuod/patch-5-test-5 success .github/scripts/patches/tests/build_rv64_nommu_virt_defconfig.sh took 23.18s
conchuod/patch-5-test-6 warning .github/scripts/patches/tests/checkpatch.sh took 4.33s
conchuod/patch-5-test-7 success .github/scripts/patches/tests/dtb_warn_rv64.sh took 43.08s
conchuod/patch-5-test-8 success .github/scripts/patches/tests/header_inline.sh took 0.00s
conchuod/patch-5-test-9 success .github/scripts/patches/tests/kdoc.sh took 0.49s
conchuod/patch-5-test-10 success .github/scripts/patches/tests/module_param.sh took 0.01s
conchuod/patch-5-test-11 success .github/scripts/patches/tests/verify_fixes.sh took 0.00s
conchuod/patch-5-test-12 success .github/scripts/patches/tests/verify_signedoff.sh took 0.03s

Commit Message

Samuel Holland Oct. 26, 2024, 5:13 p.m. UTC
When adjusted to use the correctly-sized ELF types, relocate_kernel()
works on riscv32 as well. The caveat about crossing an intermediate page
table boundary does not apply to riscv32, since for Sv32 the early
kernel mapping uses only PGD entries. Since KASLR is not yet supported
on riscv32, this option is mostly useful for NOMMU.

Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
---

 arch/riscv/Kconfig   |  2 +-
 arch/riscv/mm/init.c | 17 ++++++++---------
 2 files changed, 9 insertions(+), 10 deletions(-)
diff mbox series

Patch

diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 4420419e7054..33aa79d84021 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -934,7 +934,7 @@  config PARAVIRT_TIME_ACCOUNTING
 
 config RELOCATABLE
 	bool "Build a relocatable kernel"
-	depends on 64BIT && !XIP_KERNEL
+	depends on !XIP_KERNEL
 	select MODULE_SECTIONS if MODULES
 	help
           This builds a kernel as a Position Independent Executable (PIE),
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index a74e28367f9f..0aad925848a4 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -20,15 +20,13 @@ 
 #include <linux/dma-map-ops.h>
 #include <linux/crash_dump.h>
 #include <linux/hugetlb.h>
-#ifdef CONFIG_RELOCATABLE
-#include <linux/elf.h>
-#endif
 #include <linux/kfence.h>
 #include <linux/execmem.h>
 
 #include <asm/fixmap.h>
 #include <asm/io.h>
 #include <asm/kasan.h>
+#include <asm/module.h>
 #include <asm/numa.h>
 #include <asm/pgtable.h>
 #include <asm/sections.h>
@@ -312,7 +310,7 @@  extern unsigned long __rela_dyn_start, __rela_dyn_end;
 
 static void __init relocate_kernel(void)
 {
-	Elf64_Rela *rela = (Elf64_Rela *)&__rela_dyn_start;
+	Elf_Rela *rela = (Elf_Rela *)&__rela_dyn_start;
 	/*
 	 * This holds the offset between the linked virtual address and the
 	 * relocated virtual address.
@@ -324,9 +322,9 @@  static void __init relocate_kernel(void)
 	 */
 	uintptr_t va_kernel_link_pa_offset = KERNEL_LINK_ADDR - kernel_map.phys_addr;
 
-	for ( ; rela < (Elf64_Rela *)&__rela_dyn_end; rela++) {
-		Elf64_Addr addr = (rela->r_offset - va_kernel_link_pa_offset);
-		Elf64_Addr relocated_addr = rela->r_addend;
+	for ( ; rela < (Elf_Rela *)&__rela_dyn_end; rela++) {
+		Elf_Addr addr = (rela->r_offset - va_kernel_link_pa_offset);
+		Elf_Addr relocated_addr = rela->r_addend;
 
 		if (rela->r_info != R_RISCV_RELATIVE)
 			continue;
@@ -340,7 +338,7 @@  static void __init relocate_kernel(void)
 		if (relocated_addr >= KERNEL_LINK_ADDR)
 			relocated_addr += reloc_offset;
 
-		*(Elf64_Addr *)addr = relocated_addr;
+		*(Elf_Addr *)addr = relocated_addr;
 	}
 }
 #endif /* CONFIG_RELOCATABLE */
@@ -1155,7 +1153,8 @@  asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 	 * makes the kernel cross over a PUD_SIZE boundary, raise a bug
 	 * since a part of the kernel would not get mapped.
 	 */
-	BUG_ON(PUD_SIZE - (kernel_map.virt_addr & (PUD_SIZE - 1)) < kernel_map.size);
+	if (IS_ENABLED(CONFIG_64BIT))
+		BUG_ON(PUD_SIZE - (kernel_map.virt_addr & (PUD_SIZE - 1)) < kernel_map.size);
 	relocate_kernel();
 #endif