git: a2e28ba79238 - main - kboot: Support reading the smbios vis sysfs
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 18 Aug 2025 09:46:10 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=a2e28ba79238ef5842db7e4581ed85c2fb63c317
commit a2e28ba79238ef5842db7e4581ed85c2fb63c317
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-07-25 02:07:17 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-07-30 18:35:29 +0000
kboot: Support reading the smbios vis sysfs
When reading the smbios on Linux we try to access it via /dev/mem. On
some systems we can't do this as /dev/mem is locked down. To handle
this try reading the sysfs file first, and if that fails fall back to
/dev/mem.
Reviewed by: imp
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D51413
---
stand/kboot/kboot/main.c | 49 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 43 insertions(+), 6 deletions(-)
diff --git a/stand/kboot/kboot/main.c b/stand/kboot/kboot/main.c
index a8c725a514be..4a136b42a4a1 100644
--- a/stand/kboot/kboot/main.c
+++ b/stand/kboot/kboot/main.c
@@ -229,6 +229,7 @@ static struct mapping
uintptr_t pa;
caddr_t va;
} map[MAX_MAP];
+static bool smbios_mmap_file;
static int smbios_fd;
static int nmap;
@@ -238,12 +239,17 @@ caddr_t ptov(uintptr_t pa)
uintptr_t pa2;
struct mapping *m = map;
- pa2 = rounddown(pa, PAGE);
+ if (smbios_mmap_file)
+ pa2 = rounddown(pa, PAGE);
+ else
+ pa2 = pa;
for (int i = 0; i < nmap; i++, m++) {
if (m->pa == pa2) {
return (m->va + pa - m->pa);
}
}
+ if (!smbios_mmap_file)
+ panic("Out of bounds smbios access");
if (nmap == MAX_MAP)
panic("Too many maps for smbios");
@@ -298,6 +304,7 @@ static void
find_smbios(void)
{
char buf[40];
+ void *dmi_data;
uintptr_t pa;
caddr_t va;
@@ -306,17 +313,47 @@ find_smbios(void)
if (pa == 0)
return;
+ dmi_data = NULL;
+ smbios_fd = host_open("/sys/firmware/dmi/tables/DMI", O_RDONLY, 0);
+ if (smbios_fd >= 0) {
+ struct host_kstat sb;
+ struct mapping *m;
+
+ if (host_fstat(smbios_fd, &sb) < 0) {
+ host_close(smbios_fd);
+ goto try_dev_mem;
+ }
+
+ dmi_data = malloc(sb.st_size);
+ if (dmi_data == NULL) {
+ host_close(smbios_fd);
+ goto try_dev_mem;
+ }
+
+ host_read(smbios_fd, dmi_data, sb.st_size);
+
+ m = &map[nmap++];
+ m->pa = pa;
+ m->va = dmi_data;
+ smbios_mmap_file = false;
+ } else {
+try_dev_mem:
+ smbios_fd = host_open("/dev/mem", O_RDONLY, 0);
+ if (smbios_fd < 0) {
+ printf("Can't open /sys/firmware/dmi/tables/DMI or "
+ "/dev/mem to read smbios\n");
+ return;
+ }
+ smbios_mmap_file = true;
+ }
snprintf(buf, sizeof(buf), "%#jx", (uintmax_t)pa);
setenv("hint.smbios.0.mem", buf, 1);
- smbios_fd = host_open("/dev/mem", O_RDONLY, 0);
- if (smbios_fd < 0) {
- printf("Can't open /dev/mem to read smbios\n");
- return;
- }
+
va = ptov(pa);
printf("Start of smbios at pa %p va %p\n", (void *)pa, va);
smbios_detect(va);
smbios_cleanup();
+ free(dmi_data);
host_close(smbios_fd);
}