aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform
diff options
context:
space:
mode:
authorDave Young <dyoung@redhat.com>2013-12-20 05:02:18 -0500
committerMatt Fleming <matt.fleming@intel.com>2013-12-21 10:29:36 -0500
commit926172d46038d7610b6b8d84e40db727cefb482d (patch)
tree8963aaa9fccd0a4ee0d59717b4de8e8cdfebbe62 /arch/x86/platform
parenta0998eb15afeffbf52a2c2829318f67df9ac57b8 (diff)
efi: Export EFI runtime memory mapping to sysfs
kexec kernel will need exactly same mapping for EFI runtime memory ranges. Thus here export the runtime ranges mapping to sysfs, kexec-tools will assemble them and pass to 2nd kernel via setup_data. Introducing a new directory /sys/firmware/efi/runtime-map just like /sys/firmware/memmap. Containing below attribute in each file of that directory: attribute num_pages phys_addr type virt_addr Signed-off-by: Dave Young <dyoung@redhat.com> Tested-by: Toshi Kani <toshi.kani@hp.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'arch/x86/platform')
-rw-r--r--arch/x86/platform/efi/efi.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 28591072fbb7..74fe7a719508 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -76,6 +76,9 @@ static __initdata efi_config_table_type_t arch_tables[] = {
76 {NULL_GUID, NULL, NULL}, 76 {NULL_GUID, NULL, NULL},
77}; 77};
78 78
79static void *efi_runtime_map;
80static int nr_efi_runtime_map;
81
79/* 82/*
80 * Returns 1 if 'facility' is enabled, 0 otherwise. 83 * Returns 1 if 'facility' is enabled, 0 otherwise.
81 */ 84 */
@@ -824,6 +827,39 @@ static void __init get_systab_virt_addr(efi_memory_desc_t *md)
824 } 827 }
825} 828}
826 829
830static int __init save_runtime_map(void)
831{
832 efi_memory_desc_t *md;
833 void *tmp, *p, *q = NULL;
834 int count = 0;
835
836 for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
837 md = p;
838
839 if (!(md->attribute & EFI_MEMORY_RUNTIME) ||
840 (md->type == EFI_BOOT_SERVICES_CODE) ||
841 (md->type == EFI_BOOT_SERVICES_DATA))
842 continue;
843 tmp = krealloc(q, (count + 1) * memmap.desc_size, GFP_KERNEL);
844 if (!tmp)
845 goto out;
846 q = tmp;
847
848 memcpy(q + count * memmap.desc_size, md, memmap.desc_size);
849 count++;
850 }
851
852 efi_runtime_map = q;
853 nr_efi_runtime_map = count;
854 efi_runtime_map_setup(efi_runtime_map, nr_efi_runtime_map,
855 boot_params.efi_info.efi_memdesc_size);
856
857 return 0;
858out:
859 kfree(q);
860 return -ENOMEM;
861}
862
827/* 863/*
828 * Map efi memory ranges for runtime serivce and update new_memmap with virtual 864 * Map efi memory ranges for runtime serivce and update new_memmap with virtual
829 * addresses. 865 * addresses.
@@ -849,7 +885,7 @@ static void * __init efi_map_regions(int *count)
849 tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size, 885 tmp = krealloc(new_memmap, (*count + 1) * memmap.desc_size,
850 GFP_KERNEL); 886 GFP_KERNEL);
851 if (!tmp) 887 if (!tmp)
852 goto out_krealloc; 888 goto out;
853 new_memmap = tmp; 889 new_memmap = tmp;
854 memcpy(new_memmap + (*count * memmap.desc_size), md, 890 memcpy(new_memmap + (*count * memmap.desc_size), md,
855 memmap.desc_size); 891 memmap.desc_size);
@@ -857,7 +893,7 @@ static void * __init efi_map_regions(int *count)
857 } 893 }
858 894
859 return new_memmap; 895 return new_memmap;
860out_krealloc: 896out:
861 kfree(new_memmap); 897 kfree(new_memmap);
862 return NULL; 898 return NULL;
863} 899}
@@ -883,7 +919,7 @@ void __init efi_enter_virtual_mode(void)
883{ 919{
884 efi_status_t status; 920 efi_status_t status;
885 void *new_memmap = NULL; 921 void *new_memmap = NULL;
886 int count = 0; 922 int err, count = 0;
887 923
888 efi.systab = NULL; 924 efi.systab = NULL;
889 925
@@ -904,6 +940,10 @@ void __init efi_enter_virtual_mode(void)
904 return; 940 return;
905 } 941 }
906 942
943 err = save_runtime_map();
944 if (err)
945 pr_err("Error saving runtime map, efi runtime on kexec non-functional!!\n");
946
907 BUG_ON(!efi.systab); 947 BUG_ON(!efi.systab);
908 948
909 efi_setup_page_tables(); 949 efi_setup_page_tables();