Skip to contentSkip to conversation

dmi, Use little-endian for sysfs PRODUCT UUID

PATCH In review Prarit Bhargava 2 participants 2 messages Mar 26, 2012 – Mar 27, 2012 Dmi/smbios support

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 dmi, Use little-endian for sysfs PRODUCT UUID

I noticed this discrepancy between the output of 'dmidecode -t 1 | grep UUID' and the output of /sys/class/dmi/id/product_uuid:

[root@intel-mahobay-01 ~]# cat /sys/class/dmi/id/product_uuid 001320FB-4C2D-0013-20FB-4C2D001320FB [root@intel-mahobay-01 ~]# dmidecode | grep UUID

        UUID: FB201300-2D4C-1300-20FB-4C2D001320FB

Section 7.2.1, "System -- UUID" of the SMBIOS Specification (version 2.7.1) states:

Although RFC 4122 recommends network byte order for all fields, the PC industry (including the ACPI, UEFI, and Microsoft specifications) has consistently used little-endian byte encoding for the first three
fields: time_low, time_mid, time_hi_and_version. The same encoding, also known as wire format, should also be used for the SMBIOS representation of the UUID.

The UUID {00112233-4455-6677-8899-AABBCCDDEEFF} would thus be represented as:

33 22 11 00 55 44 77 66 88 99 AA BB CC DD EE FF.

However, A comment in the dmidecode utility contains the following warning:

* As of version 2.6 of the SMBIOS specification, the first 3
* fields of the UUID are supposed to be encoded on little-endian.
* The specification says that this is the defacto standard,
* however I've seen systems following RFC 4122 instead and use
* network byte order, so I am reluctant to apply the byte-swapping
* for older versions.

Apply this same logic to the output of the kernel's representation for SMBIOS Product UUID.

After the patch is applied on a system with SMBIOS version 2.6,

[root@intel-mahobay-01 ~]# cat /sys/class/dmi/id/product_uuid FB201300-2D4C-1300-20FB-4C2D001320FB [root@intel-mahobay-01 ~]# dmidecode | grep UUID

	UUID: FB201300-2D4C-1300-20FB-4C2D001320FB
---
 drivers/firmware/dmi_scan.c |   21 +++++++++++++++++++--
 1 files changed, 19 insertions(+), 2 deletions(-)
drivers/firmware/dmi_scan.c +19 -2
index 153980b..ef41d90 100644
@@ -15,6 +15,9 @@
  */
 static char dmi_empty_string[] = "        ";
 
+/* SMBIOS version in MMmm format */
+static u16 smbios_version;
+
 /*
  * Catch too early calls to dmi_check_system():
  */
@@ -169,7 +172,18 @@ static void __init dmi_save_uuid(const struct dmi_header *dm, int slot, int inde
 	if (!s)
 		return;
 
-	sprintf(s, "%pUB", d);
+	/*
+	 * As of version 2.6 of the SMBIOS specification, the first 3
+	 * fields of the UUID are supposed to be encoded on little-endian.
+	 * The specification says that this is the defacto standard,
+	 * however we've seen systems following RFC 4122 instead and use
+	 * network byte order, so do not apply the byte-swapping
+	 * for older versions.
+	 */
+	if (smbios_version >= 0x0206)
+		sprintf(s, "%pUL", d);
+	else
+		sprintf(s, "%pUB", d);
 
         dmi_ident[slot] = s;
 }
@@ -411,9 +425,12 @@ static int __init dmi_present(const char __iomem *p)
 		 * DMI version 0.0 means that the real version is taken from
 		 * the SMBIOS version, which we don't know at this point.
 		 */
-		if (buf[14] != 0)
+		if (buf[14] != 0){
 			printk(KERN_INFO "DMI %d.%d present.\n",
 			       buf[14] >> 4, buf[14] & 0xF);
+			smbios_version = (((buf[14] >> 4) << 8) +
+					  (buf[14] & 0xF));
+		}
 		else
 			printk(KERN_INFO "DMI present.\n");
 		if (dmi_walk_early(dmi_decode) == 0) {
Signature · 1 line
1.7.1
#1 lore raw
Quoted 6 lines · Prarit Bhargava

Although RFC 4122 recommends network byte order for all fields, the PC industry (including the ACPI, UEFI, and Microsoft specifications) has consistently used little-endian byte encoding for the first three
fields: time_low, time_mid, time_hi_and_version. The same encoding, also known as wire format, should also be used for the SMBIOS representation of the UUID.

There's some potential for breakage here. Perhaps add an additional attribute that adds the purely little-endian UUID?

Signature · 1 line
Matthew Garrett | [email protected]