The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=a2e28ba79238ef5842db7e4581ed85c2fb63c317
commit a2e28ba79238ef5842db7e4581ed85c2fb63c317 Author: Andrew Turner <and...@freebsd.org> AuthorDate: 2025-07-25 02:07:17 +0000 Commit: Andrew Turner <and...@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); }