All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] efi: use 32-bit alignment for efi_guid_t
@ 2019-01-08 15:28 ` Ard Biesheuvel
  0 siblings, 0 replies; 10+ messages in thread
From: Ard Biesheuvel @ 2019-01-08 15:28 UTC (permalink / raw)
  To: linux-efi
  Cc: Ard Biesheuvel, Heinrich Schuchardt, leif.lindholm, lersek, mingo,
	linux-arm-kernel

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>
---
 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

^ permalink raw reply related	[flat|nested] 10+ messages in thread
* [PATCH] efi: use 32-bit alignment for efi_guid_t
@ 2023-01-27 11:51 Masahisa Kojima
  2023-01-27 14:18 ` Ilias Apalodimas
  2023-01-27 19:26 ` Heinrich Schuchardt
  0 siblings, 2 replies; 10+ messages in thread
From: Masahisa Kojima @ 2023-01-27 11:51 UTC (permalink / raw)
  To: u-boot; +Cc: Heinrich Schuchardt, Ilias Apalodimas, Masahisa Kojima

Current U-Boot implements 64-bit boundary for efi_guid_t structure.
It follows the UEFI specification, page 21 of the UEFI Specification v2.10
says about EFI_GUID:
  128-bit buffer containing a unique identifier value. Unless
  otherwise specified, aligned on a 64-bit boundary.

On the other hand, page 163 of the UEFI specification v2.10 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-bit not 64-bit like U-Boot efi_guid_t.

Due to this alignment difference, EDK2 application "CapsuleApp.efi -P"
does not work as expected.
This calls EFI_FIRMWARE_MANAGEMENT_PROTOCOL.GetImageInfo()
and dump the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure,
offsetof(EFI_FIRMWARE_IMAGE_DESCRIPTOR, ImageTypeId) is different,
8 in U-Boot and 4 in EDK2(CapsuleApp.efi).
Here is the wrong EFI_GUID dump.
  wrong dump : ImageTypeId - 00000000-7D83-058B-D550-474CA19560D8
  expected   : ImageTypeId - 058B7D83-50D5-4C47-A195-60D86AD341C4

EFI_FIRMWARE_IMAGE_DESCRIPTOR structure is defined in UEFI specification:
  typedef struct {
          UINT8 ImageIndex;
          EFI_GUID ImageTypeId;
          UINT64 ImageId
          <snip>

  } EFI_FIRMWARE_IMAGE_DESCRIPTOR;

There was the relevant patch for linux kernel to use 32-bit alignment
for efi_guid_t [1].
U-Boot should get aligned to EDK2 reference implementation and
linux kernel.

Due to this alignment change, efi_hii_ref structure in include/efi_api.h
is affected, but it is not used in the current U-Boot code.

[1] https://lore.kernel.org/all/20190202094119.13230-5-ard.biesheuvel@linaro.org/

Cc: Ilias Apalodimas <ilias.apalodimas@linaro.org>
Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
---
 include/efi.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/efi.h b/include/efi.h
index 42f4e58a91..914a12967f 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -56,7 +56,7 @@ struct efi_device_path;
 
 typedef struct {
 	u8 b[16];
-} efi_guid_t __attribute__((aligned(8)));
+} efi_guid_t __attribute__((aligned(4)));
 
 #define EFI_BITS_PER_LONG	(sizeof(long) * 8)
 
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-01-28  4:47 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-01-08 15:28 [PATCH] efi: use 32-bit alignment for efi_guid_t Ard Biesheuvel
2019-01-08 15:28 ` Ard Biesheuvel
2019-01-08 15:53 ` Leif Lindholm
2019-01-08 15:53   ` Leif Lindholm
2019-01-08 16:22   ` Ard Biesheuvel
2019-01-08 16:22     ` Ard Biesheuvel
  -- strict thread matches above, loose matches on Subject: below --
2023-01-27 11:51 Masahisa Kojima
2023-01-27 14:18 ` Ilias Apalodimas
2023-01-28  4:47   ` Masahisa Kojima
2023-01-27 19:26 ` Heinrich Schuchardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.