Commit a23d3bb0 authored by Ard Biesheuvel's avatar Ard Biesheuvel

efi: add API to reserve memory persistently across kexec reboot

Add kernel plumbing to reserve memory regions persistently on a EFI
system by adding entries to the MEMRESERVE linked list.
Tested-by: default avatarJeremy Linton <jeremy.linton@arm.com>
Signed-off-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
parent b844470f
...@@ -962,6 +962,38 @@ bool efi_is_table_address(unsigned long phys_addr) ...@@ -962,6 +962,38 @@ bool efi_is_table_address(unsigned long phys_addr)
return false; return false;
} }
static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
{
struct linux_efi_memreserve *rsv, *parent;
if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
return -ENODEV;
rsv = kmalloc(sizeof(*rsv), GFP_KERNEL);
if (!rsv)
return -ENOMEM;
parent = memremap(efi.mem_reserve, sizeof(*rsv), MEMREMAP_WB);
if (!parent) {
kfree(rsv);
return -ENOMEM;
}
rsv->base = addr;
rsv->size = size;
spin_lock(&efi_mem_reserve_persistent_lock);
rsv->next = parent->next;
parent->next = __pa(rsv);
spin_unlock(&efi_mem_reserve_persistent_lock);
memunmap(parent);
return 0;
}
#ifdef CONFIG_KEXEC #ifdef CONFIG_KEXEC
static int update_efi_random_seed(struct notifier_block *nb, static int update_efi_random_seed(struct notifier_block *nb,
unsigned long code, void *unused) unsigned long code, void *unused)
......
...@@ -1043,6 +1043,7 @@ extern int __init efi_uart_console_only (void); ...@@ -1043,6 +1043,7 @@ extern int __init efi_uart_console_only (void);
extern u64 efi_mem_desc_end(efi_memory_desc_t *md); extern u64 efi_mem_desc_end(efi_memory_desc_t *md);
extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md); extern int efi_mem_desc_lookup(u64 phys_addr, efi_memory_desc_t *out_md);
extern void efi_mem_reserve(phys_addr_t addr, u64 size); extern void efi_mem_reserve(phys_addr_t addr, u64 size);
extern int efi_mem_reserve_persistent(phys_addr_t addr, u64 size);
extern void efi_initialize_iomem_resources(struct resource *code_resource, extern void efi_initialize_iomem_resources(struct resource *code_resource,
struct resource *data_resource, struct resource *bss_resource); struct resource *data_resource, struct resource *bss_resource);
extern void efi_reserve_boot_services(void); extern void efi_reserve_boot_services(void);
......
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