05ad79
From 6999f3f3ca525bb6b132f4ed804e7f8fe62e5f79 Mon Sep 17 00:00:00 2001
05ad79
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
05ad79
Date: Wed, 12 Apr 2017 10:11:29 +0100
05ad79
Subject: [PATCH] lscpu: use sysfs for table access if available
05ad79
05ad79
On ARM systems, accessing SMBIOS tables via /dev/mem using read()
05ad79
calls is not supported. The reason is that such tables are usually
05ad79
located in EFI_RUNTIME_SERVICE_DATA memory, which is not covered
05ad79
by the linear mapping on those systems, and so read() calls will
05ad79
fail.
05ad79
05ad79
So instead, use the /sys/firmware/dmi/tables/DMI sysfs file, which
05ad79
contains the entire structure table array, and will be available
05ad79
on any recent Linux system, even on ones that only export the rev3
05ad79
SMBIOS entry point, which is currently ignored by lscpu.
05ad79
05ad79
Note that the max 'num' value is inferred from the size. This is not
05ad79
a limitation of the sysfs interface, but a limitation of the rev3
05ad79
entry point, which no longer carries a number of array elements.
05ad79
05ad79
Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1455664
05ad79
Upstream: http://github.com/karelzak/util-linux/commit/92a6392c41c11bcb49af9f129dfbd1fed651f044
05ad79
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
05ad79
Tested-by: Alexander Graf <agraf@suse.de>
05ad79
Reviewed-by: Alexander Graf <agraf@suse.de>
05ad79
---
05ad79
 sys-utils/lscpu-dmi.c | 16 ++++++++++++++++
05ad79
 1 file changed, 16 insertions(+)
05ad79
05ad79
diff --git a/sys-utils/lscpu-dmi.c b/sys-utils/lscpu-dmi.c
05ad79
index 0e497d1..a8298ff 100644
05ad79
--- a/sys-utils/lscpu-dmi.c
05ad79
+++ b/sys-utils/lscpu-dmi.c
05ad79
@@ -192,6 +192,18 @@ static int hypervisor_decode_smbios(uint8_t *buf, const char *devmem)
05ad79
 		devmem);
05ad79
 }
05ad79
 
05ad79
+static int hypervisor_decode_sysfw(void)
05ad79
+{
05ad79
+	static char const sys_fw_dmi_tables[] = "/sys/firmware/dmi/tables/DMI";
05ad79
+	struct stat st;
05ad79
+
05ad79
+	if (stat(sys_fw_dmi_tables, &st))
05ad79
+		return -1;
05ad79
+
05ad79
+	return hypervisor_from_dmi_table(0, st.st_size, st.st_size / 4,
05ad79
+					 sys_fw_dmi_tables);
05ad79
+}
05ad79
+
05ad79
 /*
05ad79
  * Probe for EFI interface
05ad79
  */
05ad79
@@ -242,6 +254,10 @@ int read_hypervisor_dmi(void)
05ad79
 	    || '\0' != 0)
05ad79
 		return rc;
05ad79
 
05ad79
+	rc = hypervisor_decode_sysfw();
05ad79
+	if (rc >= 0)
05ad79
+		return rc;
05ad79
+
05ad79
 	/* First try EFI (ia64, Intel-based Mac) */
05ad79
 	switch (address_from_efi(&fp)) {
05ad79
 		case EFI_NOT_FOUND:
05ad79
-- 
05ad79
2.9.4
05ad79