efi/x86: add support for generic EFI mixed mode boot
Ard Biesheuvel
maintainerv3 cover efi/x86: add support for generic EFI mixed mode boot
This series is another part of my effort to reduce the level of knowledge on the part of the bootloader or firmware of internal per-architecture details regarding where/how the kernel is loaded and where its initrd and other context data are passed.
Changes since v2:
- add patch to correct the image size as reported in the PE/COFF header, which is slightly too small at the moment for images that happen to execute from the offset they were loaded at by UEFI,
- add even more slack to the image size for mixed mode, which may now run startup_32() misaligned with respect to the minimum alignment as reported in the bootparams struct
- check for long mode support in the 32-bit PE/COFF entrypoint, so we can fail gracefully instead of hang later on,
- simplify handover to efi_pe_entry() from startup_32()
Changes since v1:
- add mixed mode wrappers for the EFI loaded_image protocol (#2)
- expose Exit() boot service and invoke it on errors rather than doing and ordinary function return or entering a deadloop (#3)
- move code into .text and r/o data into .rodata where appropriate, and disentangle the mixed mode boot path and the ordinary one (#4)
- disable initrd load from file in mixed mode
- reorder patches #4 and #5
---- v1 blurb (cont'd) ---
The x86 architecture has a so-called 'EFI handover protocol', which defines how the bootparams struct should be populated, and how it should be interpreted to figure out where to load the kernel, and at which offset in the binary the entrypoint is located. This scheme allows the initrd to be loaded beforehand, and allows 32-bit firmware to invoke a 64-bit kernel via a special entrypoint that manages the state transitions between the two execution modes.
Due to this, x86 loaders currently do not rely on LoadImage and StartImage, and therefore, are forced to re-implement things like image authentication for secure boot and taking the measurements for measured boot in their open coded clones of these routines.
My previous series on this topic [0][1] implements a generic way to load the initrd from any source supported by the loader without relying on something like a device tree or bootparams structure, and so native boot should not need the EFI handover protocol anymore after those change are merged.
What remains is mixed mode boot, which also needs the EFI handover protocol regardless of whether an initrd is loaded or not. So let's get rid of that requirement, and take advantage of the fact that EDK2 based firmware does support LoadImage() for X64 binaries on IA32 firmware, which means we can rely on the secure boot and measured boot checks being performed by the firmware. The only thing we need to put on top is a way to discover the non-native entrypoint into the binary in a way that does not rely on x86 specific headers and data structures.
So let's introduce a new .compat header in the PE/COFF metadata of the bzImage, and populate it with a <machine type, entrypoint> tuple, allowing a generic EFI loader to decide whether the entrypoint supports its native machine type, and invoke it as an ordinary EFI application entrypoint. Since we will not be passing a bootparams structure, we need to discover the base of the image (which contains the setup header) via the loaded image protocol before we can enter the kernel in 32-bit mode at startup_32()
A loader implementation for OVMF can be found at [2]. Note that this loader code is fully generic, and permits mixed mode images to be launched from the UEFI shell or other generic components based on LoadImage/Startimage. It could be used without modifications if other architectures ever emerge that support kernels that can be invoked from a non-native (but cross-type supported) loader.
[0] https://lore.kernel.org/linux-arm-kernel/[email protected]/
[1] https://lore.kernel.org/linux-efi/[email protected]/
[2] https://github.com/ardbiesheuvel/edk2/commits/linux-efi-generic
Ard Biesheuvel (6):
efi/x86: add headroom to decompressor BSS to account for setup block efi/x86: Drop redundant .bss section
efi/libstub/x86: Make loaded_image protocol handling mixed mode safe efi/libstub/x86: Use Exit() boot service to exit the stub on errors efi/x86: Implement mixed mode boot without the handover protocol efi/x86: Add true mixed mode entry point into .compat section
arch/x86/boot/Makefile | 2 +- arch/x86/boot/compressed/head_64.S | 59 ++++++++++++- arch/x86/boot/header.S | 25 +++--- arch/x86/boot/tools/build.c | 86 +++++++++++++------ arch/x86/include/asm/efi.h | 8 ++ .../firmware/efi/libstub/efi-stub-helper.c | 4 +- drivers/firmware/efi/libstub/efistub.h | 50 +++++++---- drivers/firmware/efi/libstub/x86-stub.c | 53 +++++++----- 8 files changed, 207 insertions(+), 80 deletions(-)
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH v3 1/6 efi/x86: add headroom to decompressor BSS to account for setup block
In the bootparams struct, init_size defines the static footprint of the bzImage, counted from the start of the kernel image, i.e., startup_32().
The PE/COFF metadata declares the same size for the entire image, but this time, the image includes the setup block as well, and so the space reserved by UEFI is a bit too small. This usually doesn't matter, since we normally relocate the kernel into a memory allocation of the correct size. But in the unlikely case that the image happens to be loaded at exactly the preferred offset, we skip this relocation, and execute the image in place, stepping on memory beyond the provided allocation, which may be in use for other purposes.
Let's fix this by adding the size of the setup block to the image size as declared in the PE/COFF header.
--- arch/x86/boot/tools/build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/boot/tools/build.c +1 -1
@@ -408,7 +408,7 @@ int main(int argc, char ** argv)update_pecoff_text (setup_sectors *512 , i + (sys_size *16 )); init_sz =get_unaligned_le32 (&buf[0x260 ]); -update_pecoff_bss (i + (sys_size *16 ), init_sz); +update_pecoff_bss (i + (sys_size *16 ), init_sz + setup_sectors *512 );efi_stub_entry_update ();
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH v3 2/6 efi/x86: Drop redundant .bss section
In reply to Ard BiesheuvelIn commit
c7fb93ec51d462ec ("x86/efi: Include a .bss section within the PE/COFF headers")
we added a separate .bss section to the PE/COFF header of the compressed kernel describing the static memory footprint of the decompressor, to ensure that it has enough headroom to decompress itself.
We can achieve the exact same result by increasing the virtual size of the .text section, without changing the raw size, which, as per the PE/COFF specification, requires the loader to zero initialize the delta.
Doing so frees up a slot in the section table, which we will use later to describe the mixed mode entrypoint.
--- arch/x86/boot/header.S | 21 +----------- arch/x86/boot/tools/build.c | 36 +++++++------------- 2 files changed, 13 insertions(+), 44 deletions(-)
arch/x86/boot/header.S +1 -20
@@ -106,7 +106,7 @@ coff_header: #else .word 0x8664 # x86-64 #endif - .word 4 # nr_sections + .word 3 # nr_sections .long 0 # TimeDateStamp .long 0 # PointerToSymbolTable .long 1 # NumberOfSymbols
@@ -248,25 +248,6 @@ section_table: .word 0 # NumberOfLineNumbers .long 0x60500020 # Characteristics (section flags) - # - # The offset & size fields are filled in by build.c. - # - .ascii ".bss" - .byte 0 - .byte 0 - .byte 0 - .byte 0 - .long 0 - .long 0x0 - .long 0 # Size of initialized data - # on disk - .long 0x0 - .long 0 # PointerToRelocations - .long 0 # PointerToLineNumbers - .word 0 # NumberOfRelocations - .word 0 # NumberOfLineNumbers - .long 0xc8000080 # Characteristics (section flags) - #endif /* CONFIG_EFI_STUB */ # Kernel attributes; used by setup. This is part 1 of the
arch/x86/boot/tools/build.c +12 -24
@@ -203,10 +203,12 @@ static void update_pecoff_setup_and_reloc(unsigned int size)put_unaligned_le32 (10 , &buf[reloc_offset +4 ]); } -static void update_pecoff_text (unsigned int text_start,unsigned int file_sz) +static void update_pecoff_text (unsigned int text_start,unsigned int file_sz, +unsigned int init_sz) {unsigned int pe_header;unsigned int text_sz = file_sz - text_start; +unsigned int bss_sz = init_sz + text_start - file_sz; pe_header =get_unaligned_le32 (&buf[0x3c ]);
@@ -214,30 +216,18 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)* Size of code: Subtract the size of the first sector (512 bytes) * which includes the header. */ -put_unaligned_le32 (file_sz -512 , &buf[pe_header +0x1c ]); +put_unaligned_le32 (file_sz -512 + bss_sz, &buf[pe_header +0x1c ]); + +/* Size of image */ +put_unaligned_le32 (init_sz + text_start, &buf[pe_header +0x50 ]);/* * Address of entry point for PE/COFF executable */ put_unaligned_le32 (text_start + efi_pe_entry, &buf[pe_header +0x28 ]); -update_pecoff_section_header (".text" , text_start, text_sz); -} - -static void update_pecoff_bss (unsigned int file_sz,unsigned int init_sz) -{ -unsigned int pe_header; -unsigned int bss_sz = init_sz - file_sz; - - pe_header =get_unaligned_le32 (&buf[0x3c ]); - -/* Size of uninitialized data */ -put_unaligned_le32 (bss_sz, &buf[pe_header +0x24 ]); - -/* Size of image */ -put_unaligned_le32 (init_sz, &buf[pe_header +0x50 ]); - -update_pecoff_section_header_fields (".bss" , file_sz, bss_sz,0 ,0 ); +update_pecoff_section_header_fields (".text" , text_start, text_sz + bss_sz, + text_sz, text_start); }static int reserve_pecoff_reloc_section (int c)
@@ -278,9 +268,8 @@ static void efi_stub_entry_update(void)static inline void update_pecoff_setup_and_reloc (unsigned int size) {}static inline void update_pecoff_text (unsigned int text_start, -unsigned int file_sz) {} -static inline void update_pecoff_bss (unsigned int file_sz, -unsigned int init_sz) {} +unsigned int file_sz, +unsigned int init_sz) {}static inline void efi_stub_defaults (void ) {}static inline void efi_stub_entry_update (void ) {}
@@ -406,9 +395,8 @@ int main(int argc, char ** argv) buf[0x1f1 ] = setup_sectors-1 ;put_unaligned_le32 (sys_size, &buf[0x1f4 ]); -update_pecoff_text (setup_sectors *512 , i + (sys_size *16 )); init_sz =get_unaligned_le32 (&buf[0x260 ]); -update_pecoff_bss (i + (sys_size *16 ), init_sz + setup_sectors *512 ); +update_pecoff_text (setup_sectors *512 , i + (sys_size *16 ), init_sz);efi_stub_entry_update ();
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH v3 3/6 efi/libstub/x86: Make loaded_image protocol handling mixed mode safe
In reply to Ard BiesheuvelAdd the definitions and use the special wrapper so that the loaded_image UEFI protocol can be safely used from mixed mode.
--- drivers/firmware/efi/libstub/efi-stub-helper.c | 4 +- drivers/firmware/efi/libstub/efistub.h | 45 ++++++++++++++------ drivers/firmware/efi/libstub/x86-stub.c | 4 +- 3 files changed, 35 insertions(+), 18 deletions(-)
drivers/firmware/efi/libstub/efi-stub-helper.c +2 -2
@@ -171,8 +171,8 @@ char *efi_convert_cmdline(efi_loaded_image_t *image,const u16 *s2;u8 *s1 =NULL ;unsigned long cmdline_addr =0 ; -int load_options_chars = image->load_options_size /2 ;/* UTF-16 */ -const u16 *options = image->load_options; +int load_options_chars =efi_table_attr (image, load_options_size) /2 ; +const u16 *options =efi_table_attr (image, load_options);int options_bytes =0 ;/* UTF-8 bytes */ int options_chars =0 ;/* UTF-16 chars */ efi_status_t status;
drivers/firmware/efi/libstub/efistub.h +31 -14
51 lines not on this page · raw message
drivers/firmware/efi/libstub/x86-stub.c +2 -2
@@ -377,7 +377,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,return status; } - hdr = &((struct boot_params *)image->image_base)->hdr; + hdr = &((struct boot_params *)efi_table_attr (image, image_base))->hdr; above4g = hdr->xloadflags &XLF_CAN_BE_LOADED_ABOVE_4G ; status = efi_allocate_pages(0x4000, (unsigned long *)&boot_params,
@@ -392,7 +392,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, hdr = &boot_params->hdr;/* Copy the second sector to boot_params */ -memcpy (&hdr->jump, image->image_base +512 ,512 ); +memcpy (&hdr->jump,efi_table_attr (image, image_base) +512 ,512 );/* * Fill out some of the header fields ourselves because the
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH v3 4/6 efi/libstub/x86: Use Exit() boot service to exit the stub on errors
In reply to Ard BiesheuvelCurrently, we either return with an error [from efi_pe_entry()] or enter a deadloop [in efi_main()] if any fatal errors occur during execution of the EFI stub. Let's switch to calling the Exit() EFI boot service instead in both cases, so that we
a) can get rid of the deadloop, and simply return to the boot manager if any errors occur during execution of the stub, including during the call to ExitBootServices(),
b) can also return cleanly from efi_pe_entry() or efi_main() in mixed mode, once we introduce support for LoadImage/StartImage based mixed mode in the next patch.
Note that on systems running downstream GRUBs [which do not use LoadImage or StartImage to boot the kernel, and instead, pass their own image handle as the loaded image handle], calling Exit() will exit from GRUB rather than from the kernel, but this is a tolerable side effect.
--- arch/x86/include/asm/efi.h | 8 ++++++++ drivers/firmware/efi/libstub/efistub.h | 5 ++++- drivers/firmware/efi/libstub/x86-stub.c | 20 +++++++++++++------- 3 files changed, 25 insertions(+), 8 deletions(-)
arch/x86/include/asm/efi.h +8 -0
@@ -270,6 +270,11 @@ static inline void *efi64_zero_upper(void *p)return p; } +static inline u32 efi64_convert_status (efi_status_t status) +{ +return (u32)(status | (u64 )status >>32 ); +} +#define __efi64_argmap_free_pages (addr, size) \ ((addr), 0, (size))
@@ -288,6 +293,9 @@ static inline void *efi64_zero_upper(void *p)#define __efi64_argmap_locate_device_path (protocol, path, handle) \ ((protocol), (path), efi64_zero_upper(handle)) +#define __efi64_argmap_exit (handle, status, size, data) \ + ((handle), efi64_convert_status(status), (size), (data)) +/* PCI I/O */ #define __efi64_argmap_get_location (protocol, seg, bus, dev, func) \ ((protocol), efi64_zero_upper(seg), efi64_zero_upper(bus), \
drivers/firmware/efi/libstub/efistub.h +4 -1
@@ -144,7 +144,10 @@ union efi_boot_services { void *);void *load_image;void *start_image; -void *exit; +efi_status_t __noreturn (__efiapi *exit)(efi_handle_t, + efi_status_t, + unsigned long, + efi_char16_t *);void *unload_image;efi_status_t (__efiapi *exit_boot_services)(efi_handle_t, unsigned long);
drivers/firmware/efi/libstub/x86-stub.c +13 -7
@@ -340,6 +340,13 @@ static void setup_graphics(struct boot_params *boot_params) } } + +static void __noreturn efi_exit (efi_handle_t handle,efi_status_t status) +{ +efi_bs_call (exit, handle, status,0 ,NULL ); +unreachable (); +} +void startup_32 (struct boot_params *boot_params); void __noreturn efi_stub_entry(efi_handle_t handle,
@@ -369,12 +376,12 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,/* Check if we were booted by the EFI firmware */ if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) -return EFI_INVALID_PARAMETER ; +efi_exit (handle,EFI_INVALID_PARAMETER ); status =efi_bs_call (handle_protocol, handle, &proto, (void *)&image);if (status !=EFI_SUCCESS ) {efi_printk ("Failed to get handle for LOADED_IMAGE_PROTOCOL\n" ); -return status; +efi_exit (handle, status); } hdr = &((struct boot_params *)efi_table_attr (image, image_base))->hdr;
@@ -384,7 +391,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, above4g ? ULONG_MAX : UINT_MAX);if (status !=EFI_SUCCESS ) {efi_printk ("Failed to allocate lowmem for boot params\n" ); -return status; +efi_exit (handle, status); }memset (boot_params,0x0 ,0x4000 );
@@ -442,7 +449,7 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, fail:efi_free (0x4000 , (unsigned long )boot_params); -return status; +efi_exit (handle, status); } static void add_e820ext(struct boot_params *params,
@@ -709,7 +716,7 @@ struct boot_params *efi_main(efi_handle_t handle,/* Check if we were booted by the EFI firmware */ if (sys_table->hdr.signature !=EFI_SYSTEM_TABLE_SIGNATURE ) - goto fail; +efi_exit (handle,EFI_INVALID_PARAMETER );/* * If the kernel isn't already loaded at the preferred load
@@ -793,6 +800,5 @@ struct boot_params *efi_main(efi_handle_t handle, fail:efi_printk ("efi_main() failed!\n" ); -for (;;) - asm("hlt" ); +efi_exit (handle, status); }
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH v3 5/6 efi/x86: Implement mixed mode boot without the handover protocol
In reply to Ard BiesheuvelAdd support for booting 64-bit x86 kernels from 32-bit firmware running on 64-bit capable CPUs without requiring the bootloader to implement the EFI handover protocol or allocate the setup block, etc etc, all of which can be done by the stub itself, using code that already exists.
Instead, create an ordinary EFI application entrypoint but implemented in 32-bit code [so that it can be invoked by 32-bit firmware], and stash the address of this 32-bit entrypoint in the .compat section where the bootloader can find it.
Note that we use the setup block embedded in the binary to go through startup_32(), but it gets reallocated and copied in efi_pe_entry(), using the same code that runs when the x86 kernel is booted in EFI mode from native firmware. This requires the loaded image protocol to be installed on the kernel image's EFI handle, and point to the kernel image itself and not to its loader. This, in turn, requires the bootloader to use the LoadImage() boot service to load the 64-bit image from 32-bit firmware, which is in fact supported by firmware based on EDK2. (Only StartImage() will fail, and instead, the newly added entrypoint needs to be invoked)
--- arch/x86/boot/compressed/head_64.S | 59 +++++++++++++++++++- drivers/firmware/efi/libstub/x86-stub.c | 29 +++++----- 2 files changed, 73 insertions(+), 15 deletions(-)
arch/x86/boot/compressed/head_64.S +57 -2
@@ -207,8 +207,13 @@ SYM_FUNC_START(startup_32) cmp $0, %edi jz 1f leal efi64_stub_entry(%ebp), %eax - movl %esi, %edx movl efi32_boot_args+4(%ebp), %esi + movl efi32_boot_args+8(%ebp), %edx // saved bootparams pointer + cmpl $0, %edx + jnz 1f + leal efi_pe_entry(%ebp), %eax + movl %edi, %ecx // MS calling convention + movl %esi, %edx 1: #endif pushl %eax
@@ -233,6 +238,8 @@ SYM_FUNC_START(efi32_stub_entry) 1: pop %ebp subl $1b, %ebp + movl %esi, efi32_boot_args+8(%ebp) +SYM_INNER_LABEL(efi32_pe_stub_entry, SYM_L_LOCAL) movl %ecx, efi32_boot_args(%ebp) movl %edx, efi32_boot_args+4(%ebp) movb $0, efi_is64(%ebp)
@@ -641,8 +648,56 @@ SYM_DATA_START_LOCAL(gdt) SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end) #ifdef CONFIG_EFI_MIXED -SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0) +SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0) SYM_DATA(efi_is64, .byte 1) + +#define ST32_boottime 60 // offsetof(efi_system_table_32_t, boottime) +#define BS32_handle_protocol 88 // offsetof(efi_boot_services_32_t, handle_protocol) +#define LI32_image_base 32 // offsetof(efi_loaded_image_32_t, image_base) + + .text + .code32 +SYM_FUNC_START(efi32_pe_entry) + pushl %ebp + + call verify_cpu // check for long mode support + testl %eax, %eax + movl $0x80000003, %eax // EFI_UNSUPPORTED + jnz 3f + + call 1f +1: pop %ebp + subl $1b, %ebp + + /* Get the loaded image protocol pointer from the image handle */ + subl $12, %esp // space for the loaded image pointer + pushl %esp // pass its address + leal 4f(%ebp), %eax + pushl %eax // pass the GUID address + pushl 28(%esp) // pass the image handle + + movl 36(%esp), %eax // sys_table + movl ST32_boottime(%eax), %eax // sys_table->boottime + call *BS32_handle_protocol(%eax) // sys_table->boottime->handle_protocol + cmp $0, %eax + jnz 2f + + movl 32(%esp), %ecx // image_handle + movl 36(%esp), %edx // sys_table + movl 12(%esp), %esi // loaded_image + movl LI32_image_base(%esi), %esi // loaded_image->image_base + jmp efi32_pe_stub_entry + +2: addl $24, %esp +3: popl %ebp + ret +SYM_FUNC_END(efi32_pe_entry) + + .section ".rodata" + /* EFI loaded image protocol GUID */ +4: .long 0x5B1B31A1 + .word 0x9562, 0x11d2 + .byte 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B #endif /*
drivers/firmware/efi/libstub/x86-stub.c +16 -13
@@ -424,21 +424,24 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, hdr->ramdisk_image =0 ; hdr->ramdisk_size =0 ; - status =efi_parse_options (cmdline_ptr); -if (status !=EFI_SUCCESS ) - goto fail2; - -if (!noinitrd ()) { - status =efi_load_initrd (image, &ramdisk_addr, &ramdisk_size, - hdr->initrd_addr_max, - above4g ?ULONG_MAX - : hdr->initrd_addr_max); +if (efi_is_native ()) { + status =efi_parse_options (cmdline_ptr);if (status !=EFI_SUCCESS ) goto fail2; - hdr->ramdisk_image = ramdisk_addr &0xffffffff ; - hdr->ramdisk_size = ramdisk_size &0xffffffff ; - boot_params->ext_ramdisk_image = (u64 )ramdisk_addr >>32 ; - boot_params->ext_ramdisk_size = (u64 )ramdisk_size >>32 ; + +if (!noinitrd ()) { + status =efi_load_initrd (image, &ramdisk_addr, + &ramdisk_size, + hdr->initrd_addr_max, + above4g ?ULONG_MAX + : hdr->initrd_addr_max); +if (status !=EFI_SUCCESS ) + goto fail2; + hdr->ramdisk_image = ramdisk_addr &0xffffffff ; + hdr->ramdisk_size = ramdisk_size &0xffffffff ; + boot_params->ext_ramdisk_image = (u64 )ramdisk_addr >>32 ; + boot_params->ext_ramdisk_size = (u64 )ramdisk_size >>32 ; + } }efi_stub_entry (handle, sys_table, boot_params);
Signature · 1 line
2.17.1
Ard Biesheuvel
maintainerPATCH v3 6/6 efi/x86: Add true mixed mode entry point into .compat section
In reply to Ard BiesheuvelCurrently, mixed mode is closely tied to the EFI handover protocol and relies on intimate knowledge of the bootparams structure, setup header etc, all of which are rather byzantine and entirely specific to x86.
Even though no other EFI supported architectures are currently known that could support something like mixed mode, it still makes sense to abstract a bit from this, and make it part of a generic Linux on EFI boot protocol.
To that end, add a .compat section to the mixed mode binary, and populate it with the PE machine type and entry point address, allowing firmware implementations to match it to their native machine type, and invoke non-native binaries using a secondary entry point.
--- arch/x86/boot/Makefile | 2 +- arch/x86/boot/header.S | 20 +++++++- arch/x86/boot/tools/build.c | 50 +++++++++++++++++++- 3 files changed, 69 insertions(+), 3 deletions(-)
arch/x86/boot/Makefile +1 -1
@@ -88,7 +88,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) -sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' +sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [a-zA-Z] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|efi32_pe_entry\|input_data\|kernel_info\|_end\|_ehead\|_text\|z_.*\)$$/\#define ZO_\2 0x\1/p' quiet_cmd_zoffset = ZOFFSET $@ cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
arch/x86/boot/header.S +19 -1
@@ -106,7 +106,7 @@ coff_header: #else .word 0x8664 # x86-64 #endif - .word 3 # nr_sections + .word section_count # nr_sections .long 0 # TimeDateStamp .long 0 # PointerToSymbolTable .long 1 # NumberOfSymbols
@@ -230,6 +230,23 @@ section_table: .word 0 # NumberOfLineNumbers .long 0x42100040 # Characteristics (section flags) +#ifdef CONFIG_EFI_MIXED + # + # The offset & size fields are filled in by build.c. + # + .asciz ".compat" + .long 0 + .long 0x0 + .long 0 # Size of initialized data + # on disk + .long 0x0 + .long 0 # PointerToRelocations + .long 0 # PointerToLineNumbers + .word 0 # NumberOfRelocations + .word 0 # NumberOfLineNumbers + .long 0x42100040 # Characteristics (section flags) +#endif + # # The offset & size fields are filled in by build.c. #
@@ -248,6 +265,7 @@ section_table: .word 0 # NumberOfLineNumbers .long 0x60500020 # Characteristics (section flags) + .set section_count, (. - section_table) / 40 #endif /* CONFIG_EFI_STUB */ # Kernel attributes; used by setup. This is part 1 of the
arch/x86/boot/tools/build.c +49 -1
95 lines not on this page · raw message
Signature · 1 line
2.17.1
Quoted 5 lines · Ard Biesheuvel
This series is another part of my effort to reduce the level of knowledge on the part of the bootloader or firmware of internal per-architecture details regarding where/how the kernel is loaded and where its initrd and other context data are passed.
...
Quoted 25 lines
What remains is mixed mode boot, which also needs the EFI handover protocol regardless of whether an initrd is loaded or not. So let's get rid of that requirement, and take advantage of the fact that EDK2 based firmware does support
LoadImage()for X64 binaries on IA32 firmware, which means we can rely on the secure boot and measured boot checks being performed by the firmware. The only thing we need to put on top is a way to discover the non-native entrypoint into the binary in a way that does not rely on x86 specific headers and data structures.So let's introduce a new .compat header in the PE/COFF metadata of the bzImage, and populate it with a <machine type, entrypoint> tuple, allowing a generic EFI loader to decide whether the entrypoint supports its native machine type, and invoke it as an ordinary EFI application entrypoint. Since we will not be passing a bootparams structure, we need to discover the base of the image (which contains the setup header) via the loaded image protocol before we can enter the kernel in 32-bit mode at
startup_32()A loader implementation for OVMF can be found at [2]. Note that this loader code is fully generic, and permits mixed mode images to be launched from the UEFI shell or other generic components based on LoadImage/Startimage. It could be used without modifications if other architectures ever emerge that support kernels that can be invoked from a non-native (but cross-type supported) loader.
Quoted 4 lines
[0] https://lore.kernel.org/linux-arm-kernel/[email protected]/
[1] https://lore.kernel.org/linux-efi/[email protected]/
[2] https://github.com/ardbiesheuvel/edk2/commits/linux-efi-generic
Hi Ard, I'm getting a kernel panic with this series using the compat entry point.
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \ -drive file=fat:rw:qemu/boot -nographic -m 3072
(The bzImage is in qemu/boot) Then starting it from the UEFI shell.
FS0:\> bzImage earlyprintk=ttyS0,keep efi=debug
First problem is that qemu loads the bzImage above 2Gb causing a very early crash. Attached patch solves that issue and lets the boot proceed. However, with KASLR enabled, quite frequently I get the kernel panic in the attached log. Haven't figured out exactly where it comes from.
Thanks.
From 3c3598944a88791ba8d1925791377c39fbaf3c0d Mon Sep 17 00:00:00 2001
From: Arvind Sankar <[email protected]>
Date: Sat, 29 Feb 2020 19:04:42 -0500
Subject: [PATCH] x86/boot: Use unsigned comparison for addresses
The load address is compared with LOAD_PHYSICAL_ADDR using a signed comparison currently (using jge instruction).
When loading a 64-bit kernel using the new efi32_pe_entry point added by commit 97aa276579b2 ("efi/x86: Add true mixed mode entry point into .compat section") using qemu with -m 3072, the firmware actually loads us above 2Gb, resulting in a very early crash.
Use jae instruction to perform unsigned comparison instead, as physical addresses should be considered as unsigned.
--- arch/x86/boot/compressed/head_32.S | 2 +- arch/x86/boot/compressed/head_64.S | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
arch/x86/boot/compressed/head_32.S +1 -1
@@ -105,7 +105,7 @@ SYM_FUNC_START(startup_32) notl %eax andl %eax, %ebx cmpl $LOAD_PHYSICAL_ADDR, %ebx - jge 1f + jae 1f #endif movl $LOAD_PHYSICAL_ADDR, %ebx 1:
arch/x86/boot/compressed/head_64.S +2 -2
@@ -105,7 +105,7 @@ SYM_FUNC_START(startup_32) notl %eax andl %eax, %ebx cmpl $LOAD_PHYSICAL_ADDR, %ebx - jge 1f + jae 1f #endif movl $LOAD_PHYSICAL_ADDR, %ebx 1:
@@ -305,7 +305,7 @@ SYM_CODE_START(startup_64) notq %rax andq %rax, %rbp cmpq $LOAD_PHYSICAL_ADDR, %rbp - jge 1f + jae 1f #endif movq $LOAD_PHYSICAL_ADDR, %rbp 1:
Signature · 1 line
2.24.1
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF-mixed-mode-compat-section.fd -drive file=fat:rw:qemu/boot -nographic -m 3072
UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
FS0: Alias(s):HD0a1:;BLK1:
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)/HD(1,MBR,0xBE1AFDFA,0x3F,0xFBFC1)
BLK0: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0)
BLK2: Alias(s):
PciRoot(0x0)/Pci(0x1,0x1)/Ata(0x0) Press ESC in 5 seconds to skip startup.nsh or any other key to continue. Shell> fs0:
FS0:\> bzImage64 earlyprintk=ttyS0,keep efi=debug
early console in extract_kernelinput_data: 0x0000000002b4d3acinput_len: 0x000000000085e2d6
output: 0x0000000001400000output_len: 0x0000000001f7b8d4kernel_total_size: 0x0000000001c2c000needed_size: 0x0000000002000000trampoline_32bit: 0x000000000009d000
booted via startup_64()
Physical KASLR using RDRAND RDTSC...
Virtual KASLR using RDRAND RDTSC...
Decompressing Linux... Parsing ELF... Performing relocations... done. Booting the kernel.
[ 0.000000] Linux version 5.6.0-rc3+ (arvind@rani) (gcc version 9.2.0 (Gentoo Hardened 9.2.0-r4 p5)) #3 SMP Sun Mar 1 11:49:45 EST 2020 [ 0.000000] Command line: bzImage64 earlyprintk=ttyS0,keep efi=debug [ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers' [ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers' [ 0.000000] x86/fpu: Enabled xstate features 0x3, context size is 576 bytes, using 'standard' format. [ 0.000000] BIOS-provided physical RAM map: [ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable [ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x0000000000805fff] usable [ 0.000000] BIOS-e820: [mem 0x0000000000806000-0x0000000000807fff] ACPI NVS [ 0.000000] BIOS-e820: [mem 0x0000000000808000-0x000000000080ffff] usable [ 0.000000] BIOS-e820: [mem 0x0000000000810000-0x00000000008fffff] ACPI NVS [ 0.000000] BIOS-e820: [mem 0x0000000000900000-0x00000000be933fff] usable [ 0.000000] BIOS-e820: [mem 0x00000000be934000-0x00000000be945fff] ACPI NVS [ 0.000000] BIOS-e820: [mem 0x00000000be946000-0x00000000be960fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000be961000-0x00000000bea6bfff] usable [ 0.000000] BIOS-e820: [mem 0x00000000bea6c000-0x00000000beb1afff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000beb1b000-0x00000000bfb9afff] usable [ 0.000000] BIOS-e820: [mem 0x00000000bfb9b000-0x00000000bfbf2fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000bfbf3000-0x00000000bfbfafff] ACPI data [ 0.000000] BIOS-e820: [mem 0x00000000bfbfb000-0x00000000bfbfefff] ACPI NVS [ 0.000000] BIOS-e820: [mem 0x00000000bfbff000-0x00000000bfef3fff] usable [ 0.000000] BIOS-e820: [mem 0x00000000bfef4000-0x00000000bff77fff] reserved [ 0.000000] BIOS-e820: [mem 0x00000000bff78000-0x00000000bfffffff] ACPI NVS [ 0.000000] BIOS-e820: [mem 0x00000000ffc00000-0x00000000ffffffff] reserved [ 0.000000] printk: console [earlyser0] enabled [ 0.000000] NX (Execute Disable) protection: active [ 0.000000] extended physical RAM map: [ 0.000000] reserve setup_data: [mem 0x0000000000000000-0x000000000009ffff] usable [ 0.000000] reserve setup_data: [mem 0x0000000000100000-0x0000000000805fff] usable [ 0.000000] reserve setup_data: [mem 0x0000000000806000-0x0000000000807fff] ACPI NVS [ 0.000000] reserve setup_data: [mem 0x0000000000808000-0x000000000080ffff] usable [ 0.000000] reserve setup_data: [mem 0x0000000000810000-0x00000000008fffff] ACPI NVS [ 0.000000] reserve setup_data: [mem 0x0000000000900000-0x00000000be58700f] usable [ 0.000000] reserve setup_data: [mem 0x00000000be587010-0x00000000be5c1a4f] usable [ 0.000000] reserve setup_data: [mem 0x00000000be5c1a50-0x00000000be5e800f] usable [ 0.000000] reserve setup_data: [mem 0x00000000be5e8010-0x00000000be5f184f] usable [ 0.000000] reserve setup_data: [mem 0x00000000be5f1850-0x00000000be933fff] usable [ 0.000000] reserve setup_data: [mem 0x00000000be934000-0x00000000be945fff] ACPI NVS [ 0.000000] reserve setup_data: [mem 0x00000000be946000-0x00000000be960fff] reserved [ 0.000000] reserve setup_data: [mem 0x00000000be961000-0x00000000bea6bfff] usable [ 0.000000] reserve setup_data: [mem 0x00000000bea6c000-0x00000000beb1afff] reserved [ 0.000000] reserve setup_data: [mem 0x00000000beb1b000-0x00000000bfb9afff] usable [ 0.000000] reserve setup_data: [mem 0x00000000bfb9b000-0x00000000bfbf2fff] reserved [ 0.000000] reserve setup_data: [mem 0x00000000bfbf3000-0x00000000bfbfafff] ACPI data [ 0.000000] reserve setup_data: [mem 0x00000000bfbfb000-0x00000000bfbfefff] ACPI NVS [ 0.000000] reserve setup_data: [mem 0x00000000bfbff000-0x00000000bfef3fff] usable [ 0.000000] reserve setup_data: [mem 0x00000000bfef4000-0x00000000bff77fff] reserved [ 0.000000] reserve setup_data: [mem 0x00000000bff78000-0x00000000bfffffff] ACPI NVS [ 0.000000] reserve setup_data: [mem 0x00000000ffc00000-0x00000000ffffffff] reserved [ 0.000000] efi: EFI v2.70 by EDK II [ 0.000000] efi: SMBIOS=0xbfbcc000 ACPI=0xbfbfa000 ACPI 2.0=0xbfbfa014 MEMATTR=0xbe649190 [ 0.000000] efi: mem00: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000000000-0x0000000000000fff] (0MB) [ 0.000000] efi: mem01: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000001000-0x000000000009ffff] (0MB) [ 0.000000] efi: mem02: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000100000-0x0000000000805fff] (7MB) [ 0.000000] efi: mem03: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000806000-0x0000000000807fff] (0MB) [ 0.000000] efi: mem04: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000808000-0x000000000080ffff] (0MB) [ 0.000000] efi: mem05: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000810000-0x00000000008fffff] (0MB) [ 0.000000] efi: mem06: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000900000-0x00000000013fffff] (11MB) [ 0.000000] efi: mem07: [Loader Data | | | | | | | | | |WB|WT|WC|UC] range=[0x0000000001400000-0x00000000033e5fff] (31MB) [ 0.000000] efi: mem08: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000033e6000-0x00000000b9d8dfff] (2921MB) [ 0.000000] efi: mem09: [Loader Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000b9d8e000-0x00000000bbf77fff] (33MB) [ 0.000000] efi: mem10: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bbf78000-0x00000000bbf97fff] (0MB) [ 0.000000] efi: mem11: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bbf98000-0x00000000be49bfff] (37MB) [ 0.000000] efi: mem12: [Loader Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be49c000-0x00000000be56dfff] (0MB) [ 0.000000] efi: mem13: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be56e000-0x00000000be586fff] (0MB) [ 0.000000] efi: mem14: [Loader Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be587000-0x00000000be5c1fff] (0MB) [ 0.000000] efi: mem15: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5c2000-0x00000000be5dffff] (0MB) [ 0.000000] efi: mem16: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5e0000-0x00000000be5e6fff] (0MB) [ 0.000000] efi: mem17: [Loader Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5e7000-0x00000000be5f7fff] (0MB) [ 0.000000] efi: mem18: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5f8000-0x00000000be7ebfff] (1MB) [ 0.000000] efi: mem19: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be7ec000-0x00000000be933fff] (1MB) [ 0.000000] efi: mem20: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be934000-0x00000000be945fff] (0MB) [ 0.000000] efi: mem21: [Reserved | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be946000-0x00000000be960fff] (0MB) [ 0.000000] efi: mem22: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be961000-0x00000000bea6bfff] (1MB) [ 0.000000] efi: mem23: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea6c000-0x00000000bea70fff] (0MB) [ 0.000000] efi: mem24: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea71000-0x00000000bea75fff] (0MB) [ 0.000000] efi: mem25: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea76000-0x00000000bea7afff] (0MB) [ 0.000000] efi: mem26: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea7b000-0x00000000bea7ffff] (0MB) [ 0.000000] efi: mem27: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea80000-0x00000000bea84fff] (0MB) [ 0.000000] efi: mem28: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea85000-0x00000000bea8bfff] (0MB) [ 0.000000] efi: mem29: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea8c000-0x00000000beb1afff] (0MB) [ 0.000000] efi: mem30: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000beb1b000-0x00000000bfa1afff] (15MB) [ 0.000000] efi: mem31: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfa1b000-0x00000000bfb9afff] (1MB) [ 0.000000] efi: mem32: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfb9b000-0x00000000bfbcafff] (0MB) [ 0.000000] efi: mem33: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfbcb000-0x00000000bfbeefff] (0MB) [ 0.000000] efi: mem34: [Reserved | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfbef000-0x00000000bfbf2fff] (0MB) [ 0.000000] efi: mem35: [ACPI Reclaim Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfbf3000-0x00000000bfbfafff] (0MB) [ 0.000000] efi: mem36: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfbfb000-0x00000000bfbfefff] (0MB) [ 0.000000] efi: mem37: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfbff000-0x00000000bfdfffff] (2MB) [ 0.000000] efi: mem38: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe00000-0x00000000bfe89fff] (0MB) [ 0.000000] efi: mem39: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe8a000-0x00000000bfea9fff] (0MB) [ 0.000000] efi: mem40: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfeaa000-0x00000000bfeccfff] (0MB) [ 0.000000] efi: mem41: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfecd000-0x00000000bfed5fff] (0MB) [ 0.000000] efi: mem42: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfed6000-0x00000000bfef3fff] (0MB) [ 0.000000] efi: mem43: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfef4000-0x00000000bff77fff] (0MB) [ 0.000000] efi: mem44: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bff78000-0x00000000bfffffff] (0MB) [ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB) [ 0.000000] SMBIOS 2.8 present. [ 0.000000] DMI: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015 [ 0.000000] tsc: Fast TSC calibration using PIT [ 0.000000] tsc: Detected 2195.098 MHz processor [ 0.001418] last_pfn = 0xbfef4 max_arch_pfn = 0x400000000 [ 0.002451] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WP UC- WT Memory KASLR using RDRAND RDTSC... [ 0.019655] check: Scanning 1 areas for low memory corruption [ 0.025410] Secure boot disabled [ 0.025847] ACPI: Early table checksum verification disabled [ 0.026363] ACPI: RSDP 0x00000000BFBFA014 000024 (v02 BOCHS ) [ 0.026710] ACPI: XSDT 0x00000000BFBF90E8 000044 (v01 BOCHS BXPCFACP 00000001 01000013) [ 0.027515] ACPI: FACP 0x00000000BFBF6000 000074 (v01 BOCHS BXPCFACP 00000001 BXPC 00000001) [ 0.028190] ACPI: DSDT 0x00000000BFBF7000 00140B (v01 BOCHS BXPCDSDT 00000001 BXPC 00000001) [ 0.028566] ACPI: FACS 0x00000000BFBFD000 000040 [ 0.028792] ACPI: APIC 0x00000000BFBF5000 000078 (v01 BOCHS BXPCAPIC 00000001 BXPC 00000001) [ 0.029091] ACPI: HPET 0x00000000BFBF4000 000038 (v01 BOCHS BXPCHPET 00000001 BXPC 00000001) [ 0.029390] ACPI: BGRT 0x00000000BFBF3000 000038 (v01 INTEL EDK2 00000002 01000013) [ 0.031325] No NUMA configuration found [ 0.031502] Faking a node at [mem 0x0000000000000000-0x00000000bfef3fff] [ 0.032286] NODE_DATA(0) allocated [mem 0xbfe86000-0xbfe89fff] [ 0.034426] Zone ranges: [ 0.034560] DMA [mem 0x0000000000001000-0x0000000000ffffff] [ 0.034797] DMA32 [mem 0x0000000001000000-0x00000000bfef3fff] [ 0.035028] Normal empty [ 0.035155] Movable zone start for each node [ 0.035313] Early memory node ranges [ 0.035461] node 0: [mem 0x0000000000001000-0x000000000009ffff] [ 0.035796] node 0: [mem 0x0000000000100000-0x0000000000805fff] [ 0.036007] node 0: [mem 0x0000000000808000-0x000000000080ffff] [ 0.036228] node 0: [mem 0x0000000000900000-0x00000000be933fff] [ 0.036459] node 0: [mem 0x00000000be961000-0x00000000bea6bfff] [ 0.036671] node 0: [mem 0x00000000beb1b000-0x00000000bfb9afff] [ 0.036876] node 0: [mem 0x00000000bfbff000-0x00000000bfef3fff] [ 0.037937] Zeroed struct page in unavailable ranges: 927 pages [ 0.038083] Initmem setup node 0 [mem 0x0000000000001000-0x00000000bfef3fff] [ 0.119644] ACPI: PM-Timer IO Port: 0xb008 [ 0.120357] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1]) [ 0.120983] IOAPIC[0]: apic_id 0, version 32, address 0xfec00000, GSI 0-23 [ 0.121322] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl) [ 0.121779] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level) [ 0.122002] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level) [ 0.122319] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level) [ 0.122546] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level) [ 0.122976] Using ACPI (MADT) for SMP configuration information [ 0.123218] ACPI: HPET id: 0x8086a201 base: 0xfed00000 [ 0.124945] smpboot: Allowing 1 CPUs, 0 hotplug CPUs [ 0.126014] PM: hibernation: Registered nosave memory: [mem 0x00000000-0x00000fff] [ 0.126292] PM: hibernation: Registered nosave memory: [mem 0x000a0000-0x000fffff] [ 0.126547] PM: hibernation: Registered nosave memory: [mem 0x00806000-0x00807fff] [ 0.126796] PM: hibernation: Registered nosave memory: [mem 0x00810000-0x008fffff] [ 0.127046] PM: hibernation: Registered nosave memory: [mem 0xbe587000-0xbe587fff] [ 0.127315] PM: hibernation: Registered nosave memory: [mem 0xbe5c1000-0xbe5c1fff] [ 0.127593] PM: hibernation: Registered nosave memory: [mem 0xbe5e8000-0xbe5e8fff] [ 0.127864] PM: hibernation: Registered nosave memory: [mem 0xbe5f1000-0xbe5f1fff] [ 0.128162] PM: hibernation: Registered nosave memory: [mem 0xbe640000-0xbe648fff] [ 0.128446] PM: hibernation: Registered nosave memory: [mem 0xbe934000-0xbe945fff] [ 0.128735] PM: hibernation: Registered nosave memory: [mem 0xbe946000-0xbe960fff] [ 0.128975] PM: hibernation: Registered nosave memory: [mem 0xbea6c000-0xbeb1afff] [ 0.129234] PM: hibernation: Registered nosave memory: [mem 0xbfb9b000-0xbfbf2fff] [ 0.129495] PM: hibernation: Registered nosave memory: [mem 0xbfbf3000-0xbfbfafff] [ 0.129757] PM: hibernation: Registered nosave memory: [mem 0xbfbfb000-0xbfbfefff] [ 0.130125] [mem 0xc0000000-0xffbfffff] available for PCI devices [ 0.130766] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1910969940391419 ns [ 0.141134] setup_percpu: NR_CPUS:64 nr_cpumask_bits:64 nr_cpu_ids:1 nr_node_ids:1 [ 0.147826] percpu: Embedded 53 pages/cpu s176472 r8192 d32424 u2097152 [ 0.150221] Built 1 zonelists, mobility grouping on. Total pages: 771412 [ 0.150451] Policy zone: DMA32 [ 0.150704] Kernel command line: bzImage64 earlyprintk=ttyS0,keep efi=debug [ 0.161459] Dentry cache hash table entries: 524288 (order: 10, 4194304 bytes, linear) [ 0.231164] Inode-cache hash table entries: 262144 (order: 9, 2097152 bytes, linear) [ 0.233207] mem auto-init: stack:off, heap alloc:off, heap free:off [ 0.253204] Memory: 3024044K/3142020K available (14340K kernel code, 1520K rwdata, 3304K rodata, 1184K init, 1112K bss, 117976K reserved, 0K cma-reserved) [ 0.257804] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1 [ 0.259019] Kernel/User page tables isolation: enabled [ 0.267142] rcu: Hierarchical RCU implementation. [ 0.267376] rcu: RCU event tracing is enabled. [ 0.267561] rcu: RCU restricting CPUs from NR_CPUS=64 to nr_cpu_ids=1. [ 0.267915] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies. [ 0.268225] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1 [ 0.270606] NR_IRQS: 4352, nr_irqs: 256, preallocated irqs: 16 [ 0.278938] random: get_random_bytes called from start_kernel+0x546/0x716 with crng_init=0 [ 0.281978] Console: colour dummy device 80x25 [ 0.285564] printk: console [tty0] enabled [ 0.286640] ACPI: Core revision 20200110 [ 0.290843] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns [ 0.294895] APIC: Switch to symmetric I/O mode setup [ 0.298636] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1 [ 0.304234] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x1fa41c1cc38, max_idle_ns: 440795210299 ns [ 0.305191] Calibrating delay loop (skipped), value calculated using timer frequency.. 4390.19 BogoMIPS (lpj=2195098) [ 0.305662] pid_max: default: 32768 minimum: 301 [ 0.311267] efi: EFI runtime memory map: [ 0.311460] efi: mem00: [Boot Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x0000000000000000-0x0000000000000fff] (0MB) [ 0.311881] efi: mem01: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000001000-0x000000000009ffff] (0MB) [ 0.312000] efi: mem02: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000100000-0x0000000000805fff] (7MB) [ 0.312431] efi: mem03: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000808000-0x000000000080ffff] (0MB) [ 0.312998] efi: mem04: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x0000000000900000-0x00000000013fffff] (11MB) [ 0.313425] efi: mem05: [Loader Data | | | | | | | | | |WB|WT|WC|UC] range=[0x0000000001400000-0x00000000033e5fff] (31MB) [ 0.313997] efi: mem06: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000033e6000-0x00000000b9d8dfff] (2921MB) [ 0.314431] efi: mem07: [Loader Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000b9d8e000-0x00000000bbf77fff] (33MB) [ 0.314998] efi: mem08: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bbf78000-0x00000000bbf97fff] (0MB) [ 0.315463] efi: mem09: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bbf98000-0x00000000be49bfff] (37MB) [ 0.315998] efi: mem10: [Loader Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be49c000-0x00000000be56dfff] (0MB) [ 0.316459] efi: mem11: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be56e000-0x00000000be586fff] (0MB) [ 0.316878] efi: mem12: [Loader Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be587000-0x00000000be5c1fff] (0MB) [ 0.316996] efi: mem13: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5c2000-0x00000000be5dffff] (0MB) [ 0.317402] efi: mem14: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5e0000-0x00000000be5e6fff] (0MB) [ 0.318015] efi: mem15: [Loader Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5e7000-0x00000000be5f7fff] (0MB) [ 0.318496] efi: mem16: [Boot Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000be5f8000-0x00000000be7ebfff] (1MB) [ 0.319015] efi: mem17: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be7ec000-0x00000000be933fff] (1MB) [ 0.319430] efi: mem18: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000be961000-0x00000000bea6bfff] (1MB) [ 0.319997] efi: mem19: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea6c000-0x00000000bea70fff] (0MB) [ 0.320423] efi: mem20: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea71000-0x00000000bea75fff] (0MB) [ 0.320997] efi: mem21: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea76000-0x00000000bea7afff] (0MB) [ 0.321425] efi: mem22: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea7b000-0x00000000bea7ffff] (0MB) [ 0.321843] efi: mem23: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea80000-0x00000000bea84fff] (0MB) [ 0.321998] efi: mem24: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea85000-0x00000000bea8bfff] (0MB) [ 0.322433] efi: mem25: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bea8c000-0x00000000beb1afff] (0MB) [ 0.322996] efi: mem26: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000beb1b000-0x00000000bfa1afff] (15MB) [ 0.323376] efi: mem27: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfa1b000-0x00000000bfb9afff] (1MB) [ 0.323997] efi: mem28: [Runtime Code |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfb9b000-0x00000000bfbcafff] (0MB) [ 0.324390] efi: mem29: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfbcb000-0x00000000bfbeefff] (0MB) [ 0.324754] efi: mem30: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfbff000-0x00000000bfdfffff] (2MB) [ 0.325020] efi: mem31: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe00000-0x00000000bfe89fff] (0MB) [ 0.325422] efi: mem32: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe8a000-0x00000000bfea9fff] (0MB) [ 0.326015] efi: mem33: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfeaa000-0x00000000bfeccfff] (0MB) [ 0.326457] efi: mem34: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfecd000-0x00000000bfed5fff] (0MB) [ 0.326997] efi: mem35: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfed6000-0x00000000bfef3fff] (0MB) [ 0.327436] efi: mem36: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfef4000-0x00000000bff77fff] (0MB) [ 0.327997] efi: mem37: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB) [ 0.334217] efi: memattr: Processing EFI Memory Attributes table: [ 0.334653] efi: memattr: 0x0000bea6c000-0x0000bea70fff [Runtime Data |RUN| | | |XP| | | | | | | | ] [ 0.335239] efi: memattr: 0x0000bea71000-0x0000bea71fff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.335761] efi: memattr: 0x0000bea72000-0x0000bea73fff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.336162] efi: memattr: 0x0000bea74000-0x0000bea75fff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.337072] efi: memattr: 0x0000bea76000-0x0000bea7afff [Runtime Data |RUN| | | |XP| | | | | | | | ] [ 0.337634] efi: memattr: 0x0000bea7b000-0x0000bea7bfff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.338127] efi: memattr: 0x0000bea7c000-0x0000bea7dfff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.338647] efi: memattr: 0x0000bea7e000-0x0000bea7ffff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.339136] efi: memattr: 0x0000bea80000-0x0000bea84fff [Runtime Data |RUN| | | |XP| | | | | | | | ] [ 0.339636] efi: memattr: 0x0000bea85000-0x0000bea85fff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.340117] efi: memattr: 0x0000bea86000-0x0000bea89fff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.341013] efi: memattr: 0x0000bea8a000-0x0000bea8bfff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.341511] efi: memattr: 0x0000bea8c000-0x0000beb1afff [Runtime Data |RUN| | | |XP| | | | | | | | ] [ 0.342163] efi: memattr: 0x0000bfb9b000-0x0000bfb9efff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.342682] efi: memattr: 0x0000bfb9f000-0x0000bfba1fff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.343138] efi: memattr: 0x0000bfba2000-0x0000bfba4fff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.343620] efi: memattr: 0x0000bfba5000-0x0000bfbaffff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.344164] efi: memattr: 0x0000bfbb0000-0x0000bfbb2fff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.344727] efi: memattr: 0x0000bfbb3000-0x0000bfbb5fff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.345118] efi: memattr: 0x0000bfbb6000-0x0000bfbb8fff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.346013] efi: memattr: 0x0000bfbb9000-0x0000bfbbbfff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.346548] efi: memattr: 0x0000bfbbc000-0x0000bfbbefff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.347122] efi: memattr: 0x0000bfbbf000-0x0000bfbc1fff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.347626] efi: memattr: 0x0000bfbc2000-0x0000bfbc4fff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.348138] efi: memattr: 0x0000bfbc5000-0x0000bfbc8fff [Runtime Code |RUN| | | | | | |RO| | | | | ] [ 0.348660] efi: memattr: 0x0000bfbc9000-0x0000bfbcafff [Runtime Code |RUN| | | |XP| | | | | | | | ] [ 0.349138] efi: memattr: 0x0000bfbcb000-0x0000bfbeefff [Runtime Data |RUN| | | |XP| | | | | | | | ] [ 0.349724] efi: memattr: 0x0000bfef4000-0x0000bff77fff [Runtime Data |RUN| | | |XP| | | | | | | | ] [ 0.350974] BUG: unable to handle page fault for address: 00000000a6403e90 [ 0.350974] #PF: supervisor read access in kernel mode [ 0.350974] #PF: error_code(0x0000) - not-present page [ 0.350974] PGD bd890063 P4D bd890063 PUD bd896063 PMD 0 [ 0.350974] Oops: 0000 [#1] SMP PTI [ 0.350974] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 5.6.0-rc3+ #3 [ 0.350974] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 0.0.0 02/06/2015 [ 0.350974] RIP: 0008:0xbfba558d [ 0.350974] Code: 53 52 e8 77 fd ff ff 8b 5d 08 85 db 75 1c 84 c0 74 18 50 68 71 d8 ba bf 68 ba 00 00 00 68 5c cd ba bf e8 09 ff ff ff 83 c4 10 <8b> 03 8b 53 04 8b 5d fc c9 c3 55 89 e5 57 56 53 83 ec 28 8b 5d 08 [ 0.350974] RSP: 0018:00000000bd8a0ed0 EFLAGS: 00000086 [ 0.350974] RAX: 00000000bfbcf001 RBX: 00000000a6403e90 RCX: 0000000000000001 [ 0.350974] RDX: 0000000011d293ca RSI: 00000000a600a370 RDI: 000000008be4df61 [ 0.350974] RBP: 00000000bd8a0ed8 R08: 0000000000000000 R09: 0000000000000000 [ 0.350974] R10: ffffffff92612840 R11: 0000000000000048 R12: ffffffff92600000 [ 0.350974] R13: 0000000000000000 R14: 00000000a600a370 R15: 0000000000000286 [ 0.350974] FS: 0000000000000000(0000) GS:ffff93c23e200000(0000) knlGS:0000000000000000 [ 0.350974] CS: 0008 DS: 0018 ES: 0018 CR0: 0000000080050033 [ 0.350974] CR2: 00000000a6403e90 CR3: 00000000bd8ca000 CR4: 00000000000406b0 [ 0.350974] Call Trace: [ 0.350974] Modules linked in: [ 0.350974] CR2: 00000000a6403e90 [ 0.350974] ---[ end trace 65970dab9fc6be95 ]--- [ 0.350974] RIP: 0008:0xbfba558d [ 0.350974] Code: 53 52 e8 77 fd ff ff 8b 5d 08 85 db 75 1c 84 c0 74 18 50 68 71 d8 ba bf 68 ba 00 00 00 68 5c cd ba bf e8 09 ff ff ff 83 c4 10 <8b> 03 8b 53 04 8b 5d fc c9 c3 55 89 e5 57 56 53 83 ec 28 8b 5d 08 [ 0.350974] RSP: 0018:00000000bd8a0ed0 EFLAGS: 00000086 [ 0.350974] RAX: 00000000bfbcf001 RBX: 00000000a6403e90 RCX: 0000000000000001 [ 0.350974] RDX: 0000000011d293ca RSI: 00000000a600a370 RDI: 000000008be4df61 [ 0.350974] RBP: 00000000bd8a0ed8 R08: 0000000000000000 R09: 0000000000000000 [ 0.350974] R10: ffffffff92612840 R11: 0000000000000048 R12: ffffffff92600000 [ 0.350974] R13: 0000000000000000 R14: 00000000a600a370 R15: 0000000000000286 [ 0.350974] FS: 0000000000000000(0000) GS:ffff93c23e200000(0000) knlGS:0000000000000000 [ 0.350974] CS: 0008 DS: 0018 ES: 0018 CR0: 0000000080050033 [ 0.350974] CR2: 00000000a6403e90 CR3: 00000000bd8ca000 CR4: 00000000000406b0 [ 0.350974] Kernel panic - not syncing: Attempted to kill the idle task! [ 0.350974] ---[ end Kernel panic - not syncing: Attempted to kill the idle task! ]---
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \
^^^^^^^
That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Ard Biesheuvel
maintainerQuoted 10 lines · Arvind Sankar
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \^^^^^^^That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Thanks for the patch. Interestingly, I don't even make it to the point where it crashes, and I end up in an ASSERT() in the firmware:
ASSERT_EFI_ERROR (Status = Not Found)
ASSERT /home/ardbie01/build/edk2/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c(347):
!EFI_ERROR (Status)
which appears to be a result of the fact that the memory map passed to SetVirtualAddressMap() does not cover some function pointer that gets converted in that code.
I don't remember - does mixed mode even work in general with 3 GB of memory?
Quoted 19 lines · Ard Biesheuvel
Quoted 10 lines · Arvind Sankar
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \^^^^^^^That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Thanks for the patch. Interestingly, I don't even make it to the point where it crashes, and I end up in an
ASSERT()in the firmware:
ASSERT_EFI_ERROR(Status = Not Found)
ASSERT /home/ardbie01/build/edk2/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c(347):
!EFI_ERROR (Status)
Quoted 5 lines
which appears to be a result of the fact that the memory map passed to
SetVirtualAddressMap()does not cover some function pointer that gets converted in that code.I don't remember - does mixed mode even work in general with 3 GB of memory?
Oh -- is there some option to enable debugging assertions? I did see that it crashed somewhere inside SetVirtualMap (i.e. we called it and it never returned).
For some reason, with nokaslr on the command line, I can't get this to crash. All the addresses seem to be within 4Gb, so it ought to work, no?
Ard Biesheuvel
maintainerQuoted 25 lines · Arvind Sankar
Quoted 23 lines · Ard Biesheuvel
Quoted 10 lines · Arvind Sankar
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \^^^^^^^That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Thanks for the patch. Interestingly, I don't even make it to the point where it crashes, and I end up in an
ASSERT()in the firmware:
ASSERT_EFI_ERROR(Status = Not Found)
ASSERT /home/ardbie01/build/edk2/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c(347):
!EFI_ERROR (Status)which appears to be a result of the fact that the memory map passed to
SetVirtualAddressMap()does not cover some function pointer that gets converted in that code.
Quoted 6 lines
Quoted 1 line
I don't remember - does mixed mode even work in general with 3 GB of memory?
Oh -- is there some option to enable debugging assertions? I did see that it crashed somewhere inside SetVirtualMap (i.e. we called it and it never returned).
The ASSERT()s are always active, but you don't see them if you don't expose the debugcon
Quoted 2 lines
For some reason, with nokaslr on the command line, I can't get this to crash. All the addresses seem to be within 4Gb, so it ought to work, no?
The issue is in the memory map we compile and send back to the firware
- apparently, that ends up wrong for some reason.
Ard Biesheuvel
maintainerQuoted 34 lines · Ard Biesheuvel
Quoted 25 lines · Arvind Sankar
Quoted 23 lines · Ard Biesheuvel
Quoted 10 lines · Arvind Sankar
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \^^^^^^^That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Thanks for the patch. Interestingly, I don't even make it to the point where it crashes, and I end up in an
ASSERT()in the firmware:
ASSERT_EFI_ERROR(Status = Not Found)
ASSERT /home/ardbie01/build/edk2/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c(347):
!EFI_ERROR (Status)which appears to be a result of the fact that the memory map passed to
SetVirtualAddressMap()does not cover some function pointer that gets converted in that code.Quoted 6 lines
Quoted 1 line
I don't remember - does mixed mode even work in general with 3 GB of memory?
Oh -- is there some option to enable debugging assertions? I did see that it crashed somewhere inside SetVirtualMap (i.e. we called it and it never returned).
Quoted 8 lines
The ASSERT()s are always active, but you don't see them if you don't expose the debugcon
Quoted 2 lines
For some reason, with nokaslr on the command line, I can't get this to crash. All the addresses seem to be within 4Gb, so it ought to work, no?
The issue is in the memory map we compile and send back to the firware
- apparently, that ends up wrong for some reason.
BTW I uploaded another version which uses Loadimage/Startimage (and the .compat section) for mixed mode kernels passed to QEMU via the command line
https://people.linaro.org/~ard.biesheuvel/OVMF-mixed-mode-compat-section-cmdline.fd
Ard Biesheuvel
maintainerQuoted 42 lines · Ard Biesheuvel
Quoted 40 lines · Ard Biesheuvel
Quoted 25 lines · Arvind Sankar
Quoted 23 lines · Ard Biesheuvel
Quoted 10 lines · Arvind Sankar
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \^^^^^^^That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Thanks for the patch. Interestingly, I don't even make it to the point where it crashes, and I end up in an
ASSERT()in the firmware:
ASSERT_EFI_ERROR(Status = Not Found)
ASSERT /home/ardbie01/build/edk2/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c(347):
!EFI_ERROR (Status)which appears to be a result of the fact that the memory map passed to
SetVirtualAddressMap()does not cover some function pointer that gets converted in that code.Quoted 6 lines
Quoted 1 line
I don't remember - does mixed mode even work in general with 3 GB of memory?
Oh -- is there some option to enable debugging assertions? I did see that it crashed somewhere inside SetVirtualMap (i.e. we called it and it never returned).
The ASSERT()s are always active, but you don't see them if you don't expose the debugcon
Quoted 2 lines
For some reason, with nokaslr on the command line, I can't get this to crash. All the addresses seem to be within 4Gb, so it ought to work, no?
Quoted 8 lines
Quoted 2 lines
The issue is in the memory map we compile and send back to the firware
- apparently, that ends up wrong for some reason.BTW I uploaded another version which uses Loadimage/Startimage (and the .compat section) for mixed mode kernels passed to QEMU via the command line
https://people.linaro.org/~ard.biesheuvel/OVMF-mixed-mode-compat-section-cmdline.fd
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff]
(1024MB)
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Quoted 52 lines · Ard Biesheuvel
Quoted 42 lines · Ard Biesheuvel
Quoted 40 lines · Ard Biesheuvel
Quoted 25 lines · Arvind Sankar
Quoted 23 lines · Ard Biesheuvel
Quoted 10 lines · Arvind Sankar
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \^^^^^^^That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Thanks for the patch. Interestingly, I don't even make it to the point where it crashes, and I end up in an
ASSERT()in the firmware:
ASSERT_EFI_ERROR(Status = Not Found)
ASSERT /home/ardbie01/build/edk2/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c(347):
!EFI_ERROR (Status)which appears to be a result of the fact that the memory map passed to
SetVirtualAddressMap()does not cover some function pointer that gets converted in that code.Quoted 6 lines
Quoted 1 line
I don't remember - does mixed mode even work in general with 3 GB of memory?
Oh -- is there some option to enable debugging assertions? I did see that it crashed somewhere inside SetVirtualMap (i.e. we called it and it never returned).
The ASSERT()s are always active, but you don't see them if you don't expose the debugcon
Quoted 2 lines
For some reason, with nokaslr on the command line, I can't get this to crash. All the addresses seem to be within 4Gb, so it ought to work, no?
Quoted 8 lines
Quoted 2 lines
The issue is in the memory map we compile and send back to the firware
- apparently, that ends up wrong for some reason.BTW I uploaded another version which uses Loadimage/Startimage (and the .compat section) for mixed mode kernels passed to QEMU via the command line
https://people.linaro.org/~ard.biesheuvel/OVMF-mixed-mode-compat-section-cmdline.fd
Quoted 8 lines
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff](1024MB)
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Mine ended here:
[ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)
are you running with -m 3072 or more?
If you get memory mapped above 4Gb you will almost certainly crash in the call to SetVirtualMemoryMap, but that's usually because the memmap you pass in is above 4Gb and can't be accessed by the firmware at all.
Ard Biesheuvel
maintainerQuoted 60 lines · Arvind Sankar
Quoted 58 lines · Ard Biesheuvel
Quoted 42 lines · Ard Biesheuvel
Quoted 40 lines · Ard Biesheuvel
Quoted 25 lines · Arvind Sankar
Quoted 23 lines · Ard Biesheuvel
Quoted 10 lines · Arvind Sankar
Quoted 4 lines · Arvind Sankar
What I'm doing is creating an x86-64 defconfig based on tip:efi/core, and then running it via
$ qemu-system-x86_64 -cpu Haswell -pflash qemu/OVMF_64.fd \^^^^^^^That OVMF_64.fd is incorrect copy/paste from a different run, the panic case is using OVMF-mixed-mode-compat-section.fd.
Quoted 1 line
-drive file=fat:rw:qemu/boot -nographic -m 3072
Thanks for the patch. Interestingly, I don't even make it to the point where it crashes, and I end up in an
ASSERT()in the firmware:
ASSERT_EFI_ERROR(Status = Not Found)
ASSERT /home/ardbie01/build/edk2/MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.c(347):
!EFI_ERROR (Status)which appears to be a result of the fact that the memory map passed to
SetVirtualAddressMap()does not cover some function pointer that gets converted in that code.Quoted 6 lines
Quoted 1 line
I don't remember - does mixed mode even work in general with 3 GB of memory?
Oh -- is there some option to enable debugging assertions? I did see that it crashed somewhere inside SetVirtualMap (i.e. we called it and it never returned).
The ASSERT()s are always active, but you don't see them if you don't expose the debugcon
Quoted 2 lines
For some reason, with nokaslr on the command line, I can't get this to crash. All the addresses seem to be within 4Gb, so it ought to work, no?
Quoted 8 lines
Quoted 2 lines
The issue is in the memory map we compile and send back to the firware
- apparently, that ends up wrong for some reason.BTW I uploaded another version which uses Loadimage/Startimage (and the .compat section) for mixed mode kernels passed to QEMU via the command line
https://people.linaro.org/~ard.biesheuvel/OVMF-mixed-mode-compat-section-cmdline.fd
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff](1024MB)
Quoted 7 lines
Quoted 2 lines
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Mine ended here:
[ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)are you running with -m 3072 or more?
That is not memory, it's some mmio region
Quoted 3 lines
If you get memory mapped above 4Gb you will almost certainly crash in the call to SetVirtualMemoryMap, but that's usually because the memmap you pass in is above 4Gb and can't be accessed by the firmware at all.
Quoted 10 lines · Ard Biesheuvel
Quoted 9 lines · Arvind Sankar
Quoted 8 lines
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff](1024MB)
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Quoted 7 lines
Quoted 4 lines
Mine ended here:
[ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)are you running with -m 3072 or more?
That is not memory, it's some mmio region
Right, but it's the last (highest) range in my memory map. It was just to illustrate that I have no addresses above 4Gb, unlike the mapping you got, although I now see that the MMIO range is the last one printed regardless of where RAM ends, so that wasn't quite enough. I only get the 4g-5g mapping range if I run it with -m 4096.
This is the tail end of the mapping I got.
[ 0.000000] efi: mem38: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe00000-0x00000000bfe89fff] (0MB) [ 0.000000] efi: mem39: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe8a000-0x00000000bfea9fff] (0MB) [ 0.000000] efi: mem40: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfeaa000-0x00000000bfeccfff] (0MB) [ 0.000000] efi: mem41: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfecd000-0x00000000bfed5fff] (0MB) [ 0.000000] efi: mem42: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfed6000-0x00000000bfef3fff] (0MB) [ 0.000000] efi: mem43: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfef4000-0x00000000bff77fff] (0MB) [ 0.000000] efi: mem44: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bff78000-0x00000000bfffffff] (0MB) [ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)
Ard Biesheuvel
maintainerQuoted 28 lines · Arvind Sankar
Quoted 10 lines · Ard Biesheuvel
Quoted 9 lines · Arvind Sankar
Quoted 8 lines
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff](1024MB)
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Quoted 7 lines
Quoted 4 lines
Mine ended here:
[ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)are you running with -m 3072 or more?
That is not memory, it's some mmio region
Right, but it's the last (highest) range in my memory map. It was just to illustrate that I have no addresses above 4Gb, unlike the mapping you got, although I now see that the MMIO range is the last one printed regardless of where RAM ends, so that wasn't quite enough. I only get the 4g-5g mapping range if I run it with -m 4096.
This is the tail end of the mapping I got.
Quoted 8 lines
[ 0.000000] efi: mem38: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe00000-0x00000000bfe89fff] (0MB) [ 0.000000] efi: mem39: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe8a000-0x00000000bfea9fff] (0MB) [ 0.000000] efi: mem40: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfeaa000-0x00000000bfeccfff] (0MB) [ 0.000000] efi: mem41: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfecd000-0x00000000bfed5fff] (0MB) [ 0.000000] efi: mem42: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfed6000-0x00000000bfef3fff] (0MB) [ 0.000000] efi: mem43: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfef4000-0x00000000bff77fff] (0MB) [ 0.000000] efi: mem44: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bff78000-0x00000000bfffffff] (0MB) [ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)
Looks like it's the difference in machine type - I was using q35, and when I switch to the default, I can reproduce the early boot crash you sent the patch for. I don't see the other issue though.
Quoted 38 lines · Ard Biesheuvel
Quoted 28 lines · Arvind Sankar
Quoted 10 lines · Ard Biesheuvel
Quoted 9 lines · Arvind Sankar
Quoted 8 lines
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff](1024MB)
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Quoted 7 lines
Quoted 4 lines
Mine ended here:
[ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)are you running with -m 3072 or more?
That is not memory, it's some mmio region
Right, but it's the last (highest) range in my memory map. It was just to illustrate that I have no addresses above 4Gb, unlike the mapping you got, although I now see that the MMIO range is the last one printed regardless of where RAM ends, so that wasn't quite enough. I only get the 4g-5g mapping range if I run it with -m 4096.
This is the tail end of the mapping I got.
Quoted 8 lines
[ 0.000000] efi: mem38: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe00000-0x00000000bfe89fff] (0MB) [ 0.000000] efi: mem39: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe8a000-0x00000000bfea9fff] (0MB) [ 0.000000] efi: mem40: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfeaa000-0x00000000bfeccfff] (0MB) [ 0.000000] efi: mem41: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfecd000-0x00000000bfed5fff] (0MB) [ 0.000000] efi: mem42: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfed6000-0x00000000bfef3fff] (0MB) [ 0.000000] efi: mem43: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfef4000-0x00000000bff77fff] (0MB) [ 0.000000] efi: mem44: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bff78000-0x00000000bfffffff] (0MB) [ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)
Quoted 3 lines
Looks like it's the difference in machine type - I was using q35, and when I switch to the default, I can reproduce the early boot crash you sent the patch for. I don't see the other issue though.
So you can boot successfully without hanging in SetVirtualAddressMap? Weird. I'm using QEMU 4.2.0 in case that matters.
Ard Biesheuvel
maintainerQuoted 40 lines · Arvind Sankar
Quoted 38 lines · Ard Biesheuvel
Quoted 36 lines · Arvind Sankar
Quoted 10 lines · Ard Biesheuvel
Quoted 9 lines · Arvind Sankar
Quoted 8 lines
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff](1024MB)
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Quoted 7 lines
Quoted 4 lines
Mine ended here:
[ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)are you running with -m 3072 or more?
That is not memory, it's some mmio region
Right, but it's the last (highest) range in my memory map. It was just to illustrate that I have no addresses above 4Gb, unlike the mapping you got, although I now see that the MMIO range is the last one printed regardless of where RAM ends, so that wasn't quite enough. I only get the 4g-5g mapping range if I run it with -m 4096.
This is the tail end of the mapping I got.
[ 0.000000] efi: mem38: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe00000-0x00000000bfe89fff] (0MB) [ 0.000000] efi: mem39: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe8a000-0x00000000bfea9fff] (0MB) [ 0.000000] efi: mem40: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfeaa000-0x00000000bfeccfff] (0MB) [ 0.000000] efi: mem41: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfecd000-0x00000000bfed5fff] (0MB) [ 0.000000] efi: mem42: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfed6000-0x00000000bfef3fff] (0MB) [ 0.000000] efi: mem43: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfef4000-0x00000000bff77fff] (0MB) [ 0.000000] efi: mem44: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bff78000-0x00000000bfffffff] (0MB) [ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)
Quoted 6 lines
Quoted 3 lines
Looks like it's the difference in machine type - I was using q35, and when I switch to the default, I can reproduce the early boot crash you sent the patch for. I don't see the other issue though.
So you can boot successfully without hanging in SetVirtualAddressMap? Weird. I'm using QEMU 4.2.0 in case that matters.
Mine is 2.11, as shipped with my Ubuntu Bionic installation (company laptop)
Quoted 41 lines · Ard Biesheuvel
Quoted 40 lines · Arvind Sankar
Quoted 38 lines · Ard Biesheuvel
Quoted 36 lines · Arvind Sankar
Quoted 10 lines · Ard Biesheuvel
Quoted 9 lines · Arvind Sankar
Quoted 8 lines
I see this in the memory map
[ 0.000000] efi: mem47: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x0000000100000000-0x000000013fffffff](1024MB)
so it looks like qemu-system-x86_64 puts the memory in a weird place? Or is this expected?
Quoted 7 lines
Quoted 4 lines
Mine ended here:
[ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)are you running with -m 3072 or more?
That is not memory, it's some mmio region
Right, but it's the last (highest) range in my memory map. It was just to illustrate that I have no addresses above 4Gb, unlike the mapping you got, although I now see that the MMIO range is the last one printed regardless of where RAM ends, so that wasn't quite enough. I only get the 4g-5g mapping range if I run it with -m 4096.
This is the tail end of the mapping I got.
[ 0.000000] efi: mem38: [Conventional Memory| | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe00000-0x00000000bfe89fff] (0MB) [ 0.000000] efi: mem39: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfe8a000-0x00000000bfea9fff] (0MB) [ 0.000000] efi: mem40: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfeaa000-0x00000000bfeccfff] (0MB) [ 0.000000] efi: mem41: [Boot Data | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfecd000-0x00000000bfed5fff] (0MB) [ 0.000000] efi: mem42: [Boot Code | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfed6000-0x00000000bfef3fff] (0MB) [ 0.000000] efi: mem43: [Runtime Data |RUN| | | | | | | | |WB|WT|WC|UC] range=[0x00000000bfef4000-0x00000000bff77fff] (0MB) [ 0.000000] efi: mem44: [ACPI Memory NVS | | | | | | | | | |WB|WT|WC|UC] range=[0x00000000bff78000-0x00000000bfffffff] (0MB) [ 0.000000] efi: mem45: [Memory Mapped I/O |RUN| | | | | | | | | | | |UC] range=[0x00000000ffc00000-0x00000000ffffffff] (4MB)
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
Looks like it's the difference in machine type - I was using q35, and when I switch to the default, I can reproduce the early boot crash you sent the patch for. I don't see the other issue though.
So you can boot successfully without hanging in SetVirtualAddressMap? Weird. I'm using QEMU 4.2.0 in case that matters.
Mine is 2.11, as shipped with my Ubuntu Bionic installation (company laptop)
I think I've located the problem. kernel_map_pages_in_pgd has a bug, when gb pages are not enabled, it can sometimes not actually map the pages it claims to have mapped. The below fixes it, I'll post some patches tomorrow to clean it up.
arch/x86/mm/pat/set_memory.c +13 -4
@@ -1370,12 +1370,21 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, p4d_t *p4d,/* * Map everything starting from the Gb boundary, possibly with 1G pages */ -while (boot_cpu_has (X86_FEATURE_GBPAGES ) && end - start >=PUD_SIZE ) { -set_pud (pud,pud_mkhuge (pfn_pud (cpa->pfn, -canon_pgprot (pud_pgprot)))); +while (end - start >=PUD_SIZE ) { +if (boot_cpu_has (X86_FEATURE_GBPAGES )) { +set_pud (pud,pud_mkhuge (pfn_pud (cpa->pfn, +canon_pgprot (pud_pgprot)))); + cpa->pfn +=PUD_SIZE >>PAGE_SHIFT ; + }else { +if (pud_none (*pud)) +if (alloc_pmd_page (pud)) +return -1 ; +if (populate_pmd (cpa, start, start +PUD_SIZE , +PUD_SIZE >>PAGE_SHIFT , pud, pgprot) <0 ) +return cur_pages; + } start +=PUD_SIZE ; - cpa->pfn +=PUD_SIZE >>PAGE_SHIFT ; cur_pages +=PUD_SIZE >>PAGE_SHIFT ; pud++; }