aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/efi.h2
-rw-r--r--arch/x86/platform/efi/Makefile2
-rw-r--r--arch/x86/platform/efi/efi.c237
-rw-r--r--arch/x86/platform/efi/quirks.c267
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);
104extern void __init efi_runtime_mkexec(void); 104extern void __init efi_runtime_mkexec(void);
105extern void __init efi_dump_pagetable(void); 105extern void __init efi_dump_pagetable(void);
106extern void __init efi_apply_memmap_quirks(void); 106extern void __init efi_apply_memmap_quirks(void);
107extern int __init efi_reuse_config(u64 tables, int nr_tables);
108extern void efi_delete_dummy_variable(void);
107 109
108struct efi_setup_data { 110struct 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 @@
1obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o 1obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o
2obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o 2obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
3obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o 3obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o
4obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o 4obj-$(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
64static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
65
66struct efi_memory_map memmap; 59struct efi_memory_map memmap;
67 60
68static struct efi efi_phys __initdata; 61static struct efi efi_phys __initdata;
@@ -95,15 +88,6 @@ static int __init setup_add_efi_memmap(char *arg)
95} 88}
96early_param("add_efi_memmap", setup_add_efi_memmap); 89early_param("add_efi_memmap", setup_add_efi_memmap);
97 90
98static bool efi_no_storage_paranoia;
99
100static int __init setup_storage_paranoia(char *arg)
101{
102 efi_no_storage_paranoia = true;
103 return 0;
104}
105early_param("efi_no_storage_paranoia", setup_storage_paranoia);
106
107static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) 91static 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
395void __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
426void __init efi_unmap_memmap(void) 379void __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
435void __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
458static int __init efi_systab_init(void *phys) 388static 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 */
661static 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
702out_memremap:
703 early_iounmap(data, sizeof(*data));
704out:
705 return ret;
706}
707
708void __init efi_init(void) 582void __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
1189void __init efi_enter_virtual_mode(void) 1055void __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 */
1240efi_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}
1311EXPORT_SYMBOL_GPL(efi_query_variable_store);
1312
1313static int __init parse_efi_cmdline(char *str) 1099static 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}
1323early_param("efi", parse_efi_cmdline); 1109early_param("efi", parse_efi_cmdline);
1324
1325void __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
18static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 };
19
20static 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 */
36static int __init setup_storage_paranoia(char *arg)
37{
38 efi_no_storage_paranoia = true;
39 return 0;
40}
41early_param("efi_no_storage_paranoia", setup_storage_paranoia);
42
43/*
44 * Deleting the dummy variable which kicks off garbage collection
45*/
46void 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 */
62efi_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}
129EXPORT_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*/
140void __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
171void __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 */
203int __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
244out_memremap:
245 early_iounmap(data, sizeof(*data));
246out:
247 return ret;
248}
249
250void __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}