mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
efi: Allow drivers to reserve boot services forever
Today, it is not possible for drivers to reserve EFI boot services for access after efi_free_boot_services() has been called on x86. For ARM/arm64 it can be done simply by calling memblock_reserve(). Having this ability for all three architectures is desirable for a couple of reasons, 1) It saves drivers copying data out of those regions 2) kexec reboot can now make use of things like ESRT Instead of using the standard memblock_reserve() which is insufficient to reserve the region on x86 (see efi_reserve_boot_services()), a new API is introduced in this patch; efi_mem_reserve(). efi.memmap now always represents which EFI memory regions are available. On x86 the EFI boot services regions that have not been reserved via efi_mem_reserve() will be removed from efi.memmap during efi_free_boot_services(). This has implications for kexec, since it is not possible for a newly kexec'd kernel to access the same boot services regions that the initial boot kernel had access to unless they are reserved by every kexec kernel in the chain. Tested-by: Dave Young <[email protected]> [kexec/kdump] Tested-by: Ard Biesheuvel <[email protected]> [arm] Acked-by: Ard Biesheuvel <[email protected]> Cc: Leif Lindholm <[email protected]> Cc: Peter Jones <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Mark Rutland <[email protected]> Signed-off-by: Matt Fleming <[email protected]>
This commit is contained in:
parent
c45f4da33a
commit
816e76129e
3 changed files with 141 additions and 11 deletions
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/ucs2_string.h>
|
||||
#include <linux/memblock.h>
|
||||
|
||||
#include <asm/early_ioremap.h>
|
||||
|
||||
|
|
@ -396,6 +397,35 @@ u64 __init efi_mem_desc_end(efi_memory_desc_t *md)
|
|||
return end;
|
||||
}
|
||||
|
||||
void __init __weak efi_arch_mem_reserve(phys_addr_t addr, u64 size) {}
|
||||
|
||||
/**
|
||||
* efi_mem_reserve - Reserve an EFI memory region
|
||||
* @addr: Physical address to reserve
|
||||
* @size: Size of reservation
|
||||
*
|
||||
* Mark a region as reserved from general kernel allocation and
|
||||
* prevent it being released by efi_free_boot_services().
|
||||
*
|
||||
* This function should be called drivers once they've parsed EFI
|
||||
* configuration tables to figure out where their data lives, e.g.
|
||||
* efi_esrt_init().
|
||||
*/
|
||||
void __init efi_mem_reserve(phys_addr_t addr, u64 size)
|
||||
{
|
||||
if (!memblock_is_region_reserved(addr, size))
|
||||
memblock_reserve(addr, size);
|
||||
|
||||
/*
|
||||
* Some architectures (x86) reserve all boot services ranges
|
||||
* until efi_free_boot_services() because of buggy firmware
|
||||
* implementations. This means the above memblock_reserve() is
|
||||
* superfluous on x86 and instead what it needs to do is
|
||||
* ensure the @start, @size is not freed.
|
||||
*/
|
||||
efi_arch_mem_reserve(addr, size);
|
||||
}
|
||||
|
||||
static __initdata efi_config_table_type_t common_tables[] = {
|
||||
{ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
|
||||
{ACPI_TABLE_GUID, "ACPI", &efi.acpi},
|
||||
|
|
|
|||
Loading…
Reference in a new issue