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

efi: Use 32-bit alignment for efi_guid_t

The UEFI spec and EDK2 reference implementation both define EFI_GUID as
struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied alignment
is 32 bits not 8 bits like our guid_t. In some cases (i.e., on 32-bit ARM),
this means that firmware services invoked by the kernel may assume that
efi_guid_t* arguments are 32-bit aligned, and use memory accessors that
do not tolerate misalignment. So let's set the minimum alignment to 32 bits.

Note that the UEFI spec as well as some comments in the EDK2 code base
suggest that EFI_GUID should be 64-bit aligned, but this appears to be
a mistake, given that no code seems to exist that actually enforces that
or relies on it.

Reported-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Leif Lindholm <leif.lindholm@linaro.org>
Cc: AKASHI Takahiro <takahiro.akashi@linaro.org>
Cc: Alexander Graf <agraf@suse.de>
Cc: Bjorn Andersson <bjorn.andersson@linaro.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Jeffrey Hugo <jhugo@codeaurora.org>
Cc: Lee Jones <lee.jones@linaro.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Matt Fleming <matt@codeblueprint.co.uk>
Cc: Peter Jones <pjones@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: linux-efi@vger.kernel.org
Link: http://lkml.kernel.org/r/20190202094119.13230-5-ard.biesheuvel@linaro.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Ard Biesheuvel and committed by
Ingo Molnar
494c704f 5de0fef0

+14 -1
+14 -1
include/linux/efi.h
··· 48 48 typedef u64 efi_physical_addr_t; 49 49 typedef void *efi_handle_t; 50 50 51 - typedef guid_t efi_guid_t; 51 + /* 52 + * The UEFI spec and EDK2 reference implementation both define EFI_GUID as 53 + * struct { u32 a; u16; b; u16 c; u8 d[8]; }; and so the implied alignment 54 + * is 32 bits not 8 bits like our guid_t. In some cases (i.e., on 32-bit ARM), 55 + * this means that firmware services invoked by the kernel may assume that 56 + * efi_guid_t* arguments are 32-bit aligned, and use memory accessors that 57 + * do not tolerate misalignment. So let's set the minimum alignment to 32 bits. 58 + * 59 + * Note that the UEFI spec as well as some comments in the EDK2 code base 60 + * suggest that EFI_GUID should be 64-bit aligned, but this appears to be 61 + * a mistake, given that no code seems to exist that actually enforces that 62 + * or relies on it. 63 + */ 64 + typedef guid_t efi_guid_t __aligned(__alignof__(u32)); 52 65 53 66 #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \ 54 67 GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)