Skip to content

Commit 79bae42

Browse files
bwhackstorvalds
authored andcommitted
dmi_scan: refactor dmi_scan_machine(), {smbios,dmi}_present()
Move the calls to memcpy_fromio() up into the loop in dmi_scan_machine(), and move the signature checks back down into dmi_decode(). We need to check at 16-byte intervals but keep a 32-byte buffer for an SMBIOS entry, so shift the buffer after each iteration. Merge smbios_present() into dmi_present(), so we look for an SMBIOS signature at the beginning of the given buffer and then for a DMI signature at an offset of 16 bytes. [artem.savkov@gmail.com: use proper buf type in dmi_present()] Signed-off-by: Ben Hutchings <ben@decadent.org.uk> Reported-by: Tim McGrath <tmhikaru@gmail.com> Tested-by: Tim Mcgrath <tmhikaru@gmail.com> Cc: Zhenzhong Duan <zhenzhong.duan@oracle.com> Signed-off-by: Artem Savkov <artem.savkov@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent c1d025e commit 79bae42

File tree

1 file changed

+37
-43
lines changed

1 file changed

+37
-43
lines changed

drivers/firmware/dmi_scan.c

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -419,22 +419,45 @@ static void __init dmi_format_ids(char *buf, size_t len)
419419
dmi_get_system_info(DMI_BIOS_DATE));
420420
}
421421

422-
static int __init dmi_present(const char __iomem *p)
422+
static int __init dmi_present(const u8 *buf)
423423
{
424-
u8 buf[15];
424+
int smbios_ver;
425425

426-
memcpy_fromio(buf, p, 15);
427-
if (dmi_checksum(buf, 15)) {
426+
if (memcmp(buf, "_SM_", 4) == 0 &&
427+
buf[5] < 32 && dmi_checksum(buf, buf[5])) {
428+
smbios_ver = (buf[6] << 8) + buf[7];
429+
430+
/* Some BIOS report weird SMBIOS version, fix that up */
431+
switch (smbios_ver) {
432+
case 0x021F:
433+
case 0x0221:
434+
pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
435+
smbios_ver & 0xFF, 3);
436+
smbios_ver = 0x0203;
437+
break;
438+
case 0x0233:
439+
pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
440+
smbios_ver = 0x0206;
441+
break;
442+
}
443+
} else {
444+
smbios_ver = 0;
445+
}
446+
447+
buf += 16;
448+
449+
if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
428450
dmi_num = (buf[13] << 8) | buf[12];
429451
dmi_len = (buf[7] << 8) | buf[6];
430452
dmi_base = (buf[11] << 24) | (buf[10] << 16) |
431453
(buf[9] << 8) | buf[8];
432454

433455
if (dmi_walk_early(dmi_decode) == 0) {
434-
if (dmi_ver)
456+
if (smbios_ver) {
457+
dmi_ver = smbios_ver;
435458
pr_info("SMBIOS %d.%d present.\n",
436459
dmi_ver >> 8, dmi_ver & 0xFF);
437-
else {
460+
} else {
438461
dmi_ver = (buf[14] & 0xF0) << 4 |
439462
(buf[14] & 0x0F);
440463
pr_info("Legacy DMI %d.%d present.\n",
@@ -445,40 +468,14 @@ static int __init dmi_present(const char __iomem *p)
445468
return 0;
446469
}
447470
}
448-
dmi_ver = 0;
449-
return 1;
450-
}
451471

452-
static int __init smbios_present(const char __iomem *p)
453-
{
454-
u8 buf[32];
455-
456-
memcpy_fromio(buf, p, 32);
457-
if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) {
458-
dmi_ver = (buf[6] << 8) + buf[7];
459-
460-
/* Some BIOS report weird SMBIOS version, fix that up */
461-
switch (dmi_ver) {
462-
case 0x021F:
463-
case 0x0221:
464-
pr_debug("SMBIOS version fixup(2.%d->2.%d)\n",
465-
dmi_ver & 0xFF, 3);
466-
dmi_ver = 0x0203;
467-
break;
468-
case 0x0233:
469-
pr_debug("SMBIOS version fixup(2.%d->2.%d)\n", 51, 6);
470-
dmi_ver = 0x0206;
471-
break;
472-
}
473-
return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16);
474-
}
475472
return 1;
476473
}
477474

478475
void __init dmi_scan_machine(void)
479476
{
480477
char __iomem *p, *q;
481-
int rc;
478+
char buf[32];
482479

483480
if (efi_enabled(EFI_CONFIG_TABLES)) {
484481
if (efi.smbios == EFI_INVALID_TABLE_ADDR)
@@ -491,10 +488,10 @@ void __init dmi_scan_machine(void)
491488
p = dmi_ioremap(efi.smbios, 32);
492489
if (p == NULL)
493490
goto error;
494-
495-
rc = smbios_present(p);
491+
memcpy_fromio(buf, p, 32);
496492
dmi_iounmap(p, 32);
497-
if (!rc) {
493+
494+
if (!dmi_present(buf)) {
498495
dmi_available = 1;
499496
goto out;
500497
}
@@ -509,18 +506,15 @@ void __init dmi_scan_machine(void)
509506
if (p == NULL)
510507
goto error;
511508

509+
memset(buf, 0, 16);
512510
for (q = p; q < p + 0x10000; q += 16) {
513-
if (memcmp(q, "_SM_", 4) == 0 && q - p <= 0xFFE0)
514-
rc = smbios_present(q);
515-
else if (memcmp(q, "_DMI_", 5) == 0)
516-
rc = dmi_present(q);
517-
else
518-
continue;
519-
if (!rc) {
511+
memcpy_fromio(buf + 16, q, 16);
512+
if (!dmi_present(buf)) {
520513
dmi_available = 1;
521514
dmi_iounmap(p, 0x10000);
522515
goto out;
523516
}
517+
memcpy(buf, buf + 16, 16);
524518
}
525519
dmi_iounmap(p, 0x10000);
526520
}

0 commit comments

Comments
 (0)