|
Jiri Slaby |
533dcd |
From: Ard Biesheuvel <ardb@kernel.org>
|
|
Jiri Slaby |
533dcd |
Date: Tue, 28 Feb 2023 17:00:49 +0100
|
|
Jiri Slaby |
533dcd |
Subject: arm64: efi: Use SMBIOS processor ID to key off Altra quirk
|
|
Jiri Slaby |
533dcd |
Git-repo: https://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git#urgent
|
|
Jiri Slaby |
533dcd |
Git-commit: 22d9e53df5aa26f775d96222fbb049569720349f
|
|
Jiri Slaby |
533dcd |
Patch-mainline: Queued in subsystem maintainer repository
|
|
Jiri Slaby |
533dcd |
References: bsc#1208750
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
Instead of using the SMBIOS type 1 record 'family' field, which is often
|
|
Jiri Slaby |
533dcd |
modified by OEMs, use the type 4 'processor ID' field, which is always
|
|
Jiri Slaby |
533dcd |
set to the same value on all known Altra EFI systems in the field, and
|
|
Jiri Slaby |
533dcd |
is more likely to be left alone, given that it is based on the SOC id
|
|
Jiri Slaby |
533dcd |
SMCCC API call which is implemented in secure firmware.
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
Fixes: 550b33cfd4452968 ("arm64: efi: Force the use of ...")
|
|
Jiri Slaby |
533dcd |
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
|
|
Jiri Slaby |
533dcd |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
533dcd |
---
|
|
Jiri Slaby |
533dcd |
drivers/firmware/efi/libstub/arm64.c | 12 +++++------
|
|
Jiri Slaby |
533dcd |
drivers/firmware/efi/libstub/efistub.h | 34 +++++++++++++++++++++++++++++++++
|
|
Jiri Slaby |
533dcd |
drivers/firmware/efi/libstub/smbios.c | 14 +++++++++++--
|
|
Jiri Slaby |
533dcd |
3 files changed, 52 insertions(+), 8 deletions(-)
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
--- a/drivers/firmware/efi/libstub/arm64.c
|
|
Jiri Slaby |
533dcd |
+++ b/drivers/firmware/efi/libstub/arm64.c
|
|
Jiri Slaby |
533dcd |
@@ -16,16 +16,16 @@
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
static bool system_needs_vamap(void)
|
|
Jiri Slaby |
533dcd |
{
|
|
Jiri Slaby |
533dcd |
- const u8 *type1_family = efi_get_smbios_string(1, family);
|
|
Jiri Slaby |
533dcd |
+ const struct efi_smbios_type4_record *record;
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
/*
|
|
Jiri Slaby |
533dcd |
* Ampere eMAG, Altra, and Altra Max machines crash in SetTime() if
|
|
Jiri Slaby |
533dcd |
- * SetVirtualAddressMap() has not been called prior.
|
|
Jiri Slaby |
533dcd |
+ * SetVirtualAddressMap() has not been called prior. These systems can
|
|
Jiri Slaby |
533dcd |
+ * be identified by the SMCCC soc ID, which is conveniently exposed via
|
|
Jiri Slaby |
533dcd |
+ * the type 4 SMBIOS records.
|
|
Jiri Slaby |
533dcd |
*/
|
|
Jiri Slaby |
533dcd |
- if (!type1_family || (
|
|
Jiri Slaby |
533dcd |
- strcmp(type1_family, "eMAG") &&
|
|
Jiri Slaby |
533dcd |
- strcmp(type1_family, "Altra") &&
|
|
Jiri Slaby |
533dcd |
- strcmp(type1_family, "Altra Max")))
|
|
Jiri Slaby |
533dcd |
+ record = (struct efi_smbios_type4_record *)efi_get_smbios_record(4);
|
|
Jiri Slaby |
533dcd |
+ if (!record || memcmp(record->processor_id, "\x1\0\x16\xA\xA1\0\0\0", 8))
|
|
Jiri Slaby |
533dcd |
return false;
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
efi_warn("Working around broken SetVirtualAddressMap()\n");
|
|
Jiri Slaby |
533dcd |
--- a/drivers/firmware/efi/libstub/efistub.h
|
|
Jiri Slaby |
533dcd |
+++ b/drivers/firmware/efi/libstub/efistub.h
|
|
Jiri Slaby |
533dcd |
@@ -1054,6 +1054,8 @@ struct efi_smbios_record {
|
|
Jiri Slaby |
533dcd |
u16 handle;
|
|
Jiri Slaby |
533dcd |
};
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
+const struct efi_smbios_record *efi_get_smbios_record(u8 type);
|
|
Jiri Slaby |
533dcd |
+
|
|
Jiri Slaby |
533dcd |
struct efi_smbios_type1_record {
|
|
Jiri Slaby |
533dcd |
struct efi_smbios_record header;
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
@@ -1067,6 +1069,38 @@ struct efi_smbios_type1_record {
|
|
Jiri Slaby |
533dcd |
u8 family;
|
|
Jiri Slaby |
533dcd |
};
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
+struct efi_smbios_type4_record {
|
|
Jiri Slaby |
533dcd |
+ struct efi_smbios_record header;
|
|
Jiri Slaby |
533dcd |
+
|
|
Jiri Slaby |
533dcd |
+ u8 socket;
|
|
Jiri Slaby |
533dcd |
+ u8 processor_type;
|
|
Jiri Slaby |
533dcd |
+ u8 processor_family;
|
|
Jiri Slaby |
533dcd |
+ u8 processor_manufacturer;
|
|
Jiri Slaby |
533dcd |
+ u8 processor_id[8];
|
|
Jiri Slaby |
533dcd |
+ u8 processor_version;
|
|
Jiri Slaby |
533dcd |
+ u8 voltage;
|
|
Jiri Slaby |
533dcd |
+ u16 external_clock;
|
|
Jiri Slaby |
533dcd |
+ u16 max_speed;
|
|
Jiri Slaby |
533dcd |
+ u16 current_speed;
|
|
Jiri Slaby |
533dcd |
+ u8 status;
|
|
Jiri Slaby |
533dcd |
+ u8 processor_upgrade;
|
|
Jiri Slaby |
533dcd |
+ u16 l1_cache_handle;
|
|
Jiri Slaby |
533dcd |
+ u16 l2_cache_handle;
|
|
Jiri Slaby |
533dcd |
+ u16 l3_cache_handle;
|
|
Jiri Slaby |
533dcd |
+ u8 serial_number;
|
|
Jiri Slaby |
533dcd |
+ u8 asset_tag;
|
|
Jiri Slaby |
533dcd |
+ u8 part_number;
|
|
Jiri Slaby |
533dcd |
+ u8 core_count;
|
|
Jiri Slaby |
533dcd |
+ u8 enabled_core_count;
|
|
Jiri Slaby |
533dcd |
+ u8 thread_count;
|
|
Jiri Slaby |
533dcd |
+ u16 processor_characteristics;
|
|
Jiri Slaby |
533dcd |
+ u16 processor_family2;
|
|
Jiri Slaby |
533dcd |
+ u16 core_count2;
|
|
Jiri Slaby |
533dcd |
+ u16 enabled_core_count2;
|
|
Jiri Slaby |
533dcd |
+ u16 thread_count2;
|
|
Jiri Slaby |
533dcd |
+ u16 thread_enabled;
|
|
Jiri Slaby |
533dcd |
+};
|
|
Jiri Slaby |
533dcd |
+
|
|
Jiri Slaby |
533dcd |
#define efi_get_smbios_string(__type, __name) ({ \
|
|
Jiri Slaby |
533dcd |
int size = sizeof(struct efi_smbios_type ## __type ## _record); \
|
|
Jiri Slaby |
533dcd |
int off = offsetof(struct efi_smbios_type ## __type ## _record, \
|
|
Jiri Slaby |
533dcd |
--- a/drivers/firmware/efi/libstub/smbios.c
|
|
Jiri Slaby |
533dcd |
+++ b/drivers/firmware/efi/libstub/smbios.c
|
|
Jiri Slaby |
533dcd |
@@ -22,19 +22,29 @@ struct efi_smbios_protocol {
|
|
Jiri Slaby |
533dcd |
u8 minor_version;
|
|
Jiri Slaby |
533dcd |
};
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
-const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize)
|
|
Jiri Slaby |
533dcd |
+const struct efi_smbios_record *efi_get_smbios_record(u8 type)
|
|
Jiri Slaby |
533dcd |
{
|
|
Jiri Slaby |
533dcd |
struct efi_smbios_record *record;
|
|
Jiri Slaby |
533dcd |
efi_smbios_protocol_t *smbios;
|
|
Jiri Slaby |
533dcd |
efi_status_t status;
|
|
Jiri Slaby |
533dcd |
u16 handle = 0xfffe;
|
|
Jiri Slaby |
533dcd |
- const u8 *strtable;
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
status = efi_bs_call(locate_protocol, &EFI_SMBIOS_PROTOCOL_GUID, NULL,
|
|
Jiri Slaby |
533dcd |
(void **)&smbios) ?:
|
|
Jiri Slaby |
533dcd |
efi_call_proto(smbios, get_next, &handle, &type, &record, NULL);
|
|
Jiri Slaby |
533dcd |
if (status != EFI_SUCCESS)
|
|
Jiri Slaby |
533dcd |
return NULL;
|
|
Jiri Slaby |
533dcd |
+ return record;
|
|
Jiri Slaby |
533dcd |
+}
|
|
Jiri Slaby |
533dcd |
+
|
|
Jiri Slaby |
533dcd |
+const u8 *__efi_get_smbios_string(u8 type, int offset, int recsize)
|
|
Jiri Slaby |
533dcd |
+{
|
|
Jiri Slaby |
533dcd |
+ const struct efi_smbios_record *record;
|
|
Jiri Slaby |
533dcd |
+ const u8 *strtable;
|
|
Jiri Slaby |
533dcd |
+
|
|
Jiri Slaby |
533dcd |
+ record = efi_get_smbios_record(type);
|
|
Jiri Slaby |
533dcd |
+ if (!record)
|
|
Jiri Slaby |
533dcd |
+ return NULL;
|
|
Jiri Slaby |
533dcd |
|
|
Jiri Slaby |
533dcd |
strtable = (u8 *)record + recsize;
|
|
Jiri Slaby |
533dcd |
for (int i = 1; i < ((u8 *)record)[offset]; i++) {
|