Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/efistub: Enable SMBIOS protocol handling for x86

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>

+32 -16
+6 -1
arch/x86/include/asm/efi.h
··· 229 229 230 230 static inline void *efi64_zero_upper(void *p) 231 231 { 232 - ((u32 *)p)[1] = 0; 232 + if (p) 233 + ((u32 *)p)[1] = 0; 233 234 return p; 234 235 } 235 236 ··· 316 315 #define __efi64_argmap_clear_memory_attributes(protocol, phys, size, flags) \ 317 316 ((protocol), __efi64_split(phys), __efi64_split(size), __efi64_split(flags)) 318 317 318 + /* EFI SMBIOS protocol */ 319 + #define __efi64_argmap_get_next(protocol, smbioshandle, type, record, phandle) \ 320 + ((protocol), (smbioshandle), (type), efi64_zero_upper(record), \ 321 + efi64_zero_upper(phandle)) 319 322 /* 320 323 * The macros below handle the plumbing for the argument mapping. To add a 321 324 * mapping for a specific EFI method, simply define a macro
+1 -1
drivers/firmware/efi/libstub/Makefile
··· 76 76 77 77 lib-$(CONFIG_ARM) += arm32-stub.o 78 78 lib-$(CONFIG_ARM64) += kaslr.o arm64.o arm64-stub.o smbios.o 79 - lib-$(CONFIG_X86) += x86-stub.o 79 + lib-$(CONFIG_X86) += x86-stub.o smbios.o 80 80 lib-$(CONFIG_X86_64) += x86-5lvl.o 81 81 lib-$(CONFIG_RISCV) += kaslr.o riscv.o riscv-stub.o 82 82 lib-$(CONFIG_LOONGARCH) += loongarch.o loongarch-stub.o
+23 -12
drivers/firmware/efi/libstub/smbios.c
··· 6 6 7 7 #include "efistub.h" 8 8 9 - typedef struct efi_smbios_protocol efi_smbios_protocol_t; 9 + typedef union efi_smbios_protocol efi_smbios_protocol_t; 10 10 11 - struct efi_smbios_protocol { 12 - efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t, 13 - u16 *, struct efi_smbios_record *); 14 - efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *, 15 - unsigned long *, u8 *); 16 - efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16); 17 - efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *, 18 - struct efi_smbios_record **, 19 - efi_handle_t *); 11 + union efi_smbios_protocol { 12 + struct { 13 + efi_status_t (__efiapi *add)(efi_smbios_protocol_t *, efi_handle_t, 14 + u16 *, struct efi_smbios_record *); 15 + efi_status_t (__efiapi *update_string)(efi_smbios_protocol_t *, u16 *, 16 + unsigned long *, u8 *); 17 + efi_status_t (__efiapi *remove)(efi_smbios_protocol_t *, u16); 18 + efi_status_t (__efiapi *get_next)(efi_smbios_protocol_t *, u16 *, u8 *, 19 + struct efi_smbios_record **, 20 + efi_handle_t *); 20 21 21 - u8 major_version; 22 - u8 minor_version; 22 + u8 major_version; 23 + u8 minor_version; 24 + }; 25 + struct { 26 + u32 add; 27 + u32 update_string; 28 + u32 remove; 29 + u32 get_next; 30 + 31 + u8 major_version; 32 + u8 minor_version; 33 + } mixed_mode; 23 34 }; 24 35 25 36 const struct efi_smbios_record *efi_get_smbios_record(u8 type)
+2 -2
include/linux/efi.h
··· 74 74 */ 75 75 typedef guid_t efi_guid_t __aligned(__alignof__(u32)); 76 76 77 - #define EFI_GUID(a, b, c, d...) (efi_guid_t){ { \ 77 + #define EFI_GUID(a, b, c, d...) ((efi_guid_t){ { \ 78 78 (a) & 0xff, ((a) >> 8) & 0xff, ((a) >> 16) & 0xff, ((a) >> 24) & 0xff, \ 79 79 (b) & 0xff, ((b) >> 8) & 0xff, \ 80 - (c) & 0xff, ((c) >> 8) & 0xff, d } } 80 + (c) & 0xff, ((c) >> 8) & 0xff, d } }) 81 81 82 82 /* 83 83 * Generic EFI table header