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: e7761d827e
("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>
This commit is contained in:
parent
79b83606ab
commit
8dbe33956d
|
@ -623,6 +623,34 @@ static __init int match_config_table(const efi_guid_t *guid,
|
|||
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 count,
|
||||
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,
|
|||
|
||||
unaccepted = early_memremap(efi.unaccepted, sizeof(*unaccepted));
|
||||
if (unaccepted) {
|
||||
unsigned long size;
|
||||
|
||||
if (unaccepted->version == 1) {
|
||||
size = sizeof(*unaccepted) + unaccepted->size;
|
||||
memblock_reserve(efi.unaccepted, size);
|
||||
reserve_unaccepted(unaccepted);
|
||||
} else {
|
||||
efi.unaccepted = EFI_INVALID_TABLE_ADDR;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue