linux-efi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] arm64: efi: Use SMBIOS type 4 record for Altra quirk
@ 2023-03-22 14:26 Ard Biesheuvel
  2023-03-22 14:26 ` [PATCH 1/3] efi/libstub: smbios: Use length member instead of record struct size Ard Biesheuvel
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2023-03-22 14:26 UTC (permalink / raw)
  To: linux-efi; +Cc: linux-arm-kernel, Ard Biesheuvel, Darren Hart, Andrea Righi

We currently use the SMBIOS type 1 'family' string to identify Ampere
machines that require a EFI workaround, but this is not broad enough, as
OEMs often put arbitrary names in that field (such as 'Server')

So instead, let's use the SMBIOS type 4 records that describe the actual
CPU rather than the system.

Cc: Darren Hart <darren@os.amperecomputing.com>
Cc: Andrea Righi <andrea.righi@canonical.com>

Ard Biesheuvel (3):
  efi/libstub: smbios: Use length member instead of record struct size
  arm64: efi: Use SMBIOS processor version to key off Ampere quirk
  efi/libstub: smbios: Drop unused 'recsize' parameter

 drivers/firmware/efi/libstub/arm64.c   | 39 ++++++++++++++----
 drivers/firmware/efi/libstub/efistub.h | 42 ++++++++++++++++++--
 drivers/firmware/efi/libstub/smbios.c  | 15 +++++--
 3 files changed, 81 insertions(+), 15 deletions(-)

-- 
2.39.2


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] efi/libstub: smbios: Use length member instead of record struct size
  2023-03-22 14:26 [PATCH 0/3] arm64: efi: Use SMBIOS type 4 record for Altra quirk Ard Biesheuvel
@ 2023-03-22 14:26 ` Ard Biesheuvel
  2023-03-22 14:26 ` [PATCH 2/3] arm64: efi: Use SMBIOS processor version to key off Ampere quirk Ard Biesheuvel
  2023-03-22 14:26 ` [PATCH 3/3] efi/libstub: smbios: Drop unused 'recsize' parameter Ard Biesheuvel
  2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2023-03-22 14:26 UTC (permalink / raw)
  To: linux-efi; +Cc: linux-arm-kernel, Ard Biesheuvel, Darren Hart, Andrea Righi

The type 1 SMBIOS record happens to always be the same size, but there
are other record types which have been augmented over time, and so we
should really use the length field in the header to decide where the
string table starts.

Fixes: 550b33cfd4452968 ("arm64: efi: Force the use of ...")
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/smbios.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/firmware/efi/libstub/smbios.c b/drivers/firmware/efi/libstub/smbios.c
index 460418b7f5f5e9ab..aadb422b9637dfc0 100644
--- a/drivers/firmware/efi/libstub/smbios.c
+++ b/drivers/firmware/efi/libstub/smbios.c
@@ -36,7 +36,7 @@ const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize)
 	if (status != EFI_SUCCESS)
 		return NULL;
 
-	strtable = (u8 *)record + recsize;
+	strtable = (u8 *)record + record->length;
 	for (int i = 1; i < ((u8 *)record)[offset]; i++) {
 		int len = strlen(strtable);
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] arm64: efi: Use SMBIOS processor version to key off Ampere quirk
  2023-03-22 14:26 [PATCH 0/3] arm64: efi: Use SMBIOS type 4 record for Altra quirk Ard Biesheuvel
  2023-03-22 14:26 ` [PATCH 1/3] efi/libstub: smbios: Use length member instead of record struct size Ard Biesheuvel
@ 2023-03-22 14:26 ` Ard Biesheuvel
  2023-03-22 14:26 ` [PATCH 3/3] efi/libstub: smbios: Drop unused 'recsize' parameter Ard Biesheuvel
  2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2023-03-22 14:26 UTC (permalink / raw)
  To: linux-efi; +Cc: linux-arm-kernel, Ard Biesheuvel, Darren Hart, Andrea Righi

Instead of using the SMBIOS type 1 record 'family' field, which is often
modified by OEMs, use the type 4 'processor ID' and 'processor version'
fields, which are set to a small set of probe-able values on all known
Ampere EFI systems in the field.

Fixes: 550b33cfd4452968 ("arm64: efi: Force the use of ...")
Tested-by: Andrea Righi <andrea.righi@canonical.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/arm64.c   | 39 +++++++++++++++----
 drivers/firmware/efi/libstub/efistub.h | 41 ++++++++++++++++++--
 drivers/firmware/efi/libstub/smbios.c  | 13 ++++++-
 3 files changed, 80 insertions(+), 13 deletions(-)

diff --git a/drivers/firmware/efi/libstub/arm64.c b/drivers/firmware/efi/libstub/arm64.c
index 3997702663727e30..8aad8c49d43f18e0 100644
--- a/drivers/firmware/efi/libstub/arm64.c
+++ b/drivers/firmware/efi/libstub/arm64.c
@@ -16,20 +16,43 @@
 
 static bool system_needs_vamap(void)
 {
-	const u8 *type1_family = efi_get_smbios_string(1, family);
+	const struct efi_smbios_type4_record *record;
+	const u32 __aligned(1) *socid;
+	const u8 *version;
 
 	/*
 	 * Ampere eMAG, Altra, and Altra Max machines crash in SetTime() if
-	 * SetVirtualAddressMap() has not been called prior.
+	 * SetVirtualAddressMap() has not been called prior. Most Altra systems
+	 * can be identified by the SMCCC soc ID, which is conveniently exposed
+	 * via the type 4 SMBIOS records. Otherwise, test the processor version
+	 * field. eMAG systems all appear to have the processor version field
+	 * set to "eMAG".
 	 */
-	if (!type1_family || (
-	    strcmp(type1_family, "eMAG") &&
-	    strcmp(type1_family, "Altra") &&
-	    strcmp(type1_family, "Altra Max")))
+	record = (struct efi_smbios_type4_record *)efi_get_smbios_record(4);
+	if (!record)
 		return false;
 
-	efi_warn("Working around broken SetVirtualAddressMap()\n");
-	return true;
+	socid = (u32 *)record->processor_id;
+	switch (*socid & 0xffff000f) {
+		static char const altra[] = "Ampere(TM) Altra(TM) Processor";
+		static char const emag[] = "eMAG";
+
+	default:
+		version = efi_get_smbios_string(&record->header, 4,
+						processor_version);
+		if (!version || (strncmp(version, altra, sizeof(altra) - 1) &&
+				 strncmp(version, emag, sizeof(emag) - 1)))
+			break;
+
+		fallthrough;
+
+	case 0x0a160001:	// Altra
+	case 0x0a160002:	// Altra Max
+		efi_warn("Working around broken SetVirtualAddressMap()\n");
+		return true;
+	}
+
+	return false;
 }
 
 efi_status_t check_platform_features(void)
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 6bd3bb86d9679a1c..330565b9263a6b01 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1074,6 +1074,8 @@ struct efi_smbios_record {
 	u16	handle;
 };
 
+const struct efi_smbios_record *efi_get_smbios_record(u8 type);
+
 struct efi_smbios_type1_record {
 	struct efi_smbios_record	header;
 
@@ -1087,14 +1089,47 @@ struct efi_smbios_type1_record {
 	u8				family;
 };
 
-#define efi_get_smbios_string(__type, __name) ({			\
+struct efi_smbios_type4_record {
+	struct efi_smbios_record	header;
+
+	u8				socket;
+	u8				processor_type;
+	u8				processor_family;
+	u8				processor_manufacturer;
+	u8				processor_id[8];
+	u8				processor_version;
+	u8				voltage;
+	u16				external_clock;
+	u16				max_speed;
+	u16				current_speed;
+	u8				status;
+	u8				processor_upgrade;
+	u16				l1_cache_handle;
+	u16				l2_cache_handle;
+	u16				l3_cache_handle;
+	u8				serial_number;
+	u8				asset_tag;
+	u8				part_number;
+	u8				core_count;
+	u8				enabled_core_count;
+	u8				thread_count;
+	u16				processor_characteristics;
+	u16				processor_family2;
+	u16				core_count2;
+	u16				enabled_core_count2;
+	u16				thread_count2;
+	u16				thread_enabled;
+};
+
+#define efi_get_smbios_string(__record, __type, __name) ({		\
 	int size = sizeof(struct efi_smbios_type ## __type ## _record);	\
 	int off = offsetof(struct efi_smbios_type ## __type ## _record,	\
 			   __name);					\
-	__efi_get_smbios_string(__type, off, size);			\
+	__efi_get_smbios_string((__record), __type, off, size);		\
 })
 
-const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize);
+const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
+				  u8 type, int offset, int recsize);
 
 void efi_remap_image(unsigned long image_base, unsigned alloc_size,
 		     unsigned long code_size);
diff --git a/drivers/firmware/efi/libstub/smbios.c b/drivers/firmware/efi/libstub/smbios.c
index aadb422b9637dfc0..f9c159c28f4613f8 100644
--- a/drivers/firmware/efi/libstub/smbios.c
+++ b/drivers/firmware/efi/libstub/smbios.c
@@ -22,19 +22,28 @@ struct efi_smbios_protocol {
 	u8 minor_version;
 };
 
-const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize)
+const struct efi_smbios_record *efi_get_smbios_record(u8 type)
 {
 	struct efi_smbios_record *record;
 	efi_smbios_protocol_t *smbios;
 	efi_status_t status;
 	u16 handle = 0xfffe;
-	const u8 *strtable;
 
 	status = efi_bs_call(locate_protocol, &EFI_SMBIOS_PROTOCOL_GUID, NULL,
 			     (void **)&smbios) ?:
 		 efi_call_proto(smbios, get_next, &handle, &type, &record, NULL);
 	if (status != EFI_SUCCESS)
 		return NULL;
+	return record;
+}
+
+const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
+				  u8 type, int offset, int recsize)
+{
+	const u8 *strtable;
+
+	if (!record)
+		return NULL;
 
 	strtable = (u8 *)record + record->length;
 	for (int i = 1; i < ((u8 *)record)[offset]; i++) {
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] efi/libstub: smbios: Drop unused 'recsize' parameter
  2023-03-22 14:26 [PATCH 0/3] arm64: efi: Use SMBIOS type 4 record for Altra quirk Ard Biesheuvel
  2023-03-22 14:26 ` [PATCH 1/3] efi/libstub: smbios: Use length member instead of record struct size Ard Biesheuvel
  2023-03-22 14:26 ` [PATCH 2/3] arm64: efi: Use SMBIOS processor version to key off Ampere quirk Ard Biesheuvel
@ 2023-03-22 14:26 ` Ard Biesheuvel
  2 siblings, 0 replies; 4+ messages in thread
From: Ard Biesheuvel @ 2023-03-22 14:26 UTC (permalink / raw)
  To: linux-efi; +Cc: linux-arm-kernel, Ard Biesheuvel, Darren Hart, Andrea Righi

We no longer use the recsize argument for locating the string table in
an SMBIOS record, so we can drop it from the internal API.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/efistub.h | 5 ++---
 drivers/firmware/efi/libstub/smbios.c  | 2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 330565b9263a6b01..bd9c38a93bbce09c 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -1122,14 +1122,13 @@ struct efi_smbios_type4_record {
 };
 
 #define efi_get_smbios_string(__record, __type, __name) ({		\
-	int size = sizeof(struct efi_smbios_type ## __type ## _record);	\
 	int off = offsetof(struct efi_smbios_type ## __type ## _record,	\
 			   __name);					\
-	__efi_get_smbios_string((__record), __type, off, size);		\
+	__efi_get_smbios_string((__record), __type, off);		\
 })
 
 const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
-				  u8 type, int offset, int recsize);
+				  u8 type, int offset);
 
 void efi_remap_image(unsigned long image_base, unsigned alloc_size,
 		     unsigned long code_size);
diff --git a/drivers/firmware/efi/libstub/smbios.c b/drivers/firmware/efi/libstub/smbios.c
index f9c159c28f4613f8..c217de2cc8d56dc2 100644
--- a/drivers/firmware/efi/libstub/smbios.c
+++ b/drivers/firmware/efi/libstub/smbios.c
@@ -38,7 +38,7 @@ const struct efi_smbios_record *efi_get_smbios_record(u8 type)
 }
 
 const u8 *__efi_get_smbios_string(const struct efi_smbios_record *record,
-				  u8 type, int offset, int recsize)
+				  u8 type, int offset)
 {
 	const u8 *strtable;
 
-- 
2.39.2


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-03-22 14:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-03-22 14:26 [PATCH 0/3] arm64: efi: Use SMBIOS type 4 record for Altra quirk Ard Biesheuvel
2023-03-22 14:26 ` [PATCH 1/3] efi/libstub: smbios: Use length member instead of record struct size Ard Biesheuvel
2023-03-22 14:26 ` [PATCH 2/3] arm64: efi: Use SMBIOS processor version to key off Ampere quirk Ard Biesheuvel
2023-03-22 14:26 ` [PATCH 3/3] efi/libstub: smbios: Drop unused 'recsize' parameter Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).