diff options
author | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2014-10-18 09:04:15 -0400 |
---|---|---|
committer | Ard Biesheuvel <ard.biesheuvel@linaro.org> | 2015-01-12 03:16:55 -0500 |
commit | 7bb68410ef22067b08fd52887875b8f337f89dcc (patch) | |
tree | 90679b30e295a4d2333a69b0b726fa80d5ba9b46 | |
parent | 8ce837cee8f51fb0eacb32c85461ea2f0fafc9f8 (diff) |
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>
-rw-r--r-- | drivers/firmware/efi/efi.c | 56 | ||||
-rw-r--r-- | include/linux/efi.h | 2 |
2 files changed, 34 insertions, 24 deletions
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 9035c1b74d58..b7ba9d8ec4b0 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c | |||
@@ -293,29 +293,15 @@ static __init int match_config_table(efi_guid_t *guid, | |||
293 | return 0; | 293 | return 0; |
294 | } | 294 | } |
295 | 295 | ||
296 | int __init efi_config_init(efi_config_table_type_t *arch_tables) | 296 | int __init efi_config_parse_tables(void *config_tables, int count, int sz, |
297 | efi_config_table_type_t *arch_tables) | ||
297 | { | 298 | { |
298 | void *config_tables, *tablep; | 299 | void *tablep; |
299 | int i, sz; | 300 | int i; |
300 | |||
301 | if (efi_enabled(EFI_64BIT)) | ||
302 | sz = sizeof(efi_config_table_64_t); | ||
303 | else | ||
304 | sz = sizeof(efi_config_table_32_t); | ||
305 | |||
306 | /* | ||
307 | * Let's see what config tables the firmware passed to us. | ||
308 | */ | ||
309 | config_tables = early_memremap(efi.systab->tables, | ||
310 | efi.systab->nr_tables * sz); | ||
311 | if (config_tables == NULL) { | ||
312 | pr_err("Could not map Configuration table!\n"); | ||
313 | return -ENOMEM; | ||
314 | } | ||
315 | 301 | ||
316 | tablep = config_tables; | 302 | tablep = config_tables; |
317 | pr_info(""); | 303 | pr_info(""); |
318 | for (i = 0; i < efi.systab->nr_tables; i++) { | 304 | for (i = 0; i < count; i++) { |
319 | efi_guid_t guid; | 305 | efi_guid_t guid; |
320 | unsigned long table; | 306 | unsigned long table; |
321 | 307 | ||
@@ -328,8 +314,6 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) | |||
328 | if (table64 >> 32) { | 314 | if (table64 >> 32) { |
329 | pr_cont("\n"); | 315 | pr_cont("\n"); |
330 | pr_err("Table located above 4GB, disabling EFI.\n"); | 316 | pr_err("Table located above 4GB, disabling EFI.\n"); |
331 | early_memunmap(config_tables, | ||
332 | efi.systab->nr_tables * sz); | ||
333 | return -EINVAL; | 317 | return -EINVAL; |
334 | } | 318 | } |
335 | #endif | 319 | #endif |
@@ -344,13 +328,37 @@ int __init efi_config_init(efi_config_table_type_t *arch_tables) | |||
344 | tablep += sz; | 328 | tablep += sz; |
345 | } | 329 | } |
346 | pr_cont("\n"); | 330 | pr_cont("\n"); |
347 | early_memunmap(config_tables, efi.systab->nr_tables * sz); | ||
348 | |||
349 | set_bit(EFI_CONFIG_TABLES, &efi.flags); | 331 | set_bit(EFI_CONFIG_TABLES, &efi.flags); |
350 | |||
351 | return 0; | 332 | return 0; |
352 | } | 333 | } |
353 | 334 | ||
335 | int __init efi_config_init(efi_config_table_type_t *arch_tables) | ||
336 | { | ||
337 | void *config_tables; | ||
338 | int sz, ret; | ||
339 | |||
340 | if (efi_enabled(EFI_64BIT)) | ||
341 | sz = sizeof(efi_config_table_64_t); | ||
342 | else | ||
343 | sz = sizeof(efi_config_table_32_t); | ||
344 | |||
345 | /* | ||
346 | * Let's see what config tables the firmware passed to us. | ||
347 | */ | ||
348 | config_tables = early_memremap(efi.systab->tables, | ||
349 | efi.systab->nr_tables * sz); | ||
350 | if (config_tables == NULL) { | ||
351 | pr_err("Could not map Configuration table!\n"); | ||
352 | return -ENOMEM; | ||
353 | } | ||
354 | |||
355 | ret = efi_config_parse_tables(config_tables, efi.systab->nr_tables, sz, | ||
356 | arch_tables); | ||
357 | |||
358 | early_memunmap(config_tables, efi.systab->nr_tables * sz); | ||
359 | return ret; | ||
360 | } | ||
361 | |||
354 | #ifdef CONFIG_EFI_VARS_MODULE | 362 | #ifdef CONFIG_EFI_VARS_MODULE |
355 | static int __init efi_load_efivars(void) | 363 | static int __init efi_load_efivars(void) |
356 | { | 364 | { |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 0238d612750e..5ffe5115951f 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -875,6 +875,8 @@ static inline efi_status_t efi_query_variable_store(u32 attributes, unsigned lon | |||
875 | #endif | 875 | #endif |
876 | extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); | 876 | extern void __iomem *efi_lookup_mapped_addr(u64 phys_addr); |
877 | extern int efi_config_init(efi_config_table_type_t *arch_tables); | 877 | extern int efi_config_init(efi_config_table_type_t *arch_tables); |
878 | extern int efi_config_parse_tables(void *config_tables, int count, int sz, | ||
879 | efi_config_table_type_t *arch_tables); | ||
878 | extern u64 efi_get_iobase (void); | 880 | extern u64 efi_get_iobase (void); |
879 | extern u32 efi_mem_type (unsigned long phys_addr); | 881 | extern u32 efi_mem_type (unsigned long phys_addr); |
880 | extern u64 efi_mem_attributes (unsigned long phys_addr); | 882 | extern u64 efi_mem_attributes (unsigned long phys_addr); |