Skip to content

Commit 5c4fead

Browse files
ardbiesheuvelgregkh
authored andcommitted
x86/decompressor: Move global symbol references to C code
commit 2438829 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 <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 463b51e commit 5c4fead

File tree

3 files changed

+11
-23
lines changed

3 files changed

+11
-23
lines changed

arch/x86/boot/compressed/head_32.S

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,7 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
179179
*/
180180
/* push arguments for extract_kernel: */
181181

182-
pushl output_len@GOTOFF(%ebx) /* decompressed length, end of relocs */
183182
pushl %ebp /* output address */
184-
pushl input_len@GOTOFF(%ebx) /* input_len */
185-
leal input_data@GOTOFF(%ebx), %eax
186-
pushl %eax /* input_data */
187-
leal boot_heap@GOTOFF(%ebx), %eax
188-
pushl %eax /* heap area */
189183
pushl %esi /* real mode pointer */
190184
call extract_kernel /* returns kernel entry point in %eax */
191185
addl $24, %esp
@@ -213,8 +207,6 @@ SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
213207
*/
214208
.bss
215209
.balign 4
216-
boot_heap:
217-
.fill BOOT_HEAP_SIZE, 1, 0
218210
boot_stack:
219211
.fill BOOT_STACK_SIZE, 1, 0
220212
boot_stack_end:

arch/x86/boot/compressed/head_64.S

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -511,13 +511,9 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
511511
/*
512512
* Do the extraction, and jump to the new kernel..
513513
*/
514-
/* pass struct boot_params pointer */
514+
/* pass struct boot_params pointer and output target address */
515515
movq %r15, %rdi
516-
leaq boot_heap(%rip), %rsi /* malloc area for uncompression */
517-
leaq input_data(%rip), %rdx /* input_data */
518-
movl input_len(%rip), %ecx /* input_len */
519-
movq %rbp, %r8 /* output target address */
520-
movl output_len(%rip), %r9d /* decompressed length, end of relocs */
516+
movq %rbp, %rsi
521517
call extract_kernel /* returns kernel entry point in %rax */
522518

523519
/*
@@ -675,8 +671,6 @@ SYM_DATA_END_LABEL(boot_idt, SYM_L_GLOBAL, boot_idt_end)
675671
*/
676672
.bss
677673
.balign 4
678-
SYM_DATA_LOCAL(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0)
679-
680674
SYM_DATA_START_LOCAL(boot_stack)
681675
.fill BOOT_STACK_SIZE, 1, 0
682676
.balign 16

arch/x86/boot/compressed/misc.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,11 @@ static size_t parse_elf(void *output)
330330
return ehdr.e_entry - LOAD_PHYSICAL_ADDR;
331331
}
332332

333+
static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);
334+
335+
extern unsigned char input_data[];
336+
extern unsigned int input_len, output_len;
337+
333338
/*
334339
* The compressed kernel image (ZO), has been moved so that its position
335340
* is against the end of the buffer used to hold the uncompressed kernel
@@ -347,14 +352,11 @@ static size_t parse_elf(void *output)
347352
* |-------uncompressed kernel image---------|
348353
*
349354
*/
350-
asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
351-
unsigned char *input_data,
352-
unsigned long input_len,
353-
unsigned char *output,
354-
unsigned long output_len)
355+
asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
355356
{
356357
const unsigned long kernel_total_size = VO__end - VO__text;
357358
unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
359+
memptr heap = (memptr)boot_heap;
358360
unsigned long needed_size;
359361
size_t entry_offset;
360362

@@ -412,7 +414,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
412414
* entries. This ensures the full mapped area is usable RAM
413415
* and doesn't include any reserved areas.
414416
*/
415-
needed_size = max(output_len, kernel_total_size);
417+
needed_size = max_t(unsigned long, output_len, kernel_total_size);
416418
#ifdef CONFIG_X86_64
417419
needed_size = ALIGN(needed_size, MIN_KERNEL_ALIGN);
418420
#endif
@@ -443,7 +445,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
443445
#ifdef CONFIG_X86_64
444446
if (heap > 0x3fffffffffffUL)
445447
error("Destination address too large");
446-
if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE)
448+
if (virt_addr + needed_size > KERNEL_IMAGE_SIZE)
447449
error("Destination virtual address is beyond the kernel mapping area");
448450
#else
449451
if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))

0 commit comments

Comments
 (0)