efi: split off remapping code from efi_config_init()
Split of the remapping code from efi_config_init() so that the caller can perform its own remapping. This is necessary to correctly handle virtually remapped UEFI memory regions under kexec, as efi.systab will have been updated to a virtual address. Acked-by: Matt Fleming <matt.fleming@intel.com> Tested-by: Leif Lindholm <leif.lindholm@linaro.org> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
This commit is contained in:
@@ -293,10 +293,49 @@ static __init int match_config_table(efi_guid_t *guid,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __init efi_config_parse_tables(void *config_tables, int count, int sz,
|
||||||
|
efi_config_table_type_t *arch_tables)
|
||||||
|
{
|
||||||
|
void *tablep;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
tablep = config_tables;
|
||||||
|
pr_info("");
|
||||||
|
for (i = 0; i < count; i++) {
|
||||||
|
efi_guid_t guid;
|
||||||
|
unsigned long table;
|
||||||
|
|
||||||
|
if (efi_enabled(EFI_64BIT)) {
|
||||||
|
u64 table64;
|
||||||
|
guid = ((efi_config_table_64_t *)tablep)->guid;
|
||||||
|
table64 = ((efi_config_table_64_t *)tablep)->table;
|
||||||
|
table = table64;
|
||||||
|
#ifndef CONFIG_64BIT
|
||||||
|
if (table64 >> 32) {
|
||||||
|
pr_cont("\n");
|
||||||
|
pr_err("Table located above 4GB, disabling EFI.\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
guid = ((efi_config_table_32_t *)tablep)->guid;
|
||||||
|
table = ((efi_config_table_32_t *)tablep)->table;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match_config_table(&guid, table, common_tables))
|
||||||
|
match_config_table(&guid, table, arch_tables);
|
||||||
|
|
||||||
|
tablep += sz;
|
||||||
|
}
|
||||||
|
pr_cont("\n");
|
||||||
|
set_bit(EFI_CONFIG_TABLES, &efi.flags);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int __init efi_config_init(efi_config_table_type_t *arch_tables)
|
int __init efi_config_init(efi_config_table_type_t *arch_tables)
|
||||||
{
|
{
|
||||||
void *config_tables, *tablep;
|
void *config_tables;
|
||||||
int i, sz;
|
int sz, ret;
|
||||||
|
|
||||||
if (efi_enabled(EFI_64BIT))
|
if (efi_enabled(EFI_64BIT))
|
||||||
sz = sizeof(efi_config_table_64_t);
|
sz = sizeof(efi_config_table_64_t);
|
||||||
@@ -313,42 +352,11 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
tablep = config_tables;
|
ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz,
|
||||||
pr_info("");
|
arch_tables);
|
||||||
for (i = 0; i < efi.systab->nr_tables; i++) {
|
|
||||||
efi_guid_t guid;
|
|
||||||
unsigned long table;
|
|
||||||
|
|
||||||
if (efi_enabled(EFI_64BIT)) {
|
|
||||||
u64 table64;
|
|
||||||
guid = ((efi_config_table_64_t *)tablep)->guid;
|
|
||||||
table64 = ((efi_config_table_64_t *)tablep)->table;
|
|
||||||
table = table64;
|
|
||||||
#ifndef CONFIG_64BIT
|
|
||||||
if (table64 >> 32) {
|
|
||||||
pr_cont("\n");
|
|
||||||
pr_err("Table located above 4GB, disabling EFI.\n");
|
|
||||||
early_memunmap(config_tables,
|
|
||||||
efi.systab->nr_tables * sz);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
guid = ((efi_config_table_32_t *)tablep)->guid;
|
|
||||||
table = ((efi_config_table_32_t *)tablep)->table;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!match_config_table(&guid, table, common_tables))
|
|
||||||
match_config_table(&guid, table, arch_tables);
|
|
||||||
|
|
||||||
tablep += sz;
|
|
||||||
}
|
|
||||||
pr_cont("\n");
|
|
||||||
early_memunmap(config_tables, efi.systab->nr_tables * sz);
|
early_memunmap(config_tables, efi.systab->nr_tables * sz);
|
||||||
|
return ret;
|
||||||
set_bit(EFI_CONFIG_TABLES, &efi.flags);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_EFI_VARS_MODULE
|
#ifdef CONFIG_EFI_VARS_MODULE
|
||||||
|
@@ -875,6 +875,8 @@ static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned lon
|
|||||||
#endif
|
#endif
|
||||||
extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
|
extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr);
|
||||||
extern int efi_config_init(efi_config_table_type_t *arch_tables);
|
extern int efi_config_init(efi_config_table_type_t *arch_tables);
|
||||||
|
extern int efi_config_parse_tables(void *config_tables, int count, int sz,
|
||||||
|
efi_config_table_type_t *arch_tables);
|
||||||
extern u64 efi_get_iobase (void);
|
extern u64 efi_get_iobase (void);
|
||||||
extern u32 efi_mem_type (unsigned long phys_addr);
|
extern u32 efi_mem_type (unsigned long phys_addr);
|
||||||
extern u64 efi_mem_attributes (unsigned long phys_addr);
|
extern u64 efi_mem_attributes (unsigned long phys_addr);
|
||||||
|
Reference in New Issue
Block a user