Skip to content

Commit 8dbe339

Browse files
kirylardbiesheuvel
authored andcommitted
efi/unaccepted: Make sure unaccepted table is mapped
Unaccepted table is now allocated from EFI_ACPI_RECLAIM_MEMORY. It translates into E820_TYPE_ACPI, which is not added to memblock and therefore not mapped in the direct mapping. This causes a crash on the first touch of the table. Use memblock_add() to make sure that the table is mapped in direct mapping. Align the range to the nearest page borders. Ranges smaller than page size are not mapped. Fixes: e7761d8 ("efi/unaccepted: Use ACPI reclaim memory for unaccepted memory table") Reported-by: Hongyu Ning <hongyu.ning@intel.com> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
1 parent 79b8360 commit 8dbe339

File tree

1 file changed

+29
-3
lines changed
  • drivers/firmware/efi

1 file changed

+29
-3
lines changed

drivers/firmware/efi/efi.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,34 @@ static __init int match_config_table(const efi_guid_t *guid,
623623
return 0;
624624
}
625625

626+
/**
627+
* reserve_unaccepted - Map and reserve unaccepted configuration table
628+
* @unaccepted: Pointer to unaccepted memory table
629+
*
630+
* memblock_add() makes sure that the table is mapped in direct mapping. During
631+
* normal boot it happens automatically because the table is allocated from
632+
* usable memory. But during crashkernel boot only memory specifically reserved
633+
* for crash scenario is mapped. memblock_add() forces the table to be mapped
634+
* in crashkernel case.
635+
*
636+
* Align the range to the nearest page borders. Ranges smaller than page size
637+
* are not going to be mapped.
638+
*
639+
* memblock_reserve() makes sure that future allocations will not touch the
640+
* table.
641+
*/
642+
643+
static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
644+
{
645+
phys_addr_t start, size;
646+
647+
start = PAGE_ALIGN_DOWN(efi.unaccepted);
648+
size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
649+
650+
memblock_add(start, size);
651+
memblock_reserve(start, size);
652+
}
653+
626654
int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
627655
int count,
628656
const efi_config_table_type_t *arch_tables)
@@ -751,11 +779,9 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
751779

752780
unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted));
753781
if (unaccepted) {
754-
unsigned long size;
755782

756783
if (unaccepted->version == 1) {
757-
size = sizeof(*unaccepted) + unaccepted->size;
758-
memblock_reserve(efi.unaccepted, size);
784+
reserve_unaccepted(unaccepted);
759785
} else {
760786
efi.unaccepted = EFI_INVALID_TABLE_ADDR;
761787
}

0 commit comments

Comments
 (0)