x86/efistub: Enable SMBIOS protocol handling for x86
authorArd Biesheuvel <ardb@kernel.org>
Mon, 1 Jul 2024 07:35:33 +0000 (09:35 +0200)
committerArd Biesheuvel <ardb@kernel.org>
Mon, 8 Jul 2024 08:17:44 +0000 (10:17 +0200)
The smbios.c source file is not currently included in the x86 build, and
before we can do so, it needs some tweaks to build correctly in
combination with the EFI mixed mode support.

Reviewed-by: Lukas Wunner <lukas@wunner.de>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
arch/x86/include/asm/efi.h
drivers/firmware/efi/libstub/Makefile
drivers/firmware/efi/libstub/smbios.c
include/linux/efi.h

index b3e4d999b91371470d90790b285a9e65436831c5..521aad70e41b9d718d61c53034ade8fedd2aeef8 100644 (file)
@@ -229,7 +229,8 @@ static inline bool efi_is_native(void)
 
 static inline void *efi64_zero_upper(void *p)
 {
-       ((u32 *)p)[1] = 0;
+       if (p)
+               ((u32 *)p)[1] = 0;
        return p;
 }
 
@@ -315,6 +316,10 @@ static inline u32 efi64_convert_status(efi_status_t status)
 #define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \
        ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags))
 
+/* EFI SMBIOS protocol */
+#define __efi64_argmap_get_next(protocol, smbioshandle, type, record, phandle) \
+       ((protocol), (smbioshandle), (type), efi64_zero_upper(record), \
+        efi64_zero_upper(phandle))
 /*
  * The macros below handle the plumbing for the argument mapping. To add a
  * mapping for a specific EFI method, simply define a macro
index 06f0428a723cb8f6be287a81600cd49b40fb3341..1f32d6cf98d6913ff4e0169868126fc50a5b11fd 100644 (file)
@@ -76,7 +76,7 @@ lib-$(CONFIG_EFI_GENERIC_STUB)        += efi-stub.o string.o intrinsics.o systable.o \
 
 lib-$(CONFIG_ARM)              += arm32-stub.o
 lib-$(CONFIG_ARM64)            += kaslr.o arm64.o arm64-stub.o smbios.o
-lib-$(CONFIG_X86)              += x86-stub.o
+lib-$(CONFIG_X86)              += x86-stub.o smbios.o
 lib-$(CONFIG_X86_64)           += x86-5lvl.o
 lib-$(CONFIG_RISCV)            += kaslr.o riscv.o riscv-stub.o
 lib-$(CONFIG_LOONGARCH)                += loongarch.o loongarch-stub.o
index 520c9079717a30814a63e6133f9636f4f2c2d445..f31410d7e7e180703a05235bcdae60bea79cb5de 100644 (file)
@@ -6,20 +6,31 @@
 
 #include "efistub.h"
 
-typedef struct efi_smbios_protocol efi_smbios_protocol_t;
-
-struct efi_smbios_protocol {
-       efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t,
-                                    u16 *, struct efi_smbios_record *);
-       efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *,
-                                              unsigned long *, u8 *);
-       efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16);
-       efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *,
-                                         struct efi_smbios_record **,
-                                         efi_handle_t *);
-
-       u8 major_version;
-       u8 minor_version;
+typedef union efi_smbios_protocol efi_smbios_protocol_t;
+
+union efi_smbios_protocol {
+       struct {
+               efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t,
+                                            u16 *, struct efi_smbios_record *);
+               efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *,
+                                                      unsigned long *, u8 *);
+               efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16);
+               efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *,
+                                                 struct efi_smbios_record **,
+                                                 efi_handle_t *);
+
+               u8 major_version;
+               u8 minor_version;
+       };
+       struct {
+               u32 add;
+               u32 update_string;
+               u32 remove;
+               u32 get_next;
+
+               u8 major_version;
+               u8 minor_version;
+       } mixed_mode;
 };
 
 const struct efi_smbios_record *efi_get_smbios_record(u8 type)
index 418e555459da7c37f5e85896fa6b3feb8c8b30a1..2a539816a4362d85cc12ea9da48881bc7c3af531 100644 (file)
@@ -74,10 +74,10 @@ typedef void *efi_handle_t;
  */
 typedef guid_t efi_guid_t __aligned(__alignof__(u32));
 
-#define EFI_GUID(a, b, c, d...) (efi_guid_t){ {                                        \
+#define EFI_GUID(a, b, c, d...) ((efi_guid_t){ {                               \
        (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff,  \
        (b) & 0xff, ((b) >> 8) & 0xff,                                          \
-       (c) & 0xff, ((c) >> 8) & 0xff, d } }
+       (c) & 0xff, ((c) >> 8) & 0xff, d } })
 
 /*
  * Generic EFI table header