diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-13 13:22:30 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-04-13 13:22:30 -0400 |
| commit | 9c65e12a55fea2da50f4069ec0dc47c50b7bd2bb (patch) | |
| tree | e371d6da040aaf8b56f060dd25a19b918229927e /drivers/firmware | |
| parent | 67dbb3a099d0fe04df5974edddc0b8c64a9f7529 (diff) | |
| parent | 84a87c628a12f95d8b0c86cc7b8edb28ea5edf90 (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.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 | ||
