aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorJean Delvare <jdelvare@suse.de>2015-05-14 08:40:50 -0400
committerJean Delvare <jdelvare@suse.de>2015-05-14 08:40:50 -0400
commit5c1ac56b51b9d222ab202dec1ac2f4215346129d (patch)
tree4daf770cdb2e3eca28fd6355fe86acc27208dc66 /drivers/firmware
parentc24930457d4b06903aa5dada50e04a83513e3b6b (diff)
firmware: dmi_scan: Fix ordering of product_uuid
In function dmi_present(), dmi_walk_early() calls dmi_table(), which calls dmi_decode(), which ultimately calls dmi_save_uuid(). This last function makes a decision based on the value of global variable dmi_ver. The problem is that this variable is set right _after_ dmi_walk_early() returns. So dmi_save_uuid() always sees dmi_ver == 0 regardless of the actual version implemented. This causes /sys/class/dmi/id/product_uuid to always use the old ordering even on systems implementing DMI/SMBIOS 2.6 or later, which should use the new ordering. This is broken since kernel v3.8 for legacy DMI implementations and since kernel v3.10 for SMBIOS 2 implementations. SMBIOS 3 implementations with the 64-bit entry point are not affected. The first breakage does not matter much as in practice legacy DMI implementations are always for versions older than 2.6, which is when the UUID ordering changed. The second breakage is more problematic as it affects the vast majority of x86 systems manufactured since 2009. Signed-off-by: Jean Delvare <jdelvare@suse.de> Fixes: 9f9c9cbb6057 ("drivers/firmware/dmi_scan.c: fetch dmi version from SMBIOS if it exists") Fixes: 79bae42d51a5 ("dmi_scan: refactor dmi_scan_machine(), {smbios,dmi}_present()") Acked-by: Zhenzhong Duan <zhenzhong.duan@oracle.com> Cc: Ben Hutchings <ben@decadent.org.uk> Cc: Artem Savkov <artem.savkov@gmail.com> Cc: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> Cc: Matt Fleming <matt.fleming@intel.com> Cc: stable@vger.kernel.org [v3.10+]
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/dmi_scan.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 5ebb6ceeabfc..97b1616aa391 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -499,18 +499,19 @@ static int __init dmi_present(const u8 *buf)
499 buf += 16; 499 buf += 16;
500 500
501 if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) { 501 if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
502 if (smbios_ver)
503 dmi_ver = smbios_ver;
504 else
505 dmi_ver = (buf[14] & 0xF0) << 4 | (buf[14] & 0x0F);
502 dmi_num = get_unaligned_le16(buf + 12); 506 dmi_num = get_unaligned_le16(buf + 12);
503 dmi_len = get_unaligned_le16(buf + 6); 507 dmi_len = get_unaligned_le16(buf + 6);
504 dmi_base = get_unaligned_le32(buf + 8); 508 dmi_base = get_unaligned_le32(buf + 8);
505 509
506 if (dmi_walk_early(dmi_decode) == 0) { 510 if (dmi_walk_early(dmi_decode) == 0) {
507 if (smbios_ver) { 511 if (smbios_ver) {
508 dmi_ver = smbios_ver;
509 pr_info("SMBIOS %d.%d present.\n", 512 pr_info("SMBIOS %d.%d present.\n",
510 dmi_ver >> 8, dmi_ver & 0xFF); 513 dmi_ver >> 8, dmi_ver & 0xFF);
511 } else { 514 } else {
512 dmi_ver = (buf[14] & 0xF0) << 4 |
513 (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 }