diff options
-rw-r--r-- | arch/x86/include/asm/efi.h | 2 | ||||
-rw-r--r-- | arch/x86/platform/efi/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 237 | ||||
-rw-r--r-- | arch/x86/platform/efi/quirks.c | 267 |
4 files changed, 272 insertions, 236 deletions
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 1eb5f6433ad8..3dbf56eb540d 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -104,6 +104,8 @@ extern void __init runtime_code_page_mkexec(void); | |||
104 | extern void __init efi_runtime_mkexec(void); | 104 | extern void __init efi_runtime_mkexec(void); |
105 | extern void __init efi_dump_pagetable(void); | 105 | extern void __init efi_dump_pagetable(void); |
106 | extern void __init efi_apply_memmap_quirks(void); | 106 | extern void __init efi_apply_memmap_quirks(void); |
107 | extern int __init efi_reuse_config(u64 tables, int nr_tables); | ||
108 | extern void efi_delete_dummy_variable(void); | ||
107 | 109 | ||
108 | struct efi_setup_data { | 110 | struct efi_setup_data { |
109 | u64 fw_vendor; | 111 | u64 fw_vendor; |
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index d51045afcaaf..2846aaab5103 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o | 1 | obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o |
2 | obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o | 2 | obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o |
3 | obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o | 3 | obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o |
4 | obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o | 4 | obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 87fc96bcc13c..f8524434bf65 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -56,13 +56,6 @@ | |||
56 | 56 | ||
57 | #define EFI_DEBUG | 57 | #define EFI_DEBUG |
58 | 58 | ||
59 | #define EFI_MIN_RESERVE 5120 | ||
60 | |||
61 | #define EFI_DUMMY_GUID \ | ||
62 | EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) | ||
63 | |||
64 | static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; | ||
65 | |||
66 | struct efi_memory_map memmap; | 59 | struct efi_memory_map memmap; |
67 | 60 | ||
68 | static struct efi efi_phys __initdata; | 61 | static struct efi efi_phys __initdata; |
@@ -95,15 +88,6 @@ static int __init setup_add_efi_memmap(char *arg) | |||
95 | } | 88 | } |
96 | early_param("add_efi_memmap", setup_add_efi_memmap); | 89 | early_param("add_efi_memmap", setup_add_efi_memmap); |
97 | 90 | ||
98 | static bool efi_no_storage_paranoia; | ||
99 | |||
100 | static int __init setup_storage_paranoia(char *arg) | ||
101 | { | ||
102 | efi_no_storage_paranoia = true; | ||
103 | return 0; | ||
104 | } | ||
105 | early_param("efi_no_storage_paranoia", setup_storage_paranoia); | ||
106 | |||
107 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | 91 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) |
108 | { | 92 | { |
109 | unsigned long flags; | 93 | unsigned long flags; |
@@ -392,37 +376,6 @@ static void __init print_efi_memmap(void) | |||
392 | #endif /* EFI_DEBUG */ | 376 | #endif /* EFI_DEBUG */ |
393 | } | 377 | } |
394 | 378 | ||
395 | void __init efi_reserve_boot_services(void) | ||
396 | { | ||
397 | void *p; | ||
398 | |||
399 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
400 | efi_memory_desc_t *md = p; | ||
401 | u64 start = md->phys_addr; | ||
402 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
403 | |||
404 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
405 | md->type != EFI_BOOT_SERVICES_DATA) | ||
406 | continue; | ||
407 | /* Only reserve where possible: | ||
408 | * - Not within any already allocated areas | ||
409 | * - Not over any memory area (really needed, if above?) | ||
410 | * - Not within any part of the kernel | ||
411 | * - Not the bios reserved area | ||
412 | */ | ||
413 | if ((start + size > __pa_symbol(_text) | ||
414 | && start <= __pa_symbol(_end)) || | ||
415 | !e820_all_mapped(start, start+size, E820_RAM) || | ||
416 | memblock_is_region_reserved(start, size)) { | ||
417 | /* Could not reserve, skip it */ | ||
418 | md->num_pages = 0; | ||
419 | memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", | ||
420 | start, start+size-1); | ||
421 | } else | ||
422 | memblock_reserve(start, size); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | void __init efi_unmap_memmap(void) | 379 | void __init efi_unmap_memmap(void) |
427 | { | 380 | { |
428 | clear_bit(EFI_MEMMAP, &efi.flags); | 381 | clear_bit(EFI_MEMMAP, &efi.flags); |
@@ -432,29 +385,6 @@ void __init efi_unmap_memmap(void) | |||
432 | } | 385 | } |
433 | } | 386 | } |
434 | 387 | ||
435 | void __init efi_free_boot_services(void) | ||
436 | { | ||
437 | void *p; | ||
438 | |||
439 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
440 | efi_memory_desc_t *md = p; | ||
441 | unsigned long long start = md->phys_addr; | ||
442 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
443 | |||
444 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
445 | md->type != EFI_BOOT_SERVICES_DATA) | ||
446 | continue; | ||
447 | |||
448 | /* Could not reserve boot area */ | ||
449 | if (!size) | ||
450 | continue; | ||
451 | |||
452 | free_bootmem_late(start, size); | ||
453 | } | ||
454 | |||
455 | efi_unmap_memmap(); | ||
456 | } | ||
457 | |||
458 | static int __init efi_systab_init(void *phys) | 388 | static int __init efi_systab_init(void *phys) |
459 | { | 389 | { |
460 | if (efi_enabled(EFI_64BIT)) { | 390 | if (efi_enabled(EFI_64BIT)) { |
@@ -649,62 +579,6 @@ static int __init efi_memmap_init(void) | |||
649 | return 0; | 579 | return 0; |
650 | } | 580 | } |
651 | 581 | ||
652 | /* | ||
653 | * A number of config table entries get remapped to virtual addresses | ||
654 | * after entering EFI virtual mode. However, the kexec kernel requires | ||
655 | * their physical addresses therefore we pass them via setup_data and | ||
656 | * correct those entries to their respective physical addresses here. | ||
657 | * | ||
658 | * Currently only handles smbios which is necessary for some firmware | ||
659 | * implementation. | ||
660 | */ | ||
661 | static int __init efi_reuse_config(u64 tables, int nr_tables) | ||
662 | { | ||
663 | int i, sz, ret = 0; | ||
664 | void *p, *tablep; | ||
665 | struct efi_setup_data *data; | ||
666 | |||
667 | if (!efi_setup) | ||
668 | return 0; | ||
669 | |||
670 | if (!efi_enabled(EFI_64BIT)) | ||
671 | return 0; | ||
672 | |||
673 | data = early_memremap(efi_setup, sizeof(*data)); | ||
674 | if (!data) { | ||
675 | ret = -ENOMEM; | ||
676 | goto out; | ||
677 | } | ||
678 | |||
679 | if (!data->smbios) | ||
680 | goto out_memremap; | ||
681 | |||
682 | sz = sizeof(efi_config_table_64_t); | ||
683 | |||
684 | p = tablep = early_memremap(tables, nr_tables * sz); | ||
685 | if (!p) { | ||
686 | pr_err("Could not map Configuration table!\n"); | ||
687 | ret = -ENOMEM; | ||
688 | goto out_memremap; | ||
689 | } | ||
690 | |||
691 | for (i = 0; i < efi.systab->nr_tables; i++) { | ||
692 | efi_guid_t guid; | ||
693 | |||
694 | guid = ((efi_config_table_64_t *)p)->guid; | ||
695 | |||
696 | if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) | ||
697 | ((efi_config_table_64_t *)p)->table = data->smbios; | ||
698 | p += sz; | ||
699 | } | ||
700 | early_iounmap(tablep, nr_tables * sz); | ||
701 | |||
702 | out_memremap: | ||
703 | early_iounmap(data, sizeof(*data)); | ||
704 | out: | ||
705 | return ret; | ||
706 | } | ||
707 | |||
708 | void __init efi_init(void) | 582 | void __init efi_init(void) |
709 | { | 583 | { |
710 | efi_char16_t *c16; | 584 | efi_char16_t *c16; |
@@ -1057,11 +931,7 @@ static void __init kexec_enter_virtual_mode(void) | |||
1057 | runtime_code_page_mkexec(); | 931 | runtime_code_page_mkexec(); |
1058 | 932 | ||
1059 | /* clean DUMMY object */ | 933 | /* clean DUMMY object */ |
1060 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | 934 | efi_delete_dummy_variable(); |
1061 | EFI_VARIABLE_NON_VOLATILE | | ||
1062 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1063 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1064 | 0, NULL); | ||
1065 | #endif | 935 | #endif |
1066 | } | 936 | } |
1067 | 937 | ||
@@ -1179,11 +1049,7 @@ static void __init __efi_enter_virtual_mode(void) | |||
1179 | free_pages((unsigned long)new_memmap, pg_shift); | 1049 | free_pages((unsigned long)new_memmap, pg_shift); |
1180 | 1050 | ||
1181 | /* clean DUMMY object */ | 1051 | /* clean DUMMY object */ |
1182 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | 1052 | efi_delete_dummy_variable(); |
1183 | EFI_VARIABLE_NON_VOLATILE | | ||
1184 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1185 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1186 | 0, NULL); | ||
1187 | } | 1053 | } |
1188 | 1054 | ||
1189 | void __init efi_enter_virtual_mode(void) | 1055 | void __init efi_enter_virtual_mode(void) |
@@ -1230,86 +1096,6 @@ u64 efi_mem_attributes(unsigned long phys_addr) | |||
1230 | return 0; | 1096 | return 0; |
1231 | } | 1097 | } |
1232 | 1098 | ||
1233 | /* | ||
1234 | * Some firmware implementations refuse to boot if there's insufficient space | ||
1235 | * in the variable store. Ensure that we never use more than a safe limit. | ||
1236 | * | ||
1237 | * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable | ||
1238 | * store. | ||
1239 | */ | ||
1240 | efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | ||
1241 | { | ||
1242 | efi_status_t status; | ||
1243 | u64 storage_size, remaining_size, max_size; | ||
1244 | |||
1245 | if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) | ||
1246 | return 0; | ||
1247 | |||
1248 | status = efi.query_variable_info(attributes, &storage_size, | ||
1249 | &remaining_size, &max_size); | ||
1250 | if (status != EFI_SUCCESS) | ||
1251 | return status; | ||
1252 | |||
1253 | /* | ||
1254 | * We account for that by refusing the write if permitting it would | ||
1255 | * reduce the available space to under 5KB. This figure was provided by | ||
1256 | * Samsung, so should be safe. | ||
1257 | */ | ||
1258 | if ((remaining_size - size < EFI_MIN_RESERVE) && | ||
1259 | !efi_no_storage_paranoia) { | ||
1260 | |||
1261 | /* | ||
1262 | * Triggering garbage collection may require that the firmware | ||
1263 | * generate a real EFI_OUT_OF_RESOURCES error. We can force | ||
1264 | * that by attempting to use more space than is available. | ||
1265 | */ | ||
1266 | unsigned long dummy_size = remaining_size + 1024; | ||
1267 | void *dummy = kzalloc(dummy_size, GFP_ATOMIC); | ||
1268 | |||
1269 | if (!dummy) | ||
1270 | return EFI_OUT_OF_RESOURCES; | ||
1271 | |||
1272 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
1273 | EFI_VARIABLE_NON_VOLATILE | | ||
1274 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1275 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1276 | dummy_size, dummy); | ||
1277 | |||
1278 | if (status == EFI_SUCCESS) { | ||
1279 | /* | ||
1280 | * This should have failed, so if it didn't make sure | ||
1281 | * that we delete it... | ||
1282 | */ | ||
1283 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
1284 | EFI_VARIABLE_NON_VOLATILE | | ||
1285 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1286 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1287 | 0, dummy); | ||
1288 | } | ||
1289 | |||
1290 | kfree(dummy); | ||
1291 | |||
1292 | /* | ||
1293 | * The runtime code may now have triggered a garbage collection | ||
1294 | * run, so check the variable info again | ||
1295 | */ | ||
1296 | status = efi.query_variable_info(attributes, &storage_size, | ||
1297 | &remaining_size, &max_size); | ||
1298 | |||
1299 | if (status != EFI_SUCCESS) | ||
1300 | return status; | ||
1301 | |||
1302 | /* | ||
1303 | * There still isn't enough room, so return an error | ||
1304 | */ | ||
1305 | if (remaining_size - size < EFI_MIN_RESERVE) | ||
1306 | return EFI_OUT_OF_RESOURCES; | ||
1307 | } | ||
1308 | |||
1309 | return EFI_SUCCESS; | ||
1310 | } | ||
1311 | EXPORT_SYMBOL_GPL(efi_query_variable_store); | ||
1312 | |||
1313 | static int __init parse_efi_cmdline(char *str) | 1099 | static int __init parse_efi_cmdline(char *str) |
1314 | { | 1100 | { |
1315 | if (*str == '=') | 1101 | if (*str == '=') |
@@ -1321,22 +1107,3 @@ static int __init parse_efi_cmdline(char *str) | |||
1321 | return 0; | 1107 | return 0; |
1322 | } | 1108 | } |
1323 | early_param("efi", parse_efi_cmdline); | 1109 | early_param("efi", parse_efi_cmdline); |
1324 | |||
1325 | void __init efi_apply_memmap_quirks(void) | ||
1326 | { | ||
1327 | /* | ||
1328 | * Once setup is done earlier, unmap the EFI memory map on mismatched | ||
1329 | * firmware/kernel architectures since there is no support for runtime | ||
1330 | * services. | ||
1331 | */ | ||
1332 | if (!efi_runtime_supported()) { | ||
1333 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | ||
1334 | efi_unmap_memmap(); | ||
1335 | } | ||
1336 | |||
1337 | /* | ||
1338 | * UV doesn't support the new EFI pagetable mapping yet. | ||
1339 | */ | ||
1340 | if (is_uv_system()) | ||
1341 | set_bit(EFI_OLD_MEMMAP, &efi.flags); | ||
1342 | } | ||
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c new file mode 100644 index 000000000000..7e3099c610dd --- /dev/null +++ b/arch/x86/platform/efi/quirks.c | |||
@@ -0,0 +1,267 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/string.h> | ||
4 | #include <linux/time.h> | ||
5 | #include <linux/types.h> | ||
6 | #include <linux/efi.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/memblock.h> | ||
9 | #include <linux/bootmem.h> | ||
10 | #include <asm/efi.h> | ||
11 | #include <asm/uv/uv.h> | ||
12 | |||
13 | #define EFI_MIN_RESERVE 5120 | ||
14 | |||
15 | #define EFI_DUMMY_GUID \ | ||
16 | EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) | ||
17 | |||
18 | static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; | ||
19 | |||
20 | static bool efi_no_storage_paranoia; | ||
21 | |||
22 | /* | ||
23 | * Some firmware implementations refuse to boot if there's insufficient | ||
24 | * space in the variable store. The implementation of garbage collection | ||
25 | * in some FW versions causes stale (deleted) variables to take up space | ||
26 | * longer than intended and space is only freed once the store becomes | ||
27 | * almost completely full. | ||
28 | * | ||
29 | * Enabling this option disables the space checks in | ||
30 | * efi_query_variable_store() and forces garbage collection. | ||
31 | * | ||
32 | * Only enable this option if deleting EFI variables does not free up | ||
33 | * space in your variable store, e.g. if despite deleting variables | ||
34 | * you're unable to create new ones. | ||
35 | */ | ||
36 | static int __init setup_storage_paranoia(char *arg) | ||
37 | { | ||
38 | efi_no_storage_paranoia = true; | ||
39 | return 0; | ||
40 | } | ||
41 | early_param("efi_no_storage_paranoia", setup_storage_paranoia); | ||
42 | |||
43 | /* | ||
44 | * Deleting the dummy variable which kicks off garbage collection | ||
45 | */ | ||
46 | void efi_delete_dummy_variable(void) | ||
47 | { | ||
48 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
49 | EFI_VARIABLE_NON_VOLATILE | | ||
50 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
51 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
52 | 0, NULL); | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * Some firmware implementations refuse to boot if there's insufficient space | ||
57 | * in the variable store. Ensure that we never use more than a safe limit. | ||
58 | * | ||
59 | * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable | ||
60 | * store. | ||
61 | */ | ||
62 | efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | ||
63 | { | ||
64 | efi_status_t status; | ||
65 | u64 storage_size, remaining_size, max_size; | ||
66 | |||
67 | if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) | ||
68 | return 0; | ||
69 | |||
70 | status = efi.query_variable_info(attributes, &storage_size, | ||
71 | &remaining_size, &max_size); | ||
72 | if (status != EFI_SUCCESS) | ||
73 | return status; | ||
74 | |||
75 | /* | ||
76 | * We account for that by refusing the write if permitting it would | ||
77 | * reduce the available space to under 5KB. This figure was provided by | ||
78 | * Samsung, so should be safe. | ||
79 | */ | ||
80 | if ((remaining_size - size < EFI_MIN_RESERVE) && | ||
81 | !efi_no_storage_paranoia) { | ||
82 | |||
83 | /* | ||
84 | * Triggering garbage collection may require that the firmware | ||
85 | * generate a real EFI_OUT_OF_RESOURCES error. We can force | ||
86 | * that by attempting to use more space than is available. | ||
87 | */ | ||
88 | unsigned long dummy_size = remaining_size + 1024; | ||
89 | void *dummy = kzalloc(dummy_size, GFP_ATOMIC); | ||
90 | |||
91 | if (!dummy) | ||
92 | return EFI_OUT_OF_RESOURCES; | ||
93 | |||
94 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
95 | EFI_VARIABLE_NON_VOLATILE | | ||
96 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
97 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
98 | dummy_size, dummy); | ||
99 | |||
100 | if (status == EFI_SUCCESS) { | ||
101 | /* | ||
102 | * This should have failed, so if it didn't make sure | ||
103 | * that we delete it... | ||
104 | */ | ||
105 | efi_delete_dummy_variable(); | ||
106 | } | ||
107 | |||
108 | kfree(dummy); | ||
109 | |||
110 | /* | ||
111 | * The runtime code may now have triggered a garbage collection | ||
112 | * run, so check the variable info again | ||
113 | */ | ||
114 | status = efi.query_variable_info(attributes, &storage_size, | ||
115 | &remaining_size, &max_size); | ||
116 | |||
117 | if (status != EFI_SUCCESS) | ||
118 | return status; | ||
119 | |||
120 | /* | ||
121 | * There still isn't enough room, so return an error | ||
122 | */ | ||
123 | if (remaining_size - size < EFI_MIN_RESERVE) | ||
124 | return EFI_OUT_OF_RESOURCES; | ||
125 | } | ||
126 | |||
127 | return EFI_SUCCESS; | ||
128 | } | ||
129 | EXPORT_SYMBOL_GPL(efi_query_variable_store); | ||
130 | |||
131 | /* | ||
132 | * The UEFI specification makes it clear that the operating system is free to do | ||
133 | * whatever it wants with boot services code after ExitBootServices() has been | ||
134 | * called. Ignoring this recommendation a significant bunch of EFI implementations | ||
135 | * continue calling into boot services code (SetVirtualAddressMap). In order to | ||
136 | * work around such buggy implementations we reserve boot services region during | ||
137 | * EFI init and make sure it stays executable. Then, after SetVirtualAddressMap(), it | ||
138 | * is discarded. | ||
139 | */ | ||
140 | void __init efi_reserve_boot_services(void) | ||
141 | { | ||
142 | void *p; | ||
143 | |||
144 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
145 | efi_memory_desc_t *md = p; | ||
146 | u64 start = md->phys_addr; | ||
147 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
148 | |||
149 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
150 | md->type != EFI_BOOT_SERVICES_DATA) | ||
151 | continue; | ||
152 | /* Only reserve where possible: | ||
153 | * - Not within any already allocated areas | ||
154 | * - Not over any memory area (really needed, if above?) | ||
155 | * - Not within any part of the kernel | ||
156 | * - Not the bios reserved area | ||
157 | */ | ||
158 | if ((start + size > __pa_symbol(_text) | ||
159 | && start <= __pa_symbol(_end)) || | ||
160 | !e820_all_mapped(start, start+size, E820_RAM) || | ||
161 | memblock_is_region_reserved(start, size)) { | ||
162 | /* Could not reserve, skip it */ | ||
163 | md->num_pages = 0; | ||
164 | memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", | ||
165 | start, start+size-1); | ||
166 | } else | ||
167 | memblock_reserve(start, size); | ||
168 | } | ||
169 | } | ||
170 | |||
171 | void __init efi_free_boot_services(void) | ||
172 | { | ||
173 | void *p; | ||
174 | |||
175 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
176 | efi_memory_desc_t *md = p; | ||
177 | unsigned long long start = md->phys_addr; | ||
178 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
179 | |||
180 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
181 | md->type != EFI_BOOT_SERVICES_DATA) | ||
182 | continue; | ||
183 | |||
184 | /* Could not reserve boot area */ | ||
185 | if (!size) | ||
186 | continue; | ||
187 | |||
188 | free_bootmem_late(start, size); | ||
189 | } | ||
190 | |||
191 | efi_unmap_memmap(); | ||
192 | } | ||
193 | |||
194 | /* | ||
195 | * A number of config table entries get remapped to virtual addresses | ||
196 | * after entering EFI virtual mode. However, the kexec kernel requires | ||
197 | * their physical addresses therefore we pass them via setup_data and | ||
198 | * correct those entries to their respective physical addresses here. | ||
199 | * | ||
200 | * Currently only handles smbios which is necessary for some firmware | ||
201 | * implementation. | ||
202 | */ | ||
203 | int __init efi_reuse_config(u64 tables, int nr_tables) | ||
204 | { | ||
205 | int i, sz, ret = 0; | ||
206 | void *p, *tablep; | ||
207 | struct efi_setup_data *data; | ||
208 | |||
209 | if (!efi_setup) | ||
210 | return 0; | ||
211 | |||
212 | if (!efi_enabled(EFI_64BIT)) | ||
213 | return 0; | ||
214 | |||
215 | data = early_memremap(efi_setup, sizeof(*data)); | ||
216 | if (!data) { | ||
217 | ret = -ENOMEM; | ||
218 | goto out; | ||
219 | } | ||
220 | |||
221 | if (!data->smbios) | ||
222 | goto out_memremap; | ||
223 | |||
224 | sz = sizeof(efi_config_table_64_t); | ||
225 | |||
226 | p = tablep = early_memremap(tables, nr_tables * sz); | ||
227 | if (!p) { | ||
228 | pr_err("Could not map Configuration table!\n"); | ||
229 | ret = -ENOMEM; | ||
230 | goto out_memremap; | ||
231 | } | ||
232 | |||
233 | for (i = 0; i < efi.systab->nr_tables; i++) { | ||
234 | efi_guid_t guid; | ||
235 | |||
236 | guid = ((efi_config_table_64_t *)p)->guid; | ||
237 | |||
238 | if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) | ||
239 | ((efi_config_table_64_t *)p)->table = data->smbios; | ||
240 | p += sz; | ||
241 | } | ||
242 | early_iounmap(tablep, nr_tables * sz); | ||
243 | |||
244 | out_memremap: | ||
245 | early_iounmap(data, sizeof(*data)); | ||
246 | out: | ||
247 | return ret; | ||
248 | } | ||
249 | |||
250 | void __init efi_apply_memmap_quirks(void) | ||
251 | { | ||
252 | /* | ||
253 | * Once setup is done earlier, unmap the EFI memory map on mismatched | ||
254 | * firmware/kernel architectures since there is no support for runtime | ||
255 | * services. | ||
256 | */ | ||
257 | if (!efi_runtime_supported()) { | ||
258 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | ||
259 | efi_unmap_memmap(); | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * UV doesn't support the new EFI pagetable mapping yet. | ||
264 | */ | ||
265 | if (is_uv_system()) | ||
266 | set_bit(EFI_OLD_MEMMAP, &efi.flags); | ||
267 | } | ||