On Tue, Jan 08, 2019 at 04:28:29PM +0100, Ard Biesheuvel wrote:
> 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.

Whereas code does exist that relies on it being 32-bit aligned...

> Reported-by: Heinrich Schuchardt <[email protected]>,
> Signed-off-by: Ard Biesheuvel <[email protected]>

Reviewed-by: Leif Lindholm <[email protected]>

> ---
>  include/linux/efi.h | 15 ++++++++++++++-
>  1 file changed, 14 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/efi.h b/include/linux/efi.h
> index 45ff763fba76..be08518c2553 100644
> --- a/include/linux/efi.h
> +++ b/include/linux/efi.h
> @@ -48,7 +48,20 @@ typedef u16 efi_char16_t;          /* UNICODE character */
>  typedef u64 efi_physical_addr_t;
>  typedef void *efi_handle_t;
>  
> -typedef guid_t 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.
> + */
> +typedef guid_t efi_guid_t __aligned(__alignof__(u32));
>  
>  #define EFI_GUID(a,b,c,d0,d1,d2,d3,d4,d5,d6,d7) \
>       GUID_INIT(a, b, c, d0, d1, d2, d3, d4, d5, d6, d7)
> -- 
> 2.20.1
> 

Reply via email to