@@ -213,8 +213,7 @@ SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
*/
.bss
.balign 4
-boot_heap:
- .fill BOOT_HEAP_SIZE, 1, 0
+SYM_DATA(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0)
boot_stack:
.fill BOOT_STACK_SIZE, 1, 0
boot_stack_end:
@@ -747,7 +747,7 @@ 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(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0)
SYM_DATA_START_LOCAL(boot_stack)
.fill BOOT_STACK_SIZE, 1, 0
@@ -308,11 +308,11 @@ static inline unsigned long kernel_add_identity_map_dummy(unsigned long start,
* |-------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)
+static void *do_extract_kernel(void *rmode,
+ unsigned char *input_data,
+ unsigned long input_len,
+ unsigned char *output,
+ unsigned long output_len)
{
const unsigned long kernel_total_size = VO__end - VO__text;
unsigned long virt_addr = LOAD_PHYSICAL_ADDR;
@@ -326,26 +326,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
sanitize_boot_params(boot_params);
- init_default_io_ops();
-
- /*
- * On 64-bit this pointer is set during page table uninitialization,
- * but on 32-bit it remains uninitialized, since paging is disabled.
- */
- if (IS_ENABLED(CONFIG_X86_32))
- kernel_add_identity_map = kernel_add_identity_map_dummy;
-
-
- /*
- * Detect TDX guest environment.
- *
- * It has to be done before console_init() in order to use
- * paravirtualized port I/O operations if needed.
- */
- early_tdx_detect();
-
- init_bare_console();
-
/*
* Save RSDP address for later use. Have this after console_init()
* so that early debugging output from the RSDP parsing code can be
@@ -353,11 +333,6 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
*/
boot_params->acpi_rsdp_addr = get_rsdp_addr();
- debug_putstr("early console in extract_kernel\n");
-
- free_mem_ptr = heap; /* Heap */
- free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
-
/*
* The memory hole needed for the kernel is the larger of either
* the entire decompressed kernel plus relocation table, or the
@@ -411,12 +386,12 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
if (virt_addr & (MIN_KERNEL_ALIGN - 1))
error("Destination virtual address inappropriately aligned");
#ifdef CONFIG_X86_64
- if (heap > 0x3fffffffffffUL)
+ if (phys_addr > 0x3fffffffffffUL)
error("Destination address too large");
if (virt_addr + max(output_len, kernel_total_size) > KERNEL_IMAGE_SIZE)
error("Destination virtual address is beyond the kernel mapping area");
#else
- if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
+ if (phys_addr > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff))
error("Destination address too large");
#endif
#ifndef CONFIG_RELOCATABLE
@@ -430,12 +405,71 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
parse_elf(output, output_len, virt_addr);
debug_putstr("done.\nBooting the kernel.\n");
+ return output;
+}
+
+asmlinkage __visible void *extract_kernel(void *rmode, memptr heap,
+ unsigned char *input_data,
+ unsigned long input_len,
+ unsigned char *output,
+ unsigned long output_len)
+{
+ void *entry;
+
+ init_default_io_ops();
+
+ /*
+ * On 64-bit this pointer is set during page table uninitialization,
+ * but on 32-bit it remains uninitialized, since paging is disabled.
+ */
+ if (IS_ENABLED(CONFIG_X86_32))
+ kernel_add_identity_map = kernel_add_identity_map_dummy;
+
+ /*
+ * Detect TDX guest environment.
+ *
+ * It has to be done before console_init() in order to use
+ * paravirtualized port I/O operations if needed.
+ */
+ early_tdx_detect();
+
+ init_bare_console();
+
+ debug_putstr("early console in extract_kernel\n");
+
+ free_mem_ptr = heap; /* Heap */
+ free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
+
+ entry = do_extract_kernel(rmode, input_data,
+ input_len, output, output_len);
+
/* Disable exception handling before booting the kernel */
cleanup_exception_handling();
- return output;
+ return entry;
}
+void *efi_extract_kernel(struct boot_params *rmode,
+ struct efi_extract_callbacks *cb,
+ unsigned char *input_data,
+ unsigned long input_len,
+ unsigned long output_len)
+{
+ extern char boot_heap[BOOT_HEAP_SIZE];
+
+ free_mem_ptr = (unsigned long)boot_heap; /* Heap */
+ free_mem_end_ptr = (unsigned long)boot_heap + BOOT_HEAP_SIZE;
+
+ init_console_func(cb->putstr, cb->puthex);
+ kernel_add_identity_map = cb->map_range;
+
+ return do_extract_kernel(rmode, input_data,
+ input_len, (void *)LOAD_PHYSICAL_ADDR, output_len);
+}
+
+
+
+
void fortify_panic(const char *name)
{
error("detected buffer overflow");
@@ -26,6 +26,7 @@
#include <asm/boot.h>
#include <asm/bootparam.h>
#include <asm/desc_defs.h>
+#include <asm/shared/extract.h>
#include "tdx.h"
new file mode 100644
@@ -0,0 +1,26 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ASM_SHARED_EXTRACT_H
+#define ASM_SHARED_EXTRACT_H
+
+#include <asm/bootparam.h>
+
+#define MAP_WRITE 0x02 /* Writable memory */
+#define MAP_EXEC 0x04 /* Executable memory */
+#define MAP_ALLOC 0x10 /* Range needs to be allocated */
+#define MAP_PROTECT 0x20 /* Set exact memory attributes for memory range */
+
+struct efi_extract_callbacks {
+ void (*putstr)(const char *msg);
+ void (*puthex)(unsigned long x);
+ unsigned long (*map_range)(unsigned long start,
+ unsigned long end,
+ unsigned int flags);
+};
+
+void *efi_extract_kernel(struct boot_params *rmode,
+ struct efi_extract_callbacks *cb,
+ unsigned char *input_data,
+ unsigned long input_len,
+ unsigned long output_len);
+
+#endif /* ASM_SHARED_EXTRACT_H */