]> xenbits.xensource.com Git - people/aperard/linux.git/commitdiff
x86/decompressor: Move global symbol references to C code
authorArd Biesheuvel <ardb@kernel.org>
Mon, 7 Aug 2023 16:27:16 +0000 (18:27 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 6 Mar 2024 14:45:14 +0000 (14:45 +0000)
commit 24388292e2d7fae79a0d4183cc91716b851299cf upstream.

It is no longer necessary to be cautious when referring to global
variables in the position independent decompressor code, now that it is
built using PIE codegen and makes an assertion in the linker script that
no GOT entries exist (which would require adjustment for the actual
runtime load address of the decompressor binary).

This means global variables can be referenced directly from C code,
instead of having to pass their runtime addresses into C routines from
asm code, which needs to happen at each call site. Do so for the code
that will be called directly from the EFI stub after a subsequent patch,
and avoid the need to duplicate this logic a third time.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230807162720.545787-20-ardb@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/boot/compressed/misc.c

index 987ae727cf9f0d041cf265f707861f14b52b955c..3ecc1bbe971e1d4352aa23985c1720513a6b26a1 100644 (file)
@@ -179,13 +179,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
  */
        /* push arguments for extract_kernel: */
 
-       pushl   output_len@GOTOFF(%ebx) /* decompressed length, end of relocs */
        pushl   %ebp                    /* output address */
-       pushl   input_len@GOTOFF(%ebx)  /* input_len */
-       leal    input_data@GOTOFF(%ebx), %eax
-       pushl   %eax                    /* input_data */
-       leal    boot_heap@GOTOFF(%ebx), %eax
-       pushl   %eax                    /* heap area */
        pushl   %esi                    /* real mode pointer */
        call    extract_kernel          /* returns kernel entry point in %eax */
        addl    $24, %esp
@@ -213,8 +207,6 @@ SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
  */
        .bss
        .balign 4
-boot_heap:
-       .fill BOOT_HEAP_SIZE, 1, 0
 boot_stack:
        .fill BOOT_STACK_SIZE, 1, 0
 boot_stack_end:
index 81458f77131b271469f42d1cce54307fd4dd2c3e..fafd0a59f3961524b9fcae200e51ef11de9b2a86 100644 (file)
@@ -511,13 +511,9 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
 /*
  * Do the extraction, and jump to the new kernel..
  */
-       /* pass struct boot_params pointer */
+       /* pass struct boot_params pointer and output target address */
        movq    %r15, %rdi
-       leaq    boot_heap(%rip), %rsi   /* malloc area for uncompression */
-       leaq    input_data(%rip), %rdx  /* input_data */
-       movl    input_len(%rip), %ecx   /* input_len */
-       movq    %rbp, %r8               /* output target address */
-       movl    output_len(%rip), %r9d  /* decompressed length, end of relocs */
+       movq    %rbp, %rsi
        call    extract_kernel          /* returns kernel entry point in %rax */
 
 /*
@@ -675,8 +671,6 @@ SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
  */
        .bss
        .balign 4
-SYM_DATA_LOCAL(boot_heap,      .fill BOOT_HEAP_SIZE, 1, 0)
-
 SYM_DATA_START_LOCAL(boot_stack)
        .fill BOOT_STACK_SIZE, 1, 0
        .balign 16
index 014ff222bf4b35c2031e71938b913e368b64495f..e4e3e49fcc374bf2a542fb2d710b9316bc1a16bd 100644 (file)
@@ -330,6 +330,11 @@ static size_t parse_elf(void *output)
        return ehdr.e_entry - LOAD_PHYSICAL_ADDR;
 }
 
+static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);
+
+extern unsigned char input_data[];
+extern unsigned int input_len, output_len;
+
 /*
  * The compressed kernel image (ZO), has been moved so that its position
  * is against the end of the buffer used to hold the uncompressed kernel
@@ -347,14 +352,11 @@ static size_t parse_elf(void *output)
  *             |-------uncompressed kernel image---------|
  *
  */
-asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
-                                 unsigned char *input_data,
-                                 unsigned long input_len,
-                                 unsigned char *output,
-                                 unsigned long output_len)
+asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
 {
        const unsigned long kernel_total_size = VO__end - VO__text;
        unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
+       memptr heap = (memptr)boot_heap;
        unsigned long needed_size;
        size_t entry_offset;
 
@@ -412,7 +414,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
         * entries. This ensures the full mapped area is usable RAM
         * and doesn't include any reserved areas.
         */
-       needed_size = max(output_len, kernel_total_size);
+       needed_size = max_t(unsigned long, output_len, kernel_total_size);
 #ifdef CONFIG_X86_64
        needed_size = ALIGN(needed_size, MIN_KERNEL_ALIGN);
 #endif
@@ -443,7 +445,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
 #ifdef CONFIG_X86_64
        if (heap > 0x3fffffffffffUL)
                error("Destination address too large");
-       if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE)
+       if (virt_addr + needed_size > KERNEL_IMAGE_SIZE)
                error("Destination virtual address is beyond the kernel mapping area");
 #else
        if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))