Merge branch 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI fixes from Ingo Molnar: "Misc fixes: two warning splat fixes, a leak fix and persistent memory allocation fixes for ARM" * 'efi-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: efi: Permit calling efi_mem_reserve_persistent() from atomic context efi/arm: Defer persistent reservations until after paging_init() efi/arm/libstub: Pack FDT after populating it efi/arm: Revert deferred unmap of early memmap mapping efi: Fix debugobjects warning on 'efi_rts_work'
This commit is contained in:
commit
743a4863fd
|
@ -313,6 +313,7 @@ void __init setup_arch(char **cmdline_p)
|
||||||
arm64_memblock_init();
|
arm64_memblock_init();
|
||||||
|
|
||||||
paging_init();
|
paging_init();
|
||||||
|
efi_apply_persistent_mem_reservations();
|
||||||
|
|
||||||
acpi_table_upgrade();
|
acpi_table_upgrade();
|
||||||
|
|
||||||
|
|
|
@ -265,6 +265,10 @@ void __init efi_init(void)
|
||||||
(params.mmap & ~PAGE_MASK)));
|
(params.mmap & ~PAGE_MASK)));
|
||||||
|
|
||||||
init_screen_info();
|
init_screen_info();
|
||||||
|
|
||||||
|
/* ARM does not permit early mappings to persist across paging_init() */
|
||||||
|
if (IS_ENABLED(CONFIG_ARM))
|
||||||
|
efi_memmap_unmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __init register_gop_device(void)
|
static int __init register_gop_device(void)
|
||||||
|
|
|
@ -110,7 +110,7 @@ static int __init arm_enable_runtime_services(void)
|
||||||
{
|
{
|
||||||
u64 mapsize;
|
u64 mapsize;
|
||||||
|
|
||||||
if (!efi_enabled(EFI_BOOT) || !efi_enabled(EFI_MEMMAP)) {
|
if (!efi_enabled(EFI_BOOT)) {
|
||||||
pr_info("EFI services will not be available.\n");
|
pr_info("EFI services will not be available.\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -592,7 +592,11 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
|
||||||
|
|
||||||
early_memunmap(tbl, sizeof(*tbl));
|
early_memunmap(tbl, sizeof(*tbl));
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init efi_apply_persistent_mem_reservations(void)
|
||||||
|
{
|
||||||
if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
|
if (efi.mem_reserve != EFI_INVALID_TABLE_ADDR) {
|
||||||
unsigned long prsv = efi.mem_reserve;
|
unsigned long prsv = efi.mem_reserve;
|
||||||
|
|
||||||
|
@ -963,37 +967,44 @@ bool efi_is_table_address(unsigned long phys_addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
|
static DEFINE_SPINLOCK(efi_mem_reserve_persistent_lock);
|
||||||
|
static struct linux_efi_memreserve *efi_memreserve_root __ro_after_init;
|
||||||
|
|
||||||
int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
|
int efi_mem_reserve_persistent(phys_addr_t addr, u64 size)
|
||||||
{
|
{
|
||||||
struct linux_efi_memreserve *rsv, *parent;
|
struct linux_efi_memreserve *rsv;
|
||||||
|
|
||||||
if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
|
if (!efi_memreserve_root)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
rsv = kmalloc(sizeof(*rsv), GFP_KERNEL);
|
rsv = kmalloc(sizeof(*rsv), GFP_ATOMIC);
|
||||||
if (!rsv)
|
if (!rsv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
parent = memremap(efi.mem_reserve, sizeof(*rsv), MEMREMAP_WB);
|
|
||||||
if (!parent) {
|
|
||||||
kfree(rsv);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
rsv->base = addr;
|
rsv->base = addr;
|
||||||
rsv->size = size;
|
rsv->size = size;
|
||||||
|
|
||||||
spin_lock(&efi_mem_reserve_persistent_lock);
|
spin_lock(&efi_mem_reserve_persistent_lock);
|
||||||
rsv->next = parent->next;
|
rsv->next = efi_memreserve_root->next;
|
||||||
parent->next = __pa(rsv);
|
efi_memreserve_root->next = __pa(rsv);
|
||||||
spin_unlock(&efi_mem_reserve_persistent_lock);
|
spin_unlock(&efi_mem_reserve_persistent_lock);
|
||||||
|
|
||||||
memunmap(parent);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __init efi_memreserve_root_init(void)
|
||||||
|
{
|
||||||
|
if (efi.mem_reserve == EFI_INVALID_TABLE_ADDR)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
efi_memreserve_root = memremap(efi.mem_reserve,
|
||||||
|
sizeof(*efi_memreserve_root),
|
||||||
|
MEMREMAP_WB);
|
||||||
|
if (!efi_memreserve_root)
|
||||||
|
return -ENOMEM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
early_initcall(efi_memreserve_root_init);
|
||||||
|
|
||||||
#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)
|
||||||
|
|
|
@ -75,6 +75,9 @@ void install_memreserve_table(efi_system_table_t *sys_table_arg)
|
||||||
efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
|
efi_guid_t memreserve_table_guid = LINUX_EFI_MEMRESERVE_TABLE_GUID;
|
||||||
efi_status_t status;
|
efi_status_t status;
|
||||||
|
|
||||||
|
if (IS_ENABLED(CONFIG_ARM))
|
||||||
|
return;
|
||||||
|
|
||||||
status = efi_call_early(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
|
status = efi_call_early(allocate_pool, EFI_LOADER_DATA, sizeof(*rsv),
|
||||||
(void **)&rsv);
|
(void **)&rsv);
|
||||||
if (status != EFI_SUCCESS) {
|
if (status != EFI_SUCCESS) {
|
||||||
|
|
|
@ -158,6 +158,10 @@ static efi_status_t update_fdt(efi_system_table_t *sys_table, void *orig_fdt,
|
||||||
return efi_status;
|
return efi_status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* shrink the FDT back to its minimum size */
|
||||||
|
fdt_pack(fdt);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
|
|
||||||
fdt_set_fail:
|
fdt_set_fail:
|
||||||
|
|
|
@ -118,6 +118,9 @@ int __init efi_memmap_init_early(struct efi_memory_map_data *data)
|
||||||
|
|
||||||
void __init efi_memmap_unmap(void)
|
void __init efi_memmap_unmap(void)
|
||||||
{
|
{
|
||||||
|
if (!efi_enabled(EFI_MEMMAP))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!efi.memmap.late) {
|
if (!efi.memmap.late) {
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ struct efi_runtime_work efi_rts_work;
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
init_completion(&efi_rts_work.efi_rts_comp); \
|
init_completion(&efi_rts_work.efi_rts_comp); \
|
||||||
INIT_WORK_ONSTACK(&efi_rts_work.work, efi_call_rts); \
|
INIT_WORK(&efi_rts_work.work, efi_call_rts); \
|
||||||
efi_rts_work.arg1 = _arg1; \
|
efi_rts_work.arg1 = _arg1; \
|
||||||
efi_rts_work.arg2 = _arg2; \
|
efi_rts_work.arg2 = _arg2; \
|
||||||
efi_rts_work.arg3 = _arg3; \
|
efi_rts_work.arg3 = _arg3; \
|
||||||
|
|
|
@ -1167,6 +1167,8 @@ static inline bool efi_enabled(int feature)
|
||||||
extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
|
extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused);
|
||||||
|
|
||||||
extern bool efi_is_table_address(unsigned long phys_addr);
|
extern bool efi_is_table_address(unsigned long phys_addr);
|
||||||
|
|
||||||
|
extern int efi_apply_persistent_mem_reservations(void);
|
||||||
#else
|
#else
|
||||||
static inline bool efi_enabled(int feature)
|
static inline bool efi_enabled(int feature)
|
||||||
{
|
{
|
||||||
|
@ -1185,6 +1187,11 @@ static inline bool efi_is_table_address(unsigned long phys_addr)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int efi_apply_persistent_mem_reservations(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int efi_status_to_err(efi_status_t status);
|
extern int efi_status_to_err(efi_status_t status);
|
||||||
|
|
Loading…
Reference in New Issue