* [PATCH v5 1/3] efi/loongarch: Randomize kernel preferred address for KASLR
2026-05-11 10:45 [PATCH v5 0/3] LoongArch: Move KASLR to EFI stub to avoid initrd overlap WANG Rui
@ 2026-05-11 10:45 ` WANG Rui
2026-05-11 10:45 ` [PATCH v5 2/3] LoongArch: Skip relocation-time KASLR if already applied WANG Rui
2026-05-11 10:45 ` [PATCH v5 3/3] LoongArch: Avoid initrd overlap during kernel relocation WANG Rui
2 siblings, 0 replies; 4+ messages in thread
From: WANG Rui @ 2026-05-11 10:45 UTC (permalink / raw)
To: Huacai Chen, Ard Biesheuvel
Cc: WANG Xuerui, Ilias Apalodimas, Haiyong Sun, Lisa Robinson,
loongarch, linux-efi, linux-kernel, WANG Rui, Huacai Chen
Introduce efi_get_kimg_kaslr_address() helper to compute the preferred
kernel image load address dynamically when CONFIG_RANDOMIZE_BASE is
enabled. The function derives a random offset by using the EFI-provided
randomness combined with the timer tick value, and constrains it within
CONFIG_RANDOMIZE_BASE_MAX_OFFSET.
Update EFI_KIMG_PREFERRED_ADDRESS to call this helper so that the EFI
stub can select a randomized load address when KASLR is active, while
preserving the original base address behavior when KASLR is disabled or
"nokaslr" is specified.
Note: LoongArch can't KASLR for hibernation, so set efi_nokaslr to true
if "resume=<devname>" is explicitly specified in cmdline.
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Co-authored-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: WANG Rui <r@hev.cc>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
arch/loongarch/include/asm/efi.h | 4 +++-
drivers/firmware/efi/libstub/efi-stub-helper.c | 4 ++++
drivers/firmware/efi/libstub/loongarch.c | 16 ++++++++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/arch/loongarch/include/asm/efi.h b/arch/loongarch/include/asm/efi.h
index eddc8e79b3fa..1ad764b18c3e 100644
--- a/arch/loongarch/include/asm/efi.h
+++ b/arch/loongarch/include/asm/efi.h
@@ -30,6 +30,8 @@ static inline unsigned long efi_get_kimg_min_align(void)
return SZ_2M;
}
-#define EFI_KIMG_PREFERRED_ADDRESS PHYSADDR(VMLINUX_LOAD_ADDRESS)
+unsigned long efi_get_kimg_kaslr_address(void);
+
+#define EFI_KIMG_PREFERRED_ADDRESS efi_get_kimg_kaslr_address()
#endif /* _ASM_LOONGARCH_EFI_H */
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 7aa2f9ad2935..f27f2e1f0019 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -79,6 +79,10 @@ efi_status_t efi_parse_options(char const *cmdline)
efi_noinitrd = true;
} else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
efi_no5lvl = true;
+ } else if (IS_ENABLED(CONFIG_LOONGARCH) &&
+ IS_ENABLED(CONFIG_HIBERNATION) &&
+ !strcmp(param, "resume") && val) {
+ efi_nokaslr = true; /* LoongArch can't KASLR for hibernation */
} else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
!strcmp(param, "mem_encrypt") && val) {
if (parse_option_str(val, "on"))
diff --git a/drivers/firmware/efi/libstub/loongarch.c b/drivers/firmware/efi/libstub/loongarch.c
index f7938d5c196a..2b0c87dc9908 100644
--- a/drivers/firmware/efi/libstub/loongarch.c
+++ b/drivers/firmware/efi/libstub/loongarch.c
@@ -23,6 +23,22 @@ void efi_cache_sync_image(unsigned long image_base, unsigned long alloc_size)
asm volatile ("ibar 0" ::: "memory");
}
+unsigned long efi_get_kimg_kaslr_address(void)
+{
+ unsigned int random_offset = 0;
+
+#ifdef CONFIG_RANDOMIZE_BASE
+ if (!efi_nokaslr) {
+ efi_get_random_bytes(sizeof(random_offset), (u8 *)&random_offset);
+ random_offset ^= (random_get_entropy() << 16);
+ random_offset &= (CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1);
+ random_offset = ALIGN(random_offset + SZ_64K, SZ_64K);
+ }
+#endif
+
+ return PHYSADDR(VMLINUX_LOAD_ADDRESS) + random_offset;
+}
+
struct exit_boot_struct {
efi_memory_desc_t *runtime_map;
int runtime_entry_count;
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v5 2/3] LoongArch: Skip relocation-time KASLR if already applied
2026-05-11 10:45 [PATCH v5 0/3] LoongArch: Move KASLR to EFI stub to avoid initrd overlap WANG Rui
2026-05-11 10:45 ` [PATCH v5 1/3] efi/loongarch: Randomize kernel preferred address for KASLR WANG Rui
@ 2026-05-11 10:45 ` WANG Rui
2026-05-11 10:45 ` [PATCH v5 3/3] LoongArch: Avoid initrd overlap during kernel relocation WANG Rui
2 siblings, 0 replies; 4+ messages in thread
From: WANG Rui @ 2026-05-11 10:45 UTC (permalink / raw)
To: Huacai Chen, Ard Biesheuvel
Cc: WANG Xuerui, Ilias Apalodimas, Haiyong Sun, Lisa Robinson,
loongarch, linux-efi, linux-kernel, WANG Rui, Huacai Chen
When the kernel is relocated during early boot (efistub or kexec_file),
a randomized load address may has already been selected and applied. In
this case, performing KASLR again in relocate.c is unnecessary.
Note: strictly-defined KASLR means the kernel's final runtime address
has a random offset from the kernel's load address, which is implemented
in relocate.c; broadly-defined KALSR means the kernel's final runtime
address has a random offset from the kernel's link address (a.k.a.
VMLINUX_LOAD_ADDRESS), which also include the efistlub implementation,
kexec_file implementation and QEMU direct kernel boot. kaslr_disabled()
return true only means strictly-defined KASLR is disabled.
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Co-authored-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: WANG Rui <r@hev.cc>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
arch/loongarch/kernel/relocate.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
index 16f6a9b39659..0a045964fad5 100644
--- a/arch/loongarch/kernel/relocate.c
+++ b/arch/loongarch/kernel/relocate.c
@@ -134,11 +134,23 @@ early_param("nokaslr", nokaslr);
#define KASLR_DISABLED_MESSAGE "KASLR is disabled by %s in %s cmdline.\n"
+/*
+ * Note: strictly-defined KASLR means the kernel's final runtime address
+ * has a random offset from the kernel's load address, which is implemented
+ * in relocate.c; broadly-defined KALSR means the kernel's final runtime
+ * address has a random offset from the kernel's link address (a.k.a.
+ * VMLINUX_LOAD_ADDRESS), which also include the efistlub implementation,
+ * kexec_file implementation and QEMU direct kernel boot. kaslr_disabled()
+ * return true only means strictly-defined KASLR is disabled.
+ */
static inline __init bool kaslr_disabled(void)
{
char *str;
const char *builtin_cmdline = CONFIG_CMDLINE;
+ if (kaslr_offset())
+ return true; /* KASLR is performed during early boot. */
+
str = strstr(builtin_cmdline, "nokaslr");
if (str == builtin_cmdline || (str > builtin_cmdline && *(str - 1) == ' ')) {
pr_info(KASLR_DISABLED_MESSAGE, "\'nokaslr\'", "built-in");
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v5 3/3] LoongArch: Avoid initrd overlap during kernel relocation
2026-05-11 10:45 [PATCH v5 0/3] LoongArch: Move KASLR to EFI stub to avoid initrd overlap WANG Rui
2026-05-11 10:45 ` [PATCH v5 1/3] efi/loongarch: Randomize kernel preferred address for KASLR WANG Rui
2026-05-11 10:45 ` [PATCH v5 2/3] LoongArch: Skip relocation-time KASLR if already applied WANG Rui
@ 2026-05-11 10:45 ` WANG Rui
2 siblings, 0 replies; 4+ messages in thread
From: WANG Rui @ 2026-05-11 10:45 UTC (permalink / raw)
To: Huacai Chen, Ard Biesheuvel
Cc: WANG Xuerui, Ilias Apalodimas, Haiyong Sun, Lisa Robinson,
loongarch, linux-efi, linux-kernel, WANG Rui, Huacai Chen
Validate the relocation address against the initrd region specified via
"initrd=" or "initrdmem=" on the command line. Reject relocation targets
that overlap the initrd to prevent memory corruption during early boot.
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Co-authored-by: Huacai Chen <chenhuacai@loongson.cn>
Signed-off-by: WANG Rui <r@hev.cc>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
---
arch/loongarch/kernel/relocate.c | 38 ++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/arch/loongarch/kernel/relocate.c b/arch/loongarch/kernel/relocate.c
index 0a045964fad5..4b61a9632a98 100644
--- a/arch/loongarch/kernel/relocate.c
+++ b/arch/loongarch/kernel/relocate.c
@@ -222,14 +222,52 @@ static inline void __init *determine_relocation_address(void)
return RELOCATED_KASLR(destination);
}
+static unsigned long __init determine_initrd_address(unsigned long *size)
+{
+ unsigned long start = 0;
+ unsigned long key_length;
+ char *p, *endp, *key = "initrd=";
+
+ key_length = strlen(key);
+ p = strstr(boot_command_line, key);
+
+ if (!p) {
+ key = "initrdmem=";
+ key_length = strlen(key);
+ p = strstr(boot_command_line, key);
+ }
+
+ if (p == boot_command_line || (p > boot_command_line && *(p - 1) == ' ')) {
+ p += key_length;
+ start = memparse(p, &endp);
+ if (*endp == ',')
+ *size = memparse(endp + 1, NULL);
+ }
+
+ return start;
+}
+
static inline int __init relocation_addr_valid(void *location_new)
{
+ unsigned long kernel_start, kernel_size;
+ unsigned long initrd_start, initrd_size = 0;
+
if ((unsigned long)location_new & 0x00000ffff)
return 0; /* Inappropriately aligned new location */
if ((unsigned long)location_new < (unsigned long)_end)
return 0; /* New location overlaps original kernel */
+ initrd_start = determine_initrd_address(&initrd_size);
+ if (initrd_start && initrd_size) {
+ kernel_start = PHYSADDR(location_new);
+ kernel_size = (unsigned long)_end - (unsigned long)_text;
+
+ if (kernel_start < (initrd_start + initrd_size) &&
+ initrd_start < (kernel_start + kernel_size))
+ return 0; /* initrd/initramfs overlaps kernel */
+ }
+
return 1;
}
#endif
--
2.54.0
^ permalink raw reply related [flat|nested] 4+ messages in thread