Skip to content

Commit 8338151

Browse files
ardbiesheuvelbp3tk0v
authored andcommitted
x86/decompressor: Factor out kernel decompression and relocation
Factor out the decompressor sequence that invokes the decompressor, parses the ELF and applies the relocations so that it can be called directly from the EFI stub. 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-21-ardb@kernel.org
1 parent 2438829 commit 8338151

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

arch/x86/boot/compressed/misc.c

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

333+
const unsigned long kernel_total_size = VO__end - VO__text;
334+
333335
static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);
334336

335337
extern unsigned char input_data[];
336338
extern unsigned int input_len, output_len;
337339

340+
unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
341+
void (*error)(char *x))
342+
{
343+
unsigned long entry;
344+
345+
if (!free_mem_ptr) {
346+
free_mem_ptr = (unsigned long)boot_heap;
347+
free_mem_end_ptr = (unsigned long)boot_heap + sizeof(boot_heap);
348+
}
349+
350+
if (__decompress(input_data, input_len, NULL, NULL, outbuf, output_len,
351+
NULL, error) < 0)
352+
return ULONG_MAX;
353+
354+
entry = parse_elf(outbuf);
355+
handle_relocations(outbuf, output_len, virt_addr);
356+
357+
return entry;
358+
}
359+
338360
/*
339361
* The compressed kernel image (ZO), has been moved so that its position
340362
* is against the end of the buffer used to hold the uncompressed kernel
@@ -354,7 +376,6 @@ extern unsigned int input_len, output_len;
354376
*/
355377
asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
356378
{
357-
const unsigned long kernel_total_size = VO__end - VO__text;
358379
unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
359380
memptr heap = (memptr)boot_heap;
360381
unsigned long needed_size;
@@ -463,10 +484,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
463484
accept_memory(__pa(output), __pa(output) + needed_size);
464485
}
465486

466-
__decompress(input_data, input_len, NULL, NULL, output, output_len,
467-
NULL, error);
468-
entry_offset = parse_elf(output);
469-
handle_relocations(output, output_len, virt_addr);
487+
entry_offset = decompress_kernel(output, virt_addr, error);
470488

471489
debug_putstr("done.\nBooting the kernel (entry_offset: 0x");
472490
debug_puthex(entry_offset);

arch/x86/include/asm/boot.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,12 @@
6262
# define BOOT_STACK_SIZE 0x1000
6363
#endif
6464

65+
#ifndef __ASSEMBLY__
66+
extern unsigned int output_len;
67+
extern const unsigned long kernel_total_size;
68+
69+
unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
70+
void (*error)(char *x));
71+
#endif
72+
6573
#endif /* _ASM_X86_BOOT_H */

0 commit comments

Comments
 (0)