Skip to content

Commit ea2bde3

Browse files
SiFiveHollandpalmer-dabbelt
authored andcommitted
riscv: Support CONFIG_RELOCATABLE on riscv32
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> Link: https://lore.kernel.org/r/20241026171441.3047904-6-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent d073a57 commit ea2bde3

File tree

2 files changed

+9
-10
lines changed

2 files changed

+9
-10
lines changed

arch/riscv/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1075,7 +1075,7 @@ config PARAVIRT_TIME_ACCOUNTING
10751075

10761076
config RELOCATABLE
10771077
bool "Build a relocatable kernel"
1078-
depends on 64BIT && !XIP_KERNEL
1078+
depends on !XIP_KERNEL
10791079
select MODULE_SECTIONS if MODULES
10801080
help
10811081
This builds a kernel as a Position Independent Executable (PIE),

arch/riscv/mm/init.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,13 @@
2020
#include <linux/dma-map-ops.h>
2121
#include <linux/crash_dump.h>
2222
#include <linux/hugetlb.h>
23-
#ifdef CONFIG_RELOCATABLE
24-
#include <linux/elf.h>
25-
#endif
2623
#include <linux/kfence.h>
2724
#include <linux/execmem.h>
2825

2926
#include <asm/fixmap.h>
3027
#include <asm/io.h>
3128
#include <asm/kasan.h>
29+
#include <asm/module.h>
3230
#include <asm/numa.h>
3331
#include <asm/pgtable.h>
3432
#include <asm/sections.h>
@@ -328,7 +326,7 @@ extern unsigned long __rela_dyn_start, __rela_dyn_end;
328326

329327
static void __init relocate_kernel(void)
330328
{
331-
Elf64_Rela *rela = (Elf64_Rela *)&__rela_dyn_start;
329+
Elf_Rela *rela = (Elf_Rela *)&__rela_dyn_start;
332330
/*
333331
* This holds the offset between the linked virtual address and the
334332
* relocated virtual address.
@@ -340,9 +338,9 @@ static void __init relocate_kernel(void)
340338
*/
341339
uintptr_t va_kernel_link_pa_offset = KERNEL_LINK_ADDR - kernel_map.phys_addr;
342340

343-
for ( ; rela < (Elf64_Rela *)&__rela_dyn_end; rela++) {
344-
Elf64_Addr addr = (rela->r_offset - va_kernel_link_pa_offset);
345-
Elf64_Addr relocated_addr = rela->r_addend;
341+
for ( ; rela < (Elf_Rela *)&__rela_dyn_end; rela++) {
342+
Elf_Addr addr = (rela->r_offset - va_kernel_link_pa_offset);
343+
Elf_Addr relocated_addr = rela->r_addend;
346344

347345
if (rela->r_info != R_RISCV_RELATIVE)
348346
continue;
@@ -356,7 +354,7 @@ static void __init relocate_kernel(void)
356354
if (relocated_addr >= KERNEL_LINK_ADDR)
357355
relocated_addr += reloc_offset;
358356

359-
*(Elf64_Addr *)addr = relocated_addr;
357+
*(Elf_Addr *)addr = relocated_addr;
360358
}
361359
}
362360
#endif /* CONFIG_RELOCATABLE */
@@ -1174,7 +1172,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
11741172
* makes the kernel cross over a PUD_SIZE boundary, raise a bug
11751173
* since a part of the kernel would not get mapped.
11761174
*/
1177-
BUG_ON(PUD_SIZE - (kernel_map.virt_addr & (PUD_SIZE - 1)) < kernel_map.size);
1175+
if (IS_ENABLED(CONFIG_64BIT))
1176+
BUG_ON(PUD_SIZE - (kernel_map.virt_addr & (PUD_SIZE - 1)) < kernel_map.size);
11781177
relocate_kernel();
11791178
#endif
11801179

0 commit comments

Comments
 (0)