diff mbox

arm: Create /chosen and /memory devicetree nodes if necessary

Message ID 1479346221-18474-1-git-send-email-linux@roeck-us.net
State New
Headers show

Commit Message

Guenter Roeck Nov. 17, 2016, 1:30 a.m. UTC
While customary, the /chosen and /memory devicetree nodes do not have to
exist. Create if necessary. Also create the /memory/device_type property
if needed.

Signed-off-by: Guenter Roeck <linux@roeck-us.net>
---
The problem is seen with the latest version of the Linux kernel in
linux-next (next-20161116), where many of the /chosen and /memory nodes
in arm devicetree files have been removed. This results in a kernel hang
(sabrelite) or qemu abort (imx25-pdk).

 hw/arm/boot.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Comments

Peter Maydell Nov. 28, 2016, 11:46 a.m. UTC | #1
On 17 November 2016 at 01:30, Guenter Roeck <linux@roeck-us.net> wrote:
> While customary, the /chosen and /memory devicetree nodes do not have to
> exist. Create if necessary. Also create the /memory/device_type property
> if needed.
>
> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
> ---
> The problem is seen with the latest version of the Linux kernel in
> linux-next (next-20161116), where many of the /chosen and /memory nodes
> in arm devicetree files have been removed. This results in a kernel hang
> (sabrelite) or qemu abort (imx25-pdk).

The lack of a memory node sounds to me like a bug in the Linux device
trees. The 0.1 specification at http://www.devicetree.org/specifications/
says on page 21 "the following nodes shall be present at the root of all
devicetrees: [...] At least one memory node".

There's no harm in QEMU being robust against bogus input, though,
especially if the dtbs are common in the wild, so this patch is
worth having. (And 'chosen' is definitely optional.)

I've applied this patch to target-arm.next.

thanks
-- PMM
diff mbox

Patch

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 942416d..ff621e4 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -9,6 +9,7 @@ 
 
 #include "qemu/osdep.h"
 #include "qapi/error.h"
+#include <libfdt.h>
 #include "hw/hw.h"
 #include "hw/arm/arm.h"
 #include "hw/arm/linux-boot-if.h"
@@ -486,6 +487,17 @@  static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
             g_free(nodename);
         }
     } else {
+        Error *err = NULL;
+
+        rc = fdt_path_offset(fdt, "/memory");
+        if (rc < 0) {
+            qemu_fdt_add_subnode(fdt, "/memory");
+        }
+
+        if (!qemu_fdt_getprop(fdt, "/memory", "device_type", NULL, &err)) {
+            qemu_fdt_setprop_string(fdt, "/memory", "device_type", "memory");
+        }
+
         rc = qemu_fdt_setprop_sized_cells(fdt, "/memory", "reg",
                                           acells, binfo->loader_start,
                                           scells, binfo->ram_size);
@@ -495,6 +507,11 @@  static int load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
         }
     }
 
+    rc = fdt_path_offset(fdt, "/chosen");
+    if (rc < 0) {
+        qemu_fdt_add_subnode(fdt, "/chosen");
+    }
+
     if (binfo->kernel_cmdline && *binfo->kernel_cmdline) {
         rc = qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
                                      binfo->kernel_cmdline);