Skip to content

Commit

Permalink
x86/decompressor: Factor out kernel decompression and relocation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Ard Biesheuvel authored and Borislav Petkov (AMD) committed Aug 7, 2023
1 parent 2438829 commit 8338151
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
28 changes: 23 additions & 5 deletions arch/x86/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,11 +330,33 @@ static size_t parse_elf(void *output)
return ehdr.e_entry - LOAD_PHYSICAL_ADDR;
}

const unsigned long kernel_total_size = VO__end - VO__text;

static u8 boot_heap[BOOT_HEAP_SIZE] __aligned(4);

extern unsigned char input_data[];
extern unsigned int input_len, output_len;

unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
void (*error)(char *x))
{
unsigned long entry;

if (!free_mem_ptr) {
free_mem_ptr = (unsigned long)boot_heap;
free_mem_end_ptr = (unsigned long)boot_heap + sizeof(boot_heap);
}

if (__decompress(input_data, input_len, NULL, NULL, outbuf, output_len,
NULL, error) < 0)
return ULONG_MAX;

entry = parse_elf(outbuf);
handle_relocations(outbuf, output_len, virt_addr);

return entry;
}

/*
* 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
Expand All @@ -354,7 +376,6 @@ extern unsigned int input_len, 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;
Expand Down Expand Up @@ -463,10 +484,7 @@ asmlinkage __visible void *extract_kernel(void *rmode, unsigned char *output)
accept_memory(__pa(output), __pa(output) + needed_size);
}

__decompress(input_data, input_len, NULL, NULL, output, output_len,
NULL, error);
entry_offset = parse_elf(output);
handle_relocations(output, output_len, virt_addr);
entry_offset = decompress_kernel(output, virt_addr, error);

debug_putstr("done.\nBooting the kernel (entry_offset: 0x");
debug_puthex(entry_offset);
Expand Down
8 changes: 8 additions & 0 deletions arch/x86/include/asm/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,12 @@
# define BOOT_STACK_SIZE 0x1000
#endif

#ifndef __ASSEMBLY__
extern unsigned int output_len;
extern const unsigned long kernel_total_size;

unsigned long decompress_kernel(unsigned char *outbuf, unsigned long virt_addr,
void (*error)(char *x));
#endif

#endif /* _ASM_X86_BOOT_H */

0 comments on commit 8338151

Please sign in to comment.