Commit 8dbe3395 authored by Kirill A. Shutemov's avatar Kirill A. Shutemov Committed by Ard Biesheuvel

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: e7761d82 ("efi/unaccepted: Use ACPI reclaim memory for unaccepted memory table")
Reported-by: default avatarHongyu Ning <hongyu.ning@intel.com>
Signed-off-by: default avatarKirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
parent 79b83606
...@@ -623,6 +623,34 @@ static __init int match_config_table(const efi_guid_t *guid, ...@@ -623,6 +623,34 @@ static __init int match_config_table(const efi_guid_t *guid,
return 0; return 0;
} }
/**
* reserve_unaccepted - Map and reserve unaccepted configuration table
* @unaccepted: Pointer to unaccepted memory table
*
* memblock_add() makes sure that the table is mapped in direct mapping. During
* normal boot it happens automatically because the table is allocated from
* usable memory. But during crashkernel boot only memory specifically reserved
* for crash scenario is mapped. memblock_add() forces the table to be mapped
* in crashkernel case.
*
* Align the range to the nearest page borders. Ranges smaller than page size
* are not going to be mapped.
*
* memblock_reserve() makes sure that future allocations will not touch the
* table.
*/
static __init void reserve_unaccepted(struct efi_unaccepted_memory *unaccepted)
{
phys_addr_t start, size;
start = PAGE_ALIGN_DOWN(efi.unaccepted);
size = PAGE_ALIGN(sizeof(*unaccepted) + unaccepted->size);
memblock_add(start, size);
memblock_reserve(start, size);
}
int __init efi_config_parse_tables(const efi_config_table_t *config_tables, int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
int count, int count,
const efi_config_table_type_t *arch_tables) 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, ...@@ -751,11 +779,9 @@ int __init efi_config_parse_tables(const efi_config_table_t *config_tables,
unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted)); unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted));
if (unaccepted) { if (unaccepted) {
unsigned long size;
if (unaccepted->version == 1) { if (unaccepted->version == 1) {
size = sizeof(*unaccepted) + unaccepted->size; reserve_unaccepted(unaccepted);
memblock_reserve(efi.unaccepted, size);
} else { } else {
efi.unaccepted = EFI_INVALID_TABLE_ADDR; efi.unaccepted = EFI_INVALID_TABLE_ADDR;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment