[RFC/RFT PATCH 05/19] x86/efistub: Simplify early remapping of kernel text

Ard Biesheuvel
2026-01-08T09:28:12Z

Now that the kernel's .text, .rodata and .inittext are all covered by a
single ELF segment, there is no need to remap .inittext separately.
Instead, remap the entire region in a single call.

This remapping is needed because the EFI stub hands over to the core
kernel while running in long mode, using the page tables provided by the
firmware. Recent so-called 'MS secured core' (tm) PCs are more strict
when it comes to separating writable from executable mappings, and so
for compatibility with such systems, any code that may be callable
during early boot (i.e., before the kernel switches to its own page
tables) must be remapped executable explicitly.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/boot/compressed/Makefile | 2 +-
arch/x86/boot/compressed/misc.c | 4 +---
arch/x86/include/asm/boot.h | 2 --
arch/x86/kernel/vmlinux.lds.S | 2 --
drivers/firmware/efi/libstub/x86-stub.c | 4 +---
5 files changed, 3 insertions(+), 11 deletions(-)

diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile
index 68f9d7a1683b..bc071bdcd11e 100644
--- a/arch/x86/boot/compressed/Makefile
+++ b/arch/x86/boot/compressed/Makefile
@@ -76,7 +76,7 @@ LDFLAGS_vmlinux += -T
hostprogs := mkpiggy
HOST_EXTRACFLAGS += -I$(srctree)/tools/include

-sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABbCDGRSTtVW] \(_text\|__start_rodata\|_sinittext\|__inittext_end\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'
+sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABbCDGRSTtVW] \(_text\|__data_segment_start\|__bss_start\|_end\)$$/\#define VO_\2 _AC(0x\1,UL)/p'

quiet_cmd_voffset = VOFFSET $@
cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c
index d37569e7ee10..1ea419cf88fe 100644
--- a/arch/x86/boot/compressed/misc.c
+++ b/arch/x86/boot/compressed/misc.c
@@ -329,9 +329,7 @@ static size_t parse_elf(void *output)
return ehdr.e_entry - LOAD_PHYSICAL_ADDR;
}

-const unsigned long kernel_text_size = VO___start_rodata - VO__text;
-const unsigned long kernel_inittext_offset = VO__sinittext - VO__text;
-const unsigned long kernel_inittext_size = VO___inittext_end - VO__sinittext;
+const unsigned long kernel_text_size = VO___data_segment_start - VO__text;
const unsigned long kernel_total_size = VO__end - VO__text;

static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);
diff --git a/arch/x86/include/asm/boot.h b/arch/x86/include/asm/boot.h
index f7b67cb73915..02b23aa78955 100644
--- a/arch/x86/include/asm/boot.h
+++ b/arch/x86/include/asm/boot.h
@@ -82,8 +82,6 @@
#ifndef __ASSEMBLER__
extern unsigned int output_len;
extern const unsigned long kernel_text_size;
-extern const unsigned long kernel_inittext_offset;
-extern const unsigned long kernel_inittext_size;
extern const unsigned long kernel_total_size;

unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 1dee2987c42b..6772fe9a9957 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -196,8 +196,6 @@ SECTIONS
*/
.altinstr_aux : AT(ADDR(.altinstr_aux) - LOAD_OFFSET) {
*(.altinstr_aux)
- . = ALIGN(PAGE_SIZE);
- __inittext_end = .;
}

DATA_SEGMENT_START
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c
index cef32e2c82d8..ffe30ef73fda 100644
--- a/drivers/firmware/efi/libstub/x86-stub.c
+++ b/drivers/firmware/efi/libstub/x86-stub.c
@@ -890,9 +890,7 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry,

*kernel_entry = addr + entry;

- return efi_adjust_memory_range_protection(addr, kernel_text_size) ?:
- efi_adjust_memory_range_protection(addr + kernel_inittext_offset,
- kernel_inittext_size);
+ return efi_adjust_memory_range_protection(addr, kernel_text_size);
}

static void __noreturn enter_kernel(unsigned long kernel_addr,
--
2.47.3