Re: [PATCH] fdt: Fix fdt_pack_reg() on 64-bit platforms

2024-04-12 Thread Tom Rini
On Fri, Mar 29, 2024 at 07:55:53PM -0500, Sam Protsenko wrote:

> When "memory" node is being processed in fdt_pack_reg() on ARM64
> platforms, an unaligned bus access might happen, which leads to
> "synchronous abort" CPU exception. Consider next dts example:
> 
> / {
> #address-cells = <2>;
> #size-cells = <1>;
> 
> memory@8000 {
> device_type = "memory";
> reg = <0x0 0x8000 0x3ab0>,
>   <0x0 0xc000 0x4000>,
>   <0x8 0x8000 0x8000>;
> };
> };
> 
> After fdt_pack_reg() reads the first addr/size entry from such memory
> node, the "p" pointer becomes 12 bytes shifted from its original value
> (8 bytes for two address cells + 4 bytes for one size cell). So now it's
> not 64-bit aligned, and an attempt to do 64-bit bus access to that
> address will cause an abort like this:
> 
> "Synchronous Abort" handler, esr 0x9621, far 0xba235efc
> 
> This issue was originally reported by David Virag [1] who observed it
> happening on Samsung Exynos7885 SoC (ARM64), and later the same issue
> was observed on Samsung Exynos850 (ARM64).
> 
> Fix the issue by using put_unaligned_be64() helper, which takes care of
> possible unaligned 64-bit accesses. That solution was proposed by Simon
> Glass in the original thread [1].
> 
> [1] https://lists.denx.de/pipermail/u-boot/2023-July/522074.html
> 
> Fixes: 739a01ed8e02 ("fdt_support: fix an endian bug of 
> fdt_fixup_memory_banks")
> Suggested-by: Simon Glass 
> Reported-by: David Virag 
> Closes: https://lists.denx.de/pipermail/u-boot/2023-July/522074.html
> Signed-off-by: Sam Protsenko 
> Reviewed-by: Heinrich Schuchardt 

Applied to u-boot/master, thanks!

-- 
Tom


signature.asc
Description: PGP signature


Re: [PATCH] fdt: Fix fdt_pack_reg() on 64-bit platforms

2024-03-29 Thread Heinrich Schuchardt

On 3/30/24 01:55, Sam Protsenko wrote:

When "memory" node is being processed in fdt_pack_reg() on ARM64
platforms, an unaligned bus access might happen, which leads to
"synchronous abort" CPU exception. Consider next dts example:

 / {
 #address-cells = <2>;
 #size-cells = <1>;

 memory@8000 {
 device_type = "memory";
 reg = <0x0 0x8000 0x3ab0>,
   <0x0 0xc000 0x4000>,
   <0x8 0x8000 0x8000>;
 };
 };

After fdt_pack_reg() reads the first addr/size entry from such memory
node, the "p" pointer becomes 12 bytes shifted from its original value
(8 bytes for two address cells + 4 bytes for one size cell). So now it's
not 64-bit aligned, and an attempt to do 64-bit bus access to that
address will cause an abort like this:

 "Synchronous Abort" handler, esr 0x9621, far 0xba235efc

This issue was originally reported by David Virag [1] who observed it
happening on Samsung Exynos7885 SoC (ARM64), and later the same issue
was observed on Samsung Exynos850 (ARM64).

Fix the issue by using put_unaligned_be64() helper, which takes care of
possible unaligned 64-bit accesses. That solution was proposed by Simon
Glass in the original thread [1].

[1] https://lists.denx.de/pipermail/u-boot/2023-July/522074.html

Fixes: 739a01ed8e02 ("fdt_support: fix an endian bug of fdt_fixup_memory_banks")
Suggested-by: Simon Glass 
Reported-by: David Virag 
Closes: https://lists.denx.de/pipermail/u-boot/2023-July/522074.html
Signed-off-by: Sam Protsenko 


Reviewed-by: Heinrich Schuchardt 


---
  boot/fdt_support.c | 5 +++--
  1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/boot/fdt_support.c b/boot/fdt_support.c
index 090d82ee80a5..9844c70be806 100644
--- a/boot/fdt_support.c
+++ b/boot/fdt_support.c
@@ -17,6 +17,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -421,13 +422,13 @@ static int fdt_pack_reg(const void *fdt, void *buf, u64 
*address, u64 *size,

for (i = 0; i < n; i++) {
if (address_cells == 2)
-   *(fdt64_t *)p = cpu_to_fdt64(address[i]);
+   put_unaligned_be64(address[i], p);
else
*(fdt32_t *)p = cpu_to_fdt32(address[i]);
p += 4 * address_cells;

if (size_cells == 2)
-   *(fdt64_t *)p = cpu_to_fdt64(size[i]);
+   put_unaligned_be64(size[i], p);
else
*(fdt32_t *)p = cpu_to_fdt32(size[i]);
p += 4 * size_cells;




[PATCH] fdt: Fix fdt_pack_reg() on 64-bit platforms

2024-03-29 Thread Sam Protsenko
When "memory" node is being processed in fdt_pack_reg() on ARM64
platforms, an unaligned bus access might happen, which leads to
"synchronous abort" CPU exception. Consider next dts example:

/ {
#address-cells = <2>;
#size-cells = <1>;

memory@8000 {
device_type = "memory";
reg = <0x0 0x8000 0x3ab0>,
  <0x0 0xc000 0x4000>,
  <0x8 0x8000 0x8000>;
};
};

After fdt_pack_reg() reads the first addr/size entry from such memory
node, the "p" pointer becomes 12 bytes shifted from its original value
(8 bytes for two address cells + 4 bytes for one size cell). So now it's
not 64-bit aligned, and an attempt to do 64-bit bus access to that
address will cause an abort like this:

"Synchronous Abort" handler, esr 0x9621, far 0xba235efc

This issue was originally reported by David Virag [1] who observed it
happening on Samsung Exynos7885 SoC (ARM64), and later the same issue
was observed on Samsung Exynos850 (ARM64).

Fix the issue by using put_unaligned_be64() helper, which takes care of
possible unaligned 64-bit accesses. That solution was proposed by Simon
Glass in the original thread [1].

[1] https://lists.denx.de/pipermail/u-boot/2023-July/522074.html

Fixes: 739a01ed8e02 ("fdt_support: fix an endian bug of fdt_fixup_memory_banks")
Suggested-by: Simon Glass 
Reported-by: David Virag 
Closes: https://lists.denx.de/pipermail/u-boot/2023-July/522074.html
Signed-off-by: Sam Protsenko 
---
 boot/fdt_support.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/boot/fdt_support.c b/boot/fdt_support.c
index 090d82ee80a5..9844c70be806 100644
--- a/boot/fdt_support.c
+++ b/boot/fdt_support.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -421,13 +422,13 @@ static int fdt_pack_reg(const void *fdt, void *buf, u64 
*address, u64 *size,
 
for (i = 0; i < n; i++) {
if (address_cells == 2)
-   *(fdt64_t *)p = cpu_to_fdt64(address[i]);
+   put_unaligned_be64(address[i], p);
else
*(fdt32_t *)p = cpu_to_fdt32(address[i]);
p += 4 * address_cells;
 
if (size_cells == 2)
-   *(fdt64_t *)p = cpu_to_fdt64(size[i]);
+   put_unaligned_be64(size[i], p);
else
*(fdt32_t *)p = cpu_to_fdt32(size[i]);
p += 4 * size_cells;
-- 
2.39.2