diff options
author | Dave Young <dyoung@redhat.com> | 2013-12-20 05:02:18 -0500 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-12-21 10:29:36 -0500 |
commit | 926172d46038d7610b6b8d84e40db727cefb482d (patch) | |
tree | 8963aaa9fccd0a4ee0d59717b4de8e8cdfebbe62 /arch/x86/platform | |
parent | a0998eb15afeffbf52a2c2829318f67df9ac57b8 (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.c | 46 |
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 | ||
79 | static void *efi_runtime_map; | ||
80 | static 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 | ||
830 | static 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; | ||
858 | out: | ||
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; |
860 | out_krealloc: | 896 | out: |
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(); |