All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt
@ 2025-11-19 19:32 Marek Vasut
  2025-11-19 19:32 ` [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses Marek Vasut
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Marek Vasut @ 2025-11-19 19:32 UTC (permalink / raw)
  To: u-boot
  Cc: Marek Vasut, Aaron Kling, Eddie Kovsky, George Chan,
	Julien Masson, Mattijs Korpershoek, Nicolas Belin, Sam Day,
	Simon Glass, Tom Rini

Newer versions of libfdt strictly check whether the FDT blob
passed to them is at 8-byte aligned offset, if it is not, then
the library fails checks with -FDT_ERR_ALIGNMENT . Currently,
android_image_print_dtb_contents() passed FDT directly mapped
from abootimg to libfdt, and this FDT is not always aligned to
8-byte offset. Specifically, the FDTs are somewhat packed in
the abootimg, therefore if the first FDT blob is e.g. 0xfd bytes
long, then the next FDT blob ends up at 0xfd offset, which is
not 8-byte aligned.

Fix this by first extracting the header into 8-byte aligned buffer,
checking only the header for validity, and then by copying the
entire FDT into newly allocated 8-byte aligned buffer. While this
is not efficient, it is the correct way to handle DTs, which must
be at 8-byte aligned offsets. Mitigate the inefficiency for the
common case by checking whether the DT might be 8-byte aligned and
if it is, map it directly.

Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
---
Cc: Aaron Kling <webgeek1234@gmail.com>
Cc: Eddie Kovsky <ekovsky@redhat.com>
Cc: George Chan <gchan9527@gmail.com>
Cc: Julien Masson <jmasson@baylibre.com>
Cc: Mattijs Korpershoek <mkorpershoek@kernel.org>
Cc: Nicolas Belin <nbelin@baylibre.com>
Cc: Sam Day <me@samcday.com>
Cc: Simon Glass <sjg@chromium.org>
Cc: Tom Rini <trini@konsulko.com>
Cc: u-boot@lists.denx.de
---
V2: - Turn the two conditionals into single conditional
    - Use IS_ALIGNED()
V3: - Flip the IS_ALIGNED() conditional to check the right thing
---
 boot/image-android.c | 42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/boot/image-android.c b/boot/image-android.c
index e46dee0d9b3..ea47869a64c 100644
--- a/boot/image-android.c
+++ b/boot/image-android.c
@@ -721,17 +721,19 @@ bool android_image_get_dtb_by_index(ulong hdr_addr, ulong vendor_boot_img,
 	dtb_addr = dtb_img_addr;
 	while (dtb_addr < dtb_img_addr + dtb_img_size) {
 		const struct fdt_header *fdt;
+		struct fdt_header fdth __aligned(8);
 		u32 dtb_size;
 
 		fdt = map_sysmem(dtb_addr, sizeof(*fdt));
-		if (fdt_check_header(fdt) != 0) {
-			unmap_sysmem(fdt);
+		memcpy(&fdth, fdt, sizeof(*fdt));
+		unmap_sysmem(fdt);
+
+		if (fdt_check_header(&fdth) != 0) {
 			printf("Error: Invalid FDT header for index %u\n", i);
 			return false;
 		}
 
-		dtb_size = fdt_totalsize(fdt);
-		unmap_sysmem(fdt);
+		dtb_size = fdt_totalsize(&fdth);
 
 		if (i == index) {
 			if (size)
@@ -885,23 +887,41 @@ bool android_image_print_dtb_contents(ulong hdr_addr)
 	dtb_addr = dtb_img_addr;
 	while (dtb_addr < dtb_img_addr + dtb_img_size) {
 		const struct fdt_header *fdt;
+		struct fdt_header *fulldt;
+		struct fdt_header fdth __aligned(8);
 		u32 dtb_size;
 
 		fdt = map_sysmem(dtb_addr, sizeof(*fdt));
-		if (fdt_check_header(fdt) != 0) {
-			unmap_sysmem(fdt);
+		memcpy(&fdth, fdt, sizeof(*fdt));
+		unmap_sysmem(fdt);
+
+		if (fdt_check_header(&fdth) != 0) {
 			printf("Error: Invalid FDT header for index %u\n", i);
 			return false;
 		}
 
-		res = android_image_print_dtb_info(fdt, i);
-		if (!res) {
+		dtb_size = fdt_totalsize(&fdth);
+
+		/* The device tree must be at an 8-byte aligned address */
+		if (!IS_ALIGNED((uintptr_t)fdt, 8)) {
+			fulldt = memalign(8, dtb_size);
+			if (!fulldt)
+				return false;
+
+			fdt = map_sysmem(dtb_addr, dtb_size);
+			memcpy(fulldt, fdt, dtb_size);
 			unmap_sysmem(fdt);
-			return false;
+			res = android_image_print_dtb_info(fulldt, i);
+			free(fulldt);
+		} else {
+			fulldt = map_sysmem(dtb_addr, dtb_size);
+			res = android_image_print_dtb_info(fulldt, i);
+			unmap_sysmem(fulldt);
 		}
 
-		dtb_size = fdt_totalsize(fdt);
-		unmap_sysmem(fdt);
+		if (!res)
+			return false;
+
 		dtb_addr += dtb_size;
 		++i;
 	}
-- 
2.51.0


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

end of thread, other threads:[~2025-12-05 16:22 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-19 19:32 [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Marek Vasut
2025-11-19 19:32 ` [PATCH v3 2/2] test/py: android: Point fdt command to aligned addresses Marek Vasut
2025-11-20  9:39   ` Mattijs Korpershoek
2025-11-19 19:39 ` [PATCH v3 1/2] boot: android: Always use 8-byte aligned DT with libfdt Tom Rini
2025-11-20  9:38 ` Mattijs Korpershoek
2025-12-05 16:22 ` Mattijs Korpershoek

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.