From patchwork Wed Oct 29 15:11:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 39786 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id CFFC924029 for ; Wed, 29 Oct 2014 15:15:48 +0000 (UTC) Received: by mail-la0-f69.google.com with SMTP id q1sf1834678lam.8 for ; Wed, 29 Oct 2014 08:15:47 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:cc:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version:sender :errors-to:x-original-sender:x-original-authentication-results :mailing-list:content-type:content-transfer-encoding; bh=jCDAtU8pmKymkxtAMy42zRDy+r+k/K+Gogb3X1p2GF0=; b=jXMHBeP52k/vHUQTRrflK5KLoLxz+zw1eazTagYQE5BDRWeQXQJYEOwwDyjOuK0asD nLNzxY7NCtzridk/P2Meetuc219CXDBAsbEGZwhAdHKP88O5Ct6kqW5DLagAyPvDSMp5 /rtlArTeH8PU9PoqZ/GjwGLQTgCQpxpEYuDDLYtSAXg0N42VsAIXxYT1u8/rf2X9loR0 c4KZMib4AMEfsdT1MAyM4JZwNxmYzBv8t+6fRUHEKljEssXvXqOAe3a7/UHAPIEDBASy BhhNQCJZlG3WLJhhgpfEozm09Rv1IMnfA24rX2g1PX64gLZwPtMBHOQCVuu7s+BQoaRX QEhQ== X-Gm-Message-State: ALoCoQk3edFiJw/azAmZ9yMhjBvEBaE6HV2NejcJJdmb8Vsve7sZHByh7x2wGQVZ0uIa/ClXnLpE X-Received: by 10.112.247.74 with SMTP id yc10mr1774617lbc.8.1414595747298; Wed, 29 Oct 2014 08:15:47 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.23.7 with SMTP id i7ls174849laf.47.gmail; Wed, 29 Oct 2014 08:15:47 -0700 (PDT) X-Received: by 10.152.27.1 with SMTP id p1mr5907478lag.55.1414595747150; Wed, 29 Oct 2014 08:15:47 -0700 (PDT) Received: from mail-la0-f44.google.com (mail-la0-f44.google.com. [209.85.215.44]) by mx.google.com with ESMTPS id s2si7688116lag.22.2014.10.29.08.15.47 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 Oct 2014 08:15:47 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) client-ip=209.85.215.44; Received: by mail-la0-f44.google.com with SMTP id gf13so2713207lab.31 for ; Wed, 29 Oct 2014 08:15:47 -0700 (PDT) X-Received: by 10.112.97.135 with SMTP id ea7mr12193675lbb.46.1414595747015; Wed, 29 Oct 2014 08:15:47 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.84.229 with SMTP id c5csp677609lbz; Wed, 29 Oct 2014 08:15:45 -0700 (PDT) X-Received: by 10.69.20.74 with SMTP id ha10mr7292057pbd.122.1414595744919; Wed, 29 Oct 2014 08:15:44 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id cc5si4159607pad.223.2014.10.29.08.15.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 29 Oct 2014 08:15:44 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XjUwz-0002ZY-3H; Wed, 29 Oct 2014 15:14:17 +0000 Received: from mail-wi0-f177.google.com ([209.85.212.177]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XjUuf-0000Gd-Ub for linux-arm-kernel@lists.infradead.org; Wed, 29 Oct 2014 15:11:55 +0000 Received: by mail-wi0-f177.google.com with SMTP id ex7so4876021wid.10 for ; Wed, 29 Oct 2014 08:11:29 -0700 (PDT) X-Received: by 10.180.74.237 with SMTP id x13mr13698115wiv.6.1414595489670; Wed, 29 Oct 2014 08:11:29 -0700 (PDT) Received: from ards-macbook-pro.local (cag06-7-83-153-85-71.fbx.proxad.net. [83.153.85.71]) by mx.google.com with ESMTPSA id fv2sm5851575wib.2.2014.10.29.08.11.27 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Wed, 29 Oct 2014 08:11:28 -0700 (PDT) From: Ard Biesheuvel To: leif.lindholm@linaro.org, roy.franz@linaro.org, msalter@redhat.com, mark.rutland@arm.com, will.deacon@arm.com, catalin.marinas@arm.com, matt.fleming@intel.com, linux-efi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, dyoung@redhat.com, yi.li@linaro.org Subject: [PATCH v2] dmi: add support for SMBIOS 3.0 64-bit entry point Date: Wed, 29 Oct 2014 16:11:25 +0100 Message-Id: <1414595485-5723-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 1.8.3.2 In-Reply-To: <1414513123-20400-8-git-send-email-ard.biesheuvel@linaro.org> References: <1414513123-20400-8-git-send-email-ard.biesheuvel@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20141029_081154_320706_97ACADCE X-CRM114-Status: GOOD ( 24.44 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.212.177 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H3 RBL: Good reputation (+3) [209.85.212.177 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders Cc: Andrew Morton , Tony Luck , Ard Biesheuvel X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: ard.biesheuvel@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.44 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 The DMTF SMBIOS reference spec v3.0.0 defines a new 64-bit entry point, which enables support for SMBIOS structure tables residing at a physical offset over 4 GB. This is especially important for upcoming arm64 platforms whose system RAM resides entirely above the 4 GB boundary. For the UEFI case, this code attempts to detect the new SMBIOS 3.0 header magic at the offset passed in the SMBIOS3_TABLE_GUID UEFI configuration table. If this configuration table is not provided, or if we fail to parse the header, we fall back to using the legacy SMBIOS_TABLE_GUID configuration table. This is in line with the spec, that allows both configuration tables to be provided, but mandates that they must point to the same structure table, unless the version pointed to by the 64-bit entry point is a superset of the 32-bit one. For the non-UEFI case, the detection logic is modified to look for the SMBIOS 3.0 header magic before it looks for the legacy header magic. Note that this patch is based on version 3.0.0d [draft] of the specification, which is expected not to deviate from the final version in ways that would affect the correctness of this implementation. Tested-by: Suravee Suthikulpanit Acked-by: Leif Lindholm Cc: Andrew Morton Cc: Tony Luck Signed-off-by: Ard Biesheuvel Tested-by: Leif Lindholm --- v2: since dmi_base is now a phys_addr_t, prevent surprises caused by GCC's type promotion rules by replacing the open coded shifts/ORs with get_unaligned_leXX() --- drivers/firmware/dmi_scan.c | 79 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 17afc51f3054..f617badc2698 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, const struct dmi_header *dm = (const struct dmi_header *)data; /* + * 7.45 End-of-Table (Type 127) [SMBIOS reference spec v3.0.0] + */ + if (dm->type == 127) + break; + + /* * We want to know the total length (formatted area and * strings) before decoding to make sure we won't run off the * table in dmi_decode or dmi_string @@ -107,7 +113,7 @@ static void dmi_table(u8 *buf, int len, int num, } } -static u32 dmi_base; +static phys_addr_t dmi_base; static u16 dmi_len; static u16 dmi_num; @@ -467,7 +473,7 @@ static int __init dmi_present(const u8 *buf) if (memcmp(buf, "_SM_", 4) == 0 && buf[5] < 32 && dmi_checksum(buf, buf[5])) { - smbios_ver = (buf[6] << 8) + buf[7]; + smbios_ver = get_unaligned_be16(buf + 6); /* Some BIOS report weird SMBIOS version, fix that up */ switch (smbios_ver) { @@ -489,10 +495,9 @@ static int __init dmi_present(const u8 *buf) buf += 16; if (memcmp(buf, "_DMI_", 5) == 0 && dmi_checksum(buf, 15)) { - dmi_num = (buf[13] << 8) | buf[12]; - dmi_len = (buf[7] << 8) | buf[6]; - dmi_base = (buf[11] << 24) | (buf[10] << 16) | - (buf[9] << 8) | buf[8]; + dmi_num = get_unaligned_le16(buf + 12); + dmi_len = get_unaligned_le16(buf + 6); + dmi_base = get_unaligned_le32(buf + 8); if (dmi_walk_early(dmi_decode) == 0) { if (smbios_ver) { @@ -514,12 +519,72 @@ static int __init dmi_present(const u8 *buf) return 1; } +/* + * Check for the SMBIOS 3.0 64-bit entry point signature. Unlike the legacy + * 32-bit entry point, there is no embedded DMI header (_DMI_) in here. + */ +static int __init dmi_smbios3_present(const u8 *buf) +{ + if (memcmp(buf, "_SM3_", 5) == 0 && + buf[6] < 32 && dmi_checksum(buf, buf[6])) { + dmi_ver = get_unaligned_be16(buf + 7); + dmi_len = get_unaligned_le32(buf + 12); + dmi_base = get_unaligned_le64(buf + 16); + + /* + * The 64-bit SMBIOS 3.0 entry point no longer has a field + * containing the number of structures present in the table. + * Instead, it defines the table size as a maximum size, and + * relies on the end-of-table structure type (#127) to be used + * to signal the end of the table. + * So let's define dmi_num as an upper bound as well: each + * structure has a 4 byte header, so dmi_len / 4 is an upper + * bound for the number of structures in the table. + */ + dmi_num = dmi_len / 4; + + if (dmi_walk_early(dmi_decode) == 0) { + pr_info("SMBIOS %d.%d present.\n", + dmi_ver >> 8, dmi_ver & 0xFF); + dmi_format_ids(dmi_ids_string, sizeof(dmi_ids_string)); + pr_debug("DMI: %s\n", dmi_ids_string); + return 0; + } + } + return 1; +} + void __init dmi_scan_machine(void) { char __iomem *p, *q; char buf[32]; if (efi_enabled(EFI_CONFIG_TABLES)) { + /* + * According to the DMTF SMBIOS reference spec v3.0.0, it is + * allowed to define both the 64-bit entry point (smbios3) and + * the 32-bit entry point (smbios), in which case they should + * either both point to the same SMBIOS structure table, or the + * table pointed to by the 64-bit entry point should contain a + * superset of the table contents pointed to by the 32-bit entry + * point (section 5.2) + * This implies that the 64-bit entry point should have + * precedence if it is defined and supported by the OS. If we + * have the 64-bit entry point, but fail to decode it, fall + * back to the legacy one (if available) + */ + if (efi.smbios3 != EFI_INVALID_TABLE_ADDR) { + p = dmi_early_remap(efi.smbios3, 32); + if (p == NULL) + goto error; + memcpy_fromio(buf, p, 32); + dmi_early_unmap(p, 32); + + if (!dmi_smbios3_present(buf)) { + dmi_available = 1; + goto out; + } + } if (efi.smbios == EFI_INVALID_TABLE_ADDR) goto error; @@ -552,7 +617,7 @@ void __init dmi_scan_machine(void) memset(buf, 0, 16); for (q = p; q < p + 0x10000; q += 16) { memcpy_fromio(buf + 16, q, 16); - if (!dmi_present(buf)) { + if (!dmi_smbios3_present(buf) || !dmi_present(buf)) { dmi_available = 1; dmi_early_unmap(p, 0x10000); goto out;