Hi Detlev,

I've recently tried to update U-Boot from 2022.01 to 2022.04 and
noticed a regression introduced by the commit below.

While the unwanted error message ("Add 'reserved-memory' node failed:
FDT_ERR_EXISTS") no longer appears, I now see a lengthy kernel stack
trace in Linux instead:
...
[    0.008295] sysfs: cannot create duplicate filename 
'/devices/platform/42ff0000.ramoops'
[    0.008303] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G S                
5.15.33 #0
[    0.008312] Hardware name: Bananapi BPI-R64 (DT)
[    0.008318] Call trace:
[    0.008322]  dump_backtrace+0x0/0x15c
[    0.008337]  show_stack+0x14/0x30
[    0.008345]  dump_stack_lvl+0x64/0x7c
[    0.008355]  dump_stack+0x14/0x2c
[    0.008362]  sysfs_warn_dup+0x5c/0x74
[    0.008373]  sysfs_create_dir_ns+0xb0/0xc0
[    0.008381]  kobject_add_internal+0xbc/0x330
[    0.008392]  kobject_add+0x80/0xe0
[    0.008400]  device_add+0xd4/0x82c
[    0.008410]  of_device_add+0x4c/0x5c
[    0.008420]  of_platform_device_create_pdata+0xb8/0xf0
[    0.008428]  of_platform_default_populate_init+0x58/0xcc
[    0.008437]  do_one_initcall+0x4c/0x1b0
[    0.008444]  kernel_init_freeable+0x230/0x294
[    0.008456]  kernel_init+0x20/0x120
[    0.008463]  ret_from_fork+0x10/0x20
[    0.008471] kobject_add_internal failed for 42ff0000.ramoops with -EEXIST, 
don't try to register things with the same name in the same directory.
...

I assume that fdt_find_or_add_subnode() doesn't behave as expected and
apparently adds a duplicate node having the same name.
The pstore/ramoops reserved-memory is already defined in the fdt
contained in the FIT image (for compatibility with older U-Boot which
didn't care about pstore), so it should be not added again.


On Mon, Feb 07, 2022 at 11:02:30AM -0500, Detlev Casanova wrote:
> The pstore command tries to create a reserved-memory node but fails if
> it is already present with:
> 
>     Add 'reserved-memory' node failed: FDT_ERR_EXISTS
> 
> This patch creates the node only if it does not exist and adapts the reg
> values sizes depending on already present #address-cells and #size-cells
> values.
> 
> Signed-off-by: Detlev Casanova <detlev.casan...@collabora.com>
> ---
> 
> Changes in v2:
>  - Move declarations at beginning of function
>  - Use if instead of switch
>  - Reword Subject
> 
>  cmd/pstore.c | 39 ++++++++++++++++++++++++++++++++++-----
>  1 file changed, 34 insertions(+), 5 deletions(-)
> 
> diff --git a/cmd/pstore.c b/cmd/pstore.c
> index 9fac8c7218..cd6f6feb2f 100644
> --- a/cmd/pstore.c
> +++ b/cmd/pstore.c
> @@ -11,6 +11,7 @@
>  #include <mapmem.h>
>  #include <memalign.h>
>  #include <part.h>
> +#include <fdt_support.h>
>  
>  struct persistent_ram_buffer {
>       u32    sig;
> @@ -485,6 +486,8 @@ void fdt_fixup_pstore(void *blob)
>  {
>       char node[32];
>       int  nodeoffset;        /* node offset from libfdt */
> +     u32 addr_cells;
> +     u32 size_cells;
>  
>       nodeoffset = fdt_path_offset(blob, "/");
>       if (nodeoffset < 0) {
> @@ -493,14 +496,18 @@ void fdt_fixup_pstore(void *blob)
>               return;
>       }
>  
> -     nodeoffset = fdt_add_subnode(blob, nodeoffset, "reserved-memory");
> +     nodeoffset = fdt_find_or_add_subnode(blob, nodeoffset, 
> "reserved-memory");
>       if (nodeoffset < 0) {
>               log_err("Add 'reserved-memory' node failed: %s\n",
>                               fdt_strerror(nodeoffset));
>               return;
>       }
> -     fdt_setprop_u32(blob, nodeoffset, "#address-cells", 2);
> -     fdt_setprop_u32(blob, nodeoffset, "#size-cells", 2);
> +
> +     addr_cells = fdt_getprop_u32_default_node(blob, nodeoffset, 0, 
> "#address-cells", 2);
> +     size_cells = fdt_getprop_u32_default_node(blob, nodeoffset, 0, 
> "#size-cells", 2);
> +     fdt_setprop_u32(blob, nodeoffset, "#address-cells", addr_cells);
> +     fdt_setprop_u32(blob, nodeoffset, "#size-cells", size_cells);
> +
>       fdt_setprop_empty(blob, nodeoffset, "ranges");
>  
>       sprintf(node, "ramoops@%llx", (unsigned long long)pstore_addr);
> @@ -509,14 +516,36 @@ void fdt_fixup_pstore(void *blob)
>               log_err("Add '%s' node failed: %s\n", node, 
> fdt_strerror(nodeoffset));
>               return;
>       }
> +
>       fdt_setprop_string(blob, nodeoffset, "compatible", "ramoops");
> -     fdt_setprop_u64(blob, nodeoffset, "reg", pstore_addr);
> -     fdt_appendprop_u64(blob, nodeoffset, "reg", pstore_length);
> +
> +     if (addr_cells == 1) {
> +             fdt_setprop_u32(blob, nodeoffset, "reg", pstore_addr);
> +     } else if (addr_cells == 2) {
> +             fdt_setprop_u64(blob, nodeoffset, "reg", pstore_addr);
> +     } else {
> +             log_err("Unsupported #address-cells: %u\n", addr_cells);
> +             goto clean_ramoops;
> +     }
> +
> +     if (size_cells == 1) {
> +             // Let's consider that the pstore_length fits in a 32 bits value
> +             fdt_appendprop_u32(blob, nodeoffset, "reg", pstore_length);
> +     } else if (size_cells == 2) {
> +             fdt_appendprop_u64(blob, nodeoffset, "reg", pstore_length);
> +     } else {
> +             log_err("Unsupported #size-cells: %u\n", addr_cells);
> +             goto clean_ramoops;
> +     }
> +
>       fdt_setprop_u32(blob, nodeoffset, "record-size", pstore_record_size);
>       fdt_setprop_u32(blob, nodeoffset, "console-size", pstore_console_size);
>       fdt_setprop_u32(blob, nodeoffset, "ftrace-size", pstore_ftrace_size);
>       fdt_setprop_u32(blob, nodeoffset, "pmsg-size", pstore_pmsg_size);
>       fdt_setprop_u32(blob, nodeoffset, "ecc-size", pstore_ecc_size);
> +
> +clean_ramoops:
> +     fdt_del_node_and_alias(blob, node);
>  }
>  
>  U_BOOT_CMD(pstore, 10, 0, do_pstore,
> -- 
> 2.35.1
> 

Reply via email to