Skip to content

Commit 50d7cdf

Browse files
committed
efi/x86: Avoid physical KASLR on older Dell systems
River reports boot hangs with v6.6 and v6.7, and the bisect points to commit a1b87d5 ("x86/efistub: Avoid legacy decompressor when doing EFI boot") which moves the memory allocation and kernel decompression from the legacy decompressor (which executes *after* ExitBootServices()) to the EFI stub, using boot services for allocating the memory. The memory allocation succeeds but the subsequent call to decompress_kernel() never returns, resulting in a failed boot and a hanging system. As it turns out, this issue only occurs when physical address randomization (KASLR) is enabled, and given that this is a feature we can live without (virtual KASLR is much more important), let's disable the physical part of KASLR when booting on AMI UEFI firmware claiming to implement revision v2.0 of the specification (which was released in 2006), as this is the version these systems advertise. Fixes: a1b87d5 ("x86/efistub: Avoid legacy decompressor when doing EFI boot") Closes: https://bugzilla.kernel.org/show_bug.cgi?id=218173 Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 271f2a4 commit 50d7cdf

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

drivers/firmware/efi/libstub/x86-stub.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,17 +307,20 @@ static void setup_unaccepted_memory(void)
307307
efi_err("Memory acceptance protocol failed\n");
308308
}
309309

310+
static efi_char16_t *efistub_fw_vendor(void)
311+
{
312+
unsigned long vendor = efi_table_attr(efi_system_table, fw_vendor);
313+
314+
return (efi_char16_t *)vendor;
315+
}
316+
310317
static const efi_char16_t apple[] = L"Apple";
311318

312319
static void setup_quirks(struct boot_params *boot_params)
313320
{
314-
efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long)
315-
efi_table_attr(efi_system_table, fw_vendor);
316-
317-
if (!memcmp(fw_vendor, apple, sizeof(apple))) {
318-
if (IS_ENABLED(CONFIG_APPLE_PROPERTIES))
319-
retrieve_apple_device_properties(boot_params);
320-
}
321+
if (IS_ENABLED(CONFIG_APPLE_PROPERTIES) &&
322+
!memcmp(efistub_fw_vendor(), apple, sizeof(apple)))
323+
retrieve_apple_device_properties(boot_params);
321324
}
322325

323326
/*
@@ -765,11 +768,25 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry)
765768

766769
if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && !efi_nokaslr) {
767770
u64 range = KERNEL_IMAGE_SIZE - LOAD_PHYSICAL_ADDR - kernel_total_size;
771+
static const efi_char16_t ami[] = L"American Megatrends";
768772

769773
efi_get_seed(seed, sizeof(seed));
770774

771775
virt_addr += (range * seed[1]) >> 32;
772776
virt_addr &= ~(CONFIG_PHYSICAL_ALIGN - 1);
777+
778+
/*
779+
* Older Dell systems with AMI UEFI firmware v2.0 may hang
780+
* while decompressing the kernel if physical address
781+
* randomization is enabled.
782+
*
783+
* https://bugzilla.kernel.org/show_bug.cgi?id=218173
784+
*/
785+
if (efi_system_table->hdr.revision <= EFI_2_00_SYSTEM_TABLE_REVISION &&
786+
!memcmp(efistub_fw_vendor(), ami, sizeof(ami))) {
787+
efi_debug("AMI firmware v2.0 or older detected - disabling physical KASLR\n");
788+
seed[0] = 0;
789+
}
773790
}
774791

775792
status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr,

0 commit comments

Comments
 (0)