aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/dmi_scan.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-09 16:12:47 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-09 16:12:47 -0500
commitb64bb1d758163814687eb3b84d74e56f04d0c9d1 (patch)
tree59f1db8b718e98d13c6cf9d3486221cfff6e7eef /drivers/firmware/dmi_scan.c
parent50569687e9c688a8688982805be6d8e3c8879042 (diff)
parenteb8a653137b7e74f7cdc01f814eb9d094a65aed9 (diff)
Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 updates from Will Deacon: "Here's the usual mixed bag of arm64 updates, also including some related EFI changes (Acked by Matt) and the MMU gather range cleanup (Acked by you). Changes include: - support for alternative instruction patching from Andre - seccomp from Akashi - some AArch32 instruction emulation, required by the Android folks - optimisations for exception entry/exit code, cmpxchg, pcpu atomics - mmu_gather range calculations moved into core code - EFI updates from Ard, including long-awaited SMBIOS support - /proc/cpuinfo fixes to align with the format used by arch/arm/ - a few non-critical fixes across the architecture" * tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (70 commits) arm64: remove the unnecessary arm64_swiotlb_init() arm64: add module support for alternatives fixups arm64: perf: Prevent wraparound during overflow arm64/include/asm: Fixed a warning about 'struct pt_regs' arm64: Provide a namespace to NCAPS arm64: bpf: lift restriction on last instruction arm64: Implement support for read-mostly sections arm64: compat: align cacheflush syscall with arch/arm arm64: add seccomp support arm64: add SIGSYS siginfo for compat task arm64: add seccomp syscall for compat task asm-generic: add generic seccomp.h for secure computing mode 1 arm64: ptrace: allow tracer to skip a system call arm64: ptrace: add NT_ARM_SYSTEM_CALL regset arm64: Move some head.text functions to executable section arm64: jump labels: NOP out NOP -> NOP replacement arm64: add support to dump the kernel page tables arm64: Add FIX_HOLE to permanent fixed addresses arm64: alternatives: fix pr_fmt string for consistency arm64: vmlinux.lds.S: don't discard .exit.* sections at link-time ...
Diffstat (limited to 'drivers/firmware/dmi_scan.c')
-rw-r--r--drivers/firmware/dmi_scan.c79
1 files changed, 72 insertions, 7 deletions
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 17afc51f3054..c5f7b4e9eb6c 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -93,6 +93,12 @@ static void dmi_table(u8 *buf, int len, int num,
93 const struct dmi_header *dm = (const struct dmi_header *)data; 93 const struct dmi_header *dm = (const struct dmi_header *)data;
94 94
95 /* 95 /*
96 * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0]
97 */
98 if (dm->type == DMI_ENTRY_END_OF_TABLE)
99 break;
100
101 /*
96 * We want to know the total length (formatted area and 102 * We want to know the total length (formatted area and
97 * strings) before decoding to make sure we won't run off the 103 * strings) before decoding to make sure we won't run off the
98 * table in dmi_decode or dmi_string 104 * table in dmi_decode or dmi_string
@@ -107,7 +113,7 @@ static void dmi_table(u8 *buf, int len, int num,
107 } 113 }
108} 114}
109 115
110static u32 dmi_base; 116static phys_addr_t dmi_base;
111static u16 dmi_len; 117static u16 dmi_len;
112static u16 dmi_num; 118static u16 dmi_num;
113 119
@@ -467,7 +473,7 @@ static int __init dmi_present(const u8 *buf)
467 473
468 if (memcmp(buf, "_SM_", 4) == 0 && 474 if (memcmp(buf, "_SM_", 4) == 0 &&
469 buf[5] < 32 && dmi_checksum(buf, buf[5])) { 475 buf[5] < 32 && dmi_checksum(buf, buf[5])) {
470 smbios_ver = (buf[6] << 8) + buf[7]; 476 smbios_ver = get_unaligned_be16(buf + 6);
471 477
472 /* Some BIOS report weird SMBIOS version, fix that up */ 478 /* Some BIOS report weird SMBIOS version, fix that up */
473 switch (smbios_ver) { 479 switch (smbios_ver) {
@@ -489,10 +495,9 @@ static int __init dmi_present(const u8 *buf)
489 buf += 16; 495 buf += 16;
490 496
491 if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) { 497 if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) {
492 dmi_num = (buf[13] << 8) | buf[12]; 498 dmi_num = get_unaligned_le16(buf + 12);
493 dmi_len = (buf[7] << 8) | buf[6]; 499 dmi_len = get_unaligned_le16(buf + 6);
494 dmi_base = (buf[11] << 24) | (buf[10] << 16) | 500 dmi_base = get_unaligned_le32(buf + 8);
495 (buf[9] << 8) | buf[8];
496 501
497 if (dmi_walk_early(dmi_decode) == 0) { 502 if (dmi_walk_early(dmi_decode) == 0) {
498 if (smbios_ver) { 503 if (smbios_ver) {
@@ -514,12 +519,72 @@ static int __init dmi_present(const u8 *buf)
514 return 1; 519 return 1;
515} 520}
516 521
522/*
523 * Check for the SMBIOS 3.0 64-bit entry point signature. Unlike the legacy
524 * 32-bit entry point, there is no embedded DMI header (_DMI_) in here.
525 */
526static int __init dmi_smbios3_present(const u8 *buf)
527{
528 if (memcmp(buf, "_SM3_", 5) == 0 &&
529 buf[6] < 32 && dmi_checksum(buf, buf[6])) {
530 dmi_ver = get_unaligned_be16(buf + 7);
531 dmi_len = get_unaligned_le32(buf + 12);
532 dmi_base = get_unaligned_le64(buf + 16);
533
534 /*
535 * The 64-bit SMBIOS 3.0 entry point no longer has a field
536 * containing the number of structures present in the table.
537 * Instead, it defines the table size as a maximum size, and
538 * relies on the end-of-table structure type (#127) to be used
539 * to signal the end of the table.
540 * So let's define dmi_num as an upper bound as well: each
541 * structure has a 4 byte header, so dmi_len / 4 is an upper
542 * bound for the number of structures in the table.
543 */
544 dmi_num = dmi_len / 4;
545
546 if (dmi_walk_early(dmi_decode) == 0) {
547 pr_info("SMBIOS %d.%d present.\n",
548 dmi_ver >> 8, dmi_ver & 0xFF);
549 dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string));
550 pr_debug("DMI: %s\n", dmi_ids_string);
551 return 0;
552 }
553 }
554 return 1;
555}
556
517void __init dmi_scan_machine(void) 557void __init dmi_scan_machine(void)
518{ 558{
519 char __iomem *p, *q; 559 char __iomem *p, *q;
520 char buf[32]; 560 char buf[32];
521 561
522 if (efi_enabled(EFI_CONFIG_TABLES)) { 562 if (efi_enabled(EFI_CONFIG_TABLES)) {
563 /*
564 * According to the DMTF SMBIOS reference spec v3.0.0, it is
565 * allowed to define both the 64-bit entry point (smbios3) and
566 * the 32-bit entry point (smbios), in which case they should
567 * either both point to the same SMBIOS structure table, or the
568 * table pointed to by the 64-bit entry point should contain a
569 * superset of the table contents pointed to by the 32-bit entry
570 * point (section 5.2)
571 * This implies that the 64-bit entry point should have
572 * precedence if it is defined and supported by the OS. If we
573 * have the 64-bit entry point, but fail to decode it, fall
574 * back to the legacy one (if available)
575 */
576 if (efi.smbios3 != EFI_INVALID_TABLE_ADDR) {
577 p = dmi_early_remap(efi.smbios3, 32);
578 if (p == NULL)
579 goto error;
580 memcpy_fromio(buf, p, 32);
581 dmi_early_unmap(p, 32);
582
583 if (!dmi_smbios3_present(buf)) {
584 dmi_available = 1;
585 goto out;
586 }
587 }
523 if (efi.smbios == EFI_INVALID_TABLE_ADDR) 588 if (efi.smbios == EFI_INVALID_TABLE_ADDR)
524 goto error; 589 goto error;
525 590
@@ -552,7 +617,7 @@ void __init dmi_scan_machine(void)
552 memset(buf, 0, 16); 617 memset(buf, 0, 16);
553 for (q = p; q < p + 0x10000; q += 16) { 618 for (q = p; q < p + 0x10000; q += 16) {
554 memcpy_fromio(buf + 16, q, 16); 619 memcpy_fromio(buf + 16, q, 16);
555 if (!dmi_present(buf)) { 620 if (!dmi_smbios3_present(buf) || !dmi_present(buf)) {
556 dmi_available = 1; 621 dmi_available = 1;
557 dmi_early_unmap(p, 0x10000); 622 dmi_early_unmap(p, 0x10000);
558 goto out; 623 goto out;