146 lines
4.1 KiB
Diff
146 lines
4.1 KiB
Diff
|
From b3bb4ed21e8802cb38eb693952da058f52cf76b0 Mon Sep 17 00:00:00 2001
|
||
|
From: Takashi Iwai <tiwai@suse.de>
|
||
|
Date: Mon, 24 Aug 2020 14:41:54 +0200
|
||
|
Subject: [PATCH] Read DMI entries from /sys/firmware/dmi/tables/DMI
|
||
|
|
||
|
A kernel with Secure Boot lockdown may prohibit reading the contents
|
||
|
of /dev/mem, hence biosdevname fails. The recent kernel provides the
|
||
|
DMI byte contents in /sys/firmware/dmi/tables/*, and we can use this
|
||
|
instead of poking /dev/mem.
|
||
|
|
||
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||
|
CC: Thomas Renninger <trenn@suse.de>
|
||
|
CC: Michal Suchanek <msuchanek@suse.com>
|
||
|
---
|
||
|
src/dmidecode/dmidecode.c | 54 +++++++++++++++++++++++++++++----------
|
||
|
1 file changed, 41 insertions(+), 13 deletions(-)
|
||
|
|
||
|
diff --git a/src/dmidecode/dmidecode.c b/src/dmidecode/dmidecode.c
|
||
|
index a01a6ce..f4c1269 100644
|
||
|
--- a/src/dmidecode/dmidecode.c
|
||
|
+++ b/src/dmidecode/dmidecode.c
|
||
|
@@ -229,7 +229,7 @@ static int isvalidsmbios(int mjr, int mnr)
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, const struct libbiosdevname_state *state)
|
||
|
+static int dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, const struct libbiosdevname_state *state, int sysfs)
|
||
|
{
|
||
|
u8 *buf;
|
||
|
u8 *data;
|
||
|
@@ -237,14 +237,19 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, c
|
||
|
|
||
|
/* Verify SMBIOS version */
|
||
|
if (!isvalidsmbios(ver >> 8, ver & 0xFF)) {
|
||
|
- return;
|
||
|
+ return 0;
|
||
|
}
|
||
|
- if((buf=mem_chunk(base, len, devmem))==NULL)
|
||
|
+
|
||
|
+ if (sysfs)
|
||
|
+ buf = __mem_chunk(0, len, devmem, 0);
|
||
|
+ else
|
||
|
+ buf = mem_chunk(base, len, devmem);
|
||
|
+ if(buf == NULL)
|
||
|
{
|
||
|
#ifndef USE_MMAP
|
||
|
printf("Table is unreachable, sorry. Try compiling dmidecode with -DUSE_MMAP.\n");
|
||
|
#endif
|
||
|
- return;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
data=buf;
|
||
|
@@ -280,18 +285,18 @@ static void dmi_table(u32 base, u16 len, u16 num, u16 ver, const char *devmem, c
|
||
|
i++;
|
||
|
}
|
||
|
free(buf);
|
||
|
+ return 1;
|
||
|
}
|
||
|
|
||
|
-
|
||
|
-static int smbios_decode(u8 *buf, const char *devmem, const struct libbiosdevname_state *state)
|
||
|
+static int smbios_decode(u8 *buf, const char *devmem, const struct libbiosdevname_state *state, int sysfs)
|
||
|
{
|
||
|
if(checksum(buf, buf[0x05])
|
||
|
&& memcmp(buf+0x10, "_DMI_", 5)==0
|
||
|
&& checksum(buf+0x10, 0x0F))
|
||
|
{
|
||
|
- dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C),
|
||
|
- (buf[0x06]<<8)+buf[0x07], devmem, state);
|
||
|
- return 1;
|
||
|
+ return dmi_table(DWORD(buf+0x18), WORD(buf+0x16), WORD(buf+0x1C),
|
||
|
+ (buf[0x06]<<8)+buf[0x07], devmem, state,
|
||
|
+ sysfs);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
@@ -302,13 +307,32 @@ static int legacy_decode(u8 *buf, const char *devmem, const struct libbiosdevnam
|
||
|
if(checksum(buf, 0x0F))
|
||
|
{
|
||
|
dmi_table(DWORD(buf+0x08), WORD(buf+0x06), WORD(buf+0x0C),
|
||
|
- ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, state);
|
||
|
+ ((buf[0x0E]&0xF0)<<4)+(buf[0x0E]&0x0F), devmem, state, 0);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
+#define SYSFS_TABLE_SMBIOS "/sys/firmware/dmi/tables/smbios_entry_point"
|
||
|
+#define SYSFS_TABLE_DMI "/sys/firmware/dmi/tables/DMI"
|
||
|
+
|
||
|
+static int smibios_decode_from_sysfs(const struct libbiosdevname_state *state)
|
||
|
+{
|
||
|
+ FILE *fp;
|
||
|
+ u8 buf[0x1f];
|
||
|
+ int len;
|
||
|
+
|
||
|
+ fp = fopen(SYSFS_TABLE_SMBIOS, "r");
|
||
|
+ if (!fp)
|
||
|
+ return 0;
|
||
|
+ len = fread(buf, 1, sizeof(buf), fp);
|
||
|
+ fclose(fp);
|
||
|
+ if (len == 0x1f && memcmp(buf, "_SM_", 4) == 0)
|
||
|
+ return smbios_decode(buf, SYSFS_TABLE_DMI, state, 1);
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
/*
|
||
|
* Probe for EFI interface
|
||
|
*/
|
||
|
@@ -417,7 +441,11 @@ int dmidecode_main(const struct libbiosdevname_state *state)
|
||
|
if (dmidecode_read_file(state))
|
||
|
return 0;
|
||
|
|
||
|
- /* First try EFI (ia64, Intel-based Mac) */
|
||
|
+ /* First try sysfs entries */
|
||
|
+ if (smibios_decode_from_sysfs(state))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ /* Next try EFI (ia64, Intel-based Mac) */
|
||
|
efi=address_from_efi(&fp);
|
||
|
switch(efi)
|
||
|
{
|
||
|
@@ -434,7 +462,7 @@ int dmidecode_main(const struct libbiosdevname_state *state)
|
||
|
goto exit_free;
|
||
|
}
|
||
|
|
||
|
- if(smbios_decode(buf, devmem, state))
|
||
|
+ if(smbios_decode(buf, devmem, state, 0))
|
||
|
found++;
|
||
|
goto done;
|
||
|
|
||
|
@@ -450,7 +478,7 @@ memory_scan:
|
||
|
{
|
||
|
if(memcmp(buf+fp, "_SM_", 4)==0 && fp<=0xFFE0)
|
||
|
{
|
||
|
- if(smbios_decode(buf+fp, devmem, state))
|
||
|
+ if(smbios_decode(buf+fp, devmem, state, 0))
|
||
|
{
|
||
|
found++;
|
||
|
fp+=16;
|
||
|
--
|
||
|
2.44.0
|
||
|
|