diff options
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/dmi_scan.c | 38 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/arm-stub.c | 7 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/efistub.h | 2 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/fdt.c | 7 |
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 | */ |
18 | static const char dmi_empty_string[] = " "; | 18 | static const char dmi_empty_string[] = " "; |
19 | 19 | ||
20 | static u16 __initdata dmi_ver; | 20 | static u32 dmi_ver __initdata; |
21 | static u32 dmi_len; | ||
22 | static 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 | */ |
81 | static void dmi_table(u8 *buf, u32 len, int num, | 83 | static 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 | ||
120 | static phys_addr_t dmi_base; | 122 | static phys_addr_t dmi_base; |
121 | static u32 dmi_len; | ||
122 | static u16 dmi_num; | ||
123 | 123 | ||
124 | static int __init dmi_walk_early(void (*decode)(const struct dmi_header *, | 124 | static 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 | */ |
474 | static int __init dmi_present(const u8 *buf) | 474 | static 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 | ||
44 | void *get_fdt(efi_system_table_t *sys_table); | 44 | void *get_fdt(efi_system_table_t *sys_table, unsigned long *fdt_size); |
45 | 45 | ||
46 | void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, | 46 | void 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 | ||
326 | void *get_fdt(efi_system_table_t *sys_table) | 326 | void *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 | ||