aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 13:22:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-13 13:22:30 -0400
commit9c65e12a55fea2da50f4069ec0dc47c50b7bd2bb (patch)
treee371d6da040aaf8b56f060dd25a19b918229927e /drivers/firmware
parent67dbb3a099d0fe04df5974edddc0b8c64a9f7529 (diff)
parent84a87c628a12f95d8b0c86cc7b8edb28ea5edf90 (diff)
Merge branch 'core-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI update from Ingo Molnar: "This tree includes various fixes, cleanups, a new efi=debug boot option and EFI boot stub memory allocation optimizations" * 'core-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: efi/libstub: Retrieve FDT size when loaded from UEFI config table efi: Clean up the efi_call_phys_[prolog|epilog]() save/restore interaction efi: Disable interrupts around EFI calls, not in the epilog/prolog calls x86/efi: Add a "debug" option to the efi= cmdline firmware: dmi_scan: Use direct access to static vars firmware: dmi_scan: Use full dmi version for SMBIOS3
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/dmi_scan.c38
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c7
-rw-r--r--drivers/firmware/efi/libstub/efistub.h2
-rw-r--r--drivers/firmware/efi/libstub/fdt.c7
4 files changed, 31 insertions, 23 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 2eebd28b4c40..6e45a43ffe84 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -17,7 +17,9 @@
17 */ 17 */
18static const char dmi_empty_string[] = " "; 18static const char dmi_empty_string[] = " ";
19 19
20static u16 __initdata dmi_ver; 20static u32 dmi_ver __initdata;
21static u32 dmi_len;
22static u16 dmi_num;
21/* 23/*
22 * Catch too early calls to dmi_check_system(): 24 * Catch too early calls to dmi_check_system():
23 */ 25 */
@@ -78,7 +80,7 @@ static const char * __init dmi_string(const struct dmi_header *dm, u8 s)
78 * We have to be cautious here. We have seen BIOSes with DMI pointers 80 * We have to be cautious here. We have seen BIOSes with DMI pointers
79 * pointing to completely the wrong place for example 81 * pointing to completely the wrong place for example
80 */ 82 */
81static void dmi_table(u8 *buf, u32 len, int num, 83static void dmi_table(u8 *buf,
82 void (*decode)(const struct dmi_header *, void *), 84 void (*decode)(const struct dmi_header *, void *),
83 void *private_data) 85 void *private_data)
84{ 86{
@@ -91,8 +93,8 @@ static void dmi_table(u8 *buf, u32 len, int num,
91 * off the end of the table (should never happen but sometimes does 93 * off the end of the table (should never happen but sometimes does
92 * on bogus implementations.) 94 * on bogus implementations.)
93 */ 95 */
94 while ((!num || i < num) && 96 while ((!dmi_num || i < dmi_num) &&
95 (data - buf + sizeof(struct dmi_header)) <= len) { 97 (data - buf + sizeof(struct dmi_header)) <= dmi_len) {
96 const struct dmi_header *dm = (const struct dmi_header *)data; 98 const struct dmi_header *dm = (const struct dmi_header *)data;
97 99
98 /* 100 /*
@@ -101,9 +103,9 @@ static void dmi_table(u8 *buf, u32 len, int num,
101 * table in dmi_decode or dmi_string 103 * table in dmi_decode or dmi_string
102 */ 104 */
103 data += dm->length; 105 data += dm->length;
104 while ((data - buf < len - 1) && (data[0] || data[1])) 106 while ((data - buf < dmi_len - 1) && (data[0] || data[1]))
105 data++; 107 data++;
106 if (data - buf < len - 1) 108 if (data - buf < dmi_len - 1)
107 decode(dm, private_data); 109 decode(dm, private_data);
108 110
109 /* 111 /*
@@ -118,8 +120,6 @@ static void dmi_table(u8 *buf, u32 len, int num,
118} 120}
119 121
120static phys_addr_t dmi_base; 122static phys_addr_t dmi_base;
121static u32 dmi_len;
122static u16 dmi_num;
123 123
124static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, 124static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
125 void *)) 125 void *))
@@ -130,7 +130,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
130 if (buf == NULL) 130 if (buf == NULL)
131 return -1; 131 return -1;
132 132
133 dmi_table(buf, dmi_len, dmi_num, decode, NULL); 133 dmi_table(buf, decode, NULL);
134 134
135 add_device_randomness(buf, dmi_len); 135 add_device_randomness(buf, dmi_len);
136 136
@@ -201,7 +201,7 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot,
201 * the UUID are supposed to be little-endian encoded. The specification 201 * the UUID are supposed to be little-endian encoded. The specification
202 * says that this is the defacto standard. 202 * says that this is the defacto standard.
203 */ 203 */
204 if (dmi_ver >= 0x0206) 204 if (dmi_ver >= 0x020600)
205 sprintf(s, "%pUL", d); 205 sprintf(s, "%pUL", d);
206 else 206 else
207 sprintf(s, "%pUB", d); 207 sprintf(s, "%pUB", d);
@@ -473,7 +473,7 @@ static void __init dmi_format_ids(char *buf, size_t len)
473 */ 473 */
474static int __init dmi_present(const u8 *buf) 474static int __init dmi_present(const u8 *buf)
475{ 475{
476 int smbios_ver; 476 u32 smbios_ver;
477 477
478 if (memcmp(buf, "_SM_", 4) == 0 && 478 if (memcmp(buf, "_SM_", 4) == 0 &&
479 buf[5] < 32 && dmi_checksum(buf, buf[5])) { 479 buf[5] < 32 && dmi_checksum(buf, buf[5])) {
@@ -506,14 +506,16 @@ static int __init dmi_present(const u8 *buf)
506 if (dmi_walk_early(dmi_decode) == 0) { 506 if (dmi_walk_early(dmi_decode) == 0) {
507 if (smbios_ver) { 507 if (smbios_ver) {
508 dmi_ver = smbios_ver; 508 dmi_ver = smbios_ver;
509 pr_info("SMBIOS %d.%d present.\n", 509 pr_info("SMBIOS %d.%d%s present.\n",
510 dmi_ver >> 8, dmi_ver & 0xFF); 510 dmi_ver >> 8, dmi_ver & 0xFF,
511 (dmi_ver < 0x0300) ? "" : ".x");
511 } else { 512 } else {
512 dmi_ver = (buf[14] & 0xF0) << 4 | 513 dmi_ver = (buf[14] & 0xF0) << 4 |
513 (buf[14] & 0x0F); 514 (buf[14] & 0x0F);
514 pr_info("Legacy DMI %d.%d present.\n", 515 pr_info("Legacy DMI %d.%d present.\n",
515 dmi_ver >> 8, dmi_ver & 0xFF); 516 dmi_ver >> 8, dmi_ver & 0xFF);
516 } 517 }
518 dmi_ver <<= 8;
517 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string)); 519 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
518 printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string); 520 printk(KERN_DEBUG "DMI: %s\n", dmi_ids_string);
519 return 0; 521 return 0;
@@ -531,14 +533,16 @@ static int __init dmi_smbios3_present(const u8 *buf)
531{ 533{
532 if (memcmp(buf, "_SM3_", 5) == 0 && 534 if (memcmp(buf, "_SM3_", 5) == 0 &&
533 buf[6] < 32 && dmi_checksum(buf, buf[6])) { 535 buf[6] < 32 && dmi_checksum(buf, buf[6])) {
534 dmi_ver = get_unaligned_be16(buf + 7); 536 dmi_ver = get_unaligned_be32(buf + 6);
537 dmi_ver &= 0xFFFFFF;
535 dmi_num = 0; /* No longer specified */ 538 dmi_num = 0; /* No longer specified */
536 dmi_len = get_unaligned_le32(buf + 12); 539 dmi_len = get_unaligned_le32(buf + 12);
537 dmi_base = get_unaligned_le64(buf + 16); 540 dmi_base = get_unaligned_le64(buf + 16);
538 541
539 if (dmi_walk_early(dmi_decode) == 0) { 542 if (dmi_walk_early(dmi_decode) == 0) {
540 pr_info("SMBIOS %d.%d present.\n", 543 pr_info("SMBIOS %d.%d.%d present.\n",
541 dmi_ver >> 8, dmi_ver & 0xFF); 544 dmi_ver >> 16, (dmi_ver >> 8) & 0xFF,
545 dmi_ver & 0xFF);
542 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string)); 546 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
543 pr_debug("DMI: %s\n", dmi_ids_string); 547 pr_debug("DMI: %s\n", dmi_ids_string);
544 return 0; 548 return 0;
@@ -893,7 +897,7 @@ int dmi_walk(void (*decode)(const struct dmi_header *, void *),
893 if (buf == NULL) 897 if (buf == NULL)
894 return -1; 898 return -1;
895 899
896 dmi_table(buf, dmi_len, dmi_num, decode, private_data); 900 dmi_table(buf, decode, private_data);
897 901
898 dmi_unmap(buf); 902 dmi_unmap(buf);
899 return 0; 903 return 0;
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index dcae482a9a17..e29560e6b40b 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -175,7 +175,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
175 unsigned long initrd_addr; 175 unsigned long initrd_addr;
176 u64 initrd_size = 0; 176 u64 initrd_size = 0;
177 unsigned long fdt_addr = 0; /* Original DTB */ 177 unsigned long fdt_addr = 0; /* Original DTB */
178 u64 fdt_size = 0; /* We don't get size from configuration table */ 178 unsigned long fdt_size = 0;
179 char *cmdline_ptr = NULL; 179 char *cmdline_ptr = NULL;
180 int cmdline_size = 0; 180 int cmdline_size = 0;
181 unsigned long new_fdt_addr; 181 unsigned long new_fdt_addr;
@@ -239,8 +239,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
239 } else { 239 } else {
240 status = handle_cmdline_files(sys_table, image, cmdline_ptr, 240 status = handle_cmdline_files(sys_table, image, cmdline_ptr,
241 "dtb=", 241 "dtb=",
242 ~0UL, (unsigned long *)&fdt_addr, 242 ~0UL, &fdt_addr, &fdt_size);
243 (unsigned long *)&fdt_size);
244 243
245 if (status != EFI_SUCCESS) { 244 if (status != EFI_SUCCESS) {
246 pr_efi_err(sys_table, "Failed to load device tree!\n"); 245 pr_efi_err(sys_table, "Failed to load device tree!\n");
@@ -252,7 +251,7 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
252 pr_efi(sys_table, "Using DTB from command line\n"); 251 pr_efi(sys_table, "Using DTB from command line\n");
253 } else { 252 } else {
254 /* Look for a device tree configuration table entry. */ 253 /* Look for a device tree configuration table entry. */
255 fdt_addr = (uintptr_t)get_fdt(sys_table); 254 fdt_addr = (uintptr_t)get_fdt(sys_table, &fdt_size);
256 if (fdt_addr) 255 if (fdt_addr)
257 pr_efi(sys_table, "Using DTB from configuration table\n"); 256 pr_efi(sys_table, "Using DTB from configuration table\n");
258 } 257 }
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 47437b16b186..e334a01cf92f 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -41,7 +41,7 @@ efi_status_t allocate_new_fdt_and_exit_boot(efi_system_table_t *sys_table,
41 unsigned long fdt_addr, 41 unsigned long fdt_addr,
42 unsigned long fdt_size); 42 unsigned long fdt_size);
43 43
44void *get_fdt(efi_system_table_t *sys_table); 44void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size);
45 45
46void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, 46void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size,
47 unsigned long desc_size, efi_memory_desc_t *runtime_map, 47 unsigned long desc_size, efi_memory_desc_t *runtime_map,
diff --git a/drivers/firmware/efi/libstub/fdt.c b/drivers/firmware/efi/libstub/fdt.c
index 91da56c4fd54..ef5d764e2a27 100644
--- a/drivers/firmware/efi/libstub/fdt.c
+++ b/drivers/firmware/efi/libstub/fdt.c
@@ -323,7 +323,7 @@ fail:
323 return EFI_LOAD_ERROR; 323 return EFI_LOAD_ERROR;
324} 324}
325 325
326void *get_fdt(efi_system_table_t *sys_table) 326void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size)
327{ 327{
328 efi_guid_t fdt_guid = DEVICE_TREE_GUID; 328 efi_guid_t fdt_guid = DEVICE_TREE_GUID;
329 efi_config_table_t *tables; 329 efi_config_table_t *tables;
@@ -336,6 +336,11 @@ void *get_fdt(efi_system_table_t *sys_table)
336 for (i = 0; i < sys_table->nr_tables; i++) 336 for (i = 0; i < sys_table->nr_tables; i++)
337 if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) { 337 if (efi_guidcmp(tables[i].guid, fdt_guid) == 0) {
338 fdt = (void *) tables[i].table; 338 fdt = (void *) tables[i].table;
339 if (fdt_check_header(fdt) != 0) {
340 pr_efi_err(sys_table, "Invalid header detected on UEFI supplied FDT, ignoring ...\n");
341 return NULL;
342 }
343 *fdt_size = fdt_totalsize(fdt);
339 break; 344 break;
340 } 345 }
341 346