From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751436AbdAWQst (ORCPT ); Mon, 23 Jan 2017 11:48:49 -0500 Received: from mx2.suse.de ([195.135.220.15]:60702 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750732AbdAWQss (ORCPT ); Mon, 23 Jan 2017 11:48:48 -0500 Date: Mon, 23 Jan 2017 17:48:43 +0100 From: Jean Delvare To: LKML Cc: Kefeng Wang , Jordan Hargrave , Ivan Khoronzhuk Subject: [PATCH] firmware: dmi_scan: Look for SMBIOS 3 entry point first Message-ID: <20170123174843.2f681487@endymion> Organization: SUSE Linux X-Mailer: Claws Mail 3.12.0 (GTK+ 2.24.31; x86_64-suse-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Since version 3.0.0 of the SMBIOS specification, there can be multiple entry points in memory, pointing to one or two DMI tables. If both a 32-bit ("_SM_") entry point and a 64-bit ("_SM3_") entry point are present, the specification requires that the latter points to a table which is a super-set of the table pointed to by the former. Therefore we should give preference to the 64-bit ("_SM3_") entry point. However, currently the code is picking the first valid entry point it finds. Per specification, we should look for a 64-bit ("_SM3_") entry point first, and if we can't find any, look for a 32-bit ("_SM_" or "_DMI_") entry point. Modify the code to do that. Signed-off-by: Jean Delvare --- * Note 1: I can't test the 64-bit ("_SM3_") entry point case. I would appreciate if someone with access to a machine supporting legacy (non-UEFI) mode and implementing a 64-bit table could test and report. * Note 2: I'm not particularly happy with this change as it will make the entry point scan 3 times slower on average for legacy machines, but I couldn't come up with anything smarter. If anyone can think of a better implementation, please let me know. drivers/firmware/dmi_scan.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) --- linux-4.10-rc4.orig/drivers/firmware/dmi_scan.c 2017-01-04 14:05:09.392301072 +0100 +++ linux-4.10-rc4/drivers/firmware/dmi_scan.c 2017-01-16 11:55:24.500984728 +0100 @@ -649,6 +649,21 @@ void __init dmi_scan_machine(void) goto error; /* + * Same logic as above, look for a 64-bit entry point + * first, and if not found, fall back to 32-bit entry point. + */ + memcpy_fromio(buf, p, 16); + for (q = p + 16; q < p + 0x10000; q += 16) { + memcpy_fromio(buf + 16, q, 16); + if (!dmi_smbios3_present(buf)) { + dmi_available = 1; + dmi_early_unmap(p, 0x10000); + goto out; + } + memcpy(buf, buf + 16, 16); + } + + /* * Iterate over all possible DMI header addresses q. * Maintain the 32 bytes around q in buf. On the * first iteration, substitute zero for the @@ -658,7 +673,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_smbios3_present(buf) || !dmi_present(buf)) { + if (!dmi_present(buf)) { dmi_available = 1; dmi_early_unmap(p, 0x10000); goto out; -- Jean Delvare SUSE L3 Support