I've opened a bug to report further investigations and had some success
by implementing and calling EFI's GetNextMonotonicCount() via
get_next_monotonic_count() **immediately after** calling
exit_boot_services - which makes absolutely no sense but is now reliably
starting Linux although that fails in other ways which I'm working through.
https://bugzilla.kernel.org/show_bug.cgi?id=216375
On 19/08/2022 08:22, Ard Biesheuvel wrote:
(cc Steve - not sure who else still works on this stuff these days)
On Thu, 18 Aug 2022 at 13:00, Tj <linux@xxxxxx> wrote:
I've been diagnosing a failure to boot on a Samsung Galaxy Book2 (W737)
but have not been able to get the kernel to boot, and would welcome some
assistance:
EFI stub: ERROR: Exit boot services failed
The problem occurs in
drivers/firmware/efi/libstub/efi-stub-helper.c::efi_exit_boot_services().
EFI_INVALID_PARAMETER is returned by efi_bs_call(exit_boot_services...).
Based on reading the EDK source I suspected either the key was changing
or memory alignment is wrong based on a reading of EDK's
CoreExitBootServices() and CoreTerminateMemoryMap() - making a large
assumption that Lenovo/Aptio (American Megatrends) firmware is based
around EDK.
Since the addition of commit d4b341269efb3 "arm64: dts: qcom: Add
support for Samsung Galaxy Book2" I had inferred it is now possible to
boot this device into Linux, but so far it seems not.
I added extensive efi_debug() logging to try to identify the problem and
have reported the patches I'm using and results extensively (too
extensively for including in this email) at "Issue #11: Samsung Galaxy
Book2 (SM-W737Y) snapdragon 850" of the aarch64-laptops project:
https://github.com/aarch64-laptops/debian-cdimage/issues/11
Looking at your adventures, it seems you are looking for something
that the EFI stub in Linux is doing wrong, causing the
ExitBootServices() call to fail.
One thing to be aware of is that vendors of such hardware don't care
about EFI compliance, and rarely run the certification tests or turn
up for plugfests, etc. They only care about the Windows Logo sticker,
which is a lower bar in terms of EFI compatibility, and apparently,
their buggy firmware manages to boot Windows fine.
One thing you could try is setting the TPL level to TPL_HIGH before
calling exit_boot_services (or just disable interrupts). That way,
your first call is more likely to succeed, as nothing that could
change the memory map could run in the meantime.
The latest results show:
EFI stub: Booting Linux Kernel...
EFI stub: Using DTB from configuration table
EFI stub: DEBUG: Entering allocate_new_fdt_and_exit_boot()
EFI stub: Exiting boot services...
EFI stub: DEBUG: Calling efi_exit_boot_services() with map:
EFI stub: DEBUG: efi_boot_memmap = {map=0x000000009ffce870
map_size=0xa20 desc_size=0x30 desc_ver=0x1
key_ptr=0x000000009ffce868 *key_ptr=0x2b2c buff_size=0xc90 }
EFI stub: DEBUG: Entered efi_exit_boot_services()
EFI stub: DEBUG: Memory map before calling priv_func():
EFI stub: DEBUG: efi_boot_memmap = {map=0x000000009ffce870
map_size=0xa20 desc_size=0x30 desc_ver=0x1
key_ptr=0x000000009ffce868 *key_ptr=0x2b2c buff_size=0xc90 }
EFI stub: DEBUG: Memory map after calling priv_func():
EFI stub: DEBUG: efi_boot_memmap = {map=0x000000009ffce870
map_size=0xa20 desc_size=0x30 desc_ver=0x1
key_ptr=0x000000009ffce868 *key_ptr=0x2b2c buff_size=0xc90 }
EFI stub: DEBUG: Calling efi_bs_call(exit_boot_services,
0x00000000fcb87c98, 0x2b2c)
EFI stub: DEBUG: efi_bs_call() returned -9223372036854775806
(EFI_INVALID_PARAMETER)
EFI stub: DEBUG: Calling efi_bs_call() with get_memory_map
EFI stub: DEBUG: Memory map after calling get_memory_map() again:
EFI stub: DEBUG: efi_boot_memmap = {map=0x000000009ffce870
map_size=0xa20 desc_size=0x30 desc_ver=0x1
key_ptr=0x000000009ffce868 *key_ptr=0x2b6e buff_size=0xc90 }
EFI stub: DEBUG: Calling priv_func() again
EFI stub: DEBUG: Memory map after calling priv_func() again:
EFI stub: DEBUG: efi_boot_memmap = {map=0x000000009ffce870
map_size=0xa20 desc_size=0x30 desc_ver=0x1
key_ptr=0x000000009ffce868 *key_ptr=0x2b6e buff_size=0xc90 }
EFI stub: DEBUG: Calling (again!) efi_bs_call(exit_boot_services,
0x00000000fcb87c98, 0x2b6e)
EFI stub: DEBUG: fail: efi_exit_boot_services() returns -9223372036854775806
EFI stub: DEBUG: Returned from efi_Exit_boot_services()
EFI stub: ERROR: Exit boot services failed.
EFI stub: DEBUG: fail_free_new_fdt: status= -9223372036854775806
EFI stub: DEBUG: fail: status= -9223372036854775806
EFI stub: DEBUG: Busy Wait so you can read the debug messages!