xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Campbell <ian.campbell@citrix.com>
To: xen-devel@lists.xen.org
Cc: julien.grall@linaro.org, tim@xen.org,
	Ian Campbell <ian.campbell@citrix.com>,
	stefano.stabellini@eu.citrix.com
Subject: [PATCH] xen: arm: handle initrd addresses above the 4G boundary
Date: Thu, 5 Dec 2013 14:42:20 +0000	[thread overview]
Message-ID: <1386254540-14231-1-git-send-email-ian.campbell@citrix.com> (raw)

The Xgene platform has no RAM below 4G.

The /chosen/linux,initrd-* properties do not have "reg" semantics and
therefore #*-size are not used when interpreting. Instead they are are simply
numbers which are interpreted according to the properties length.

Fix this both when parsing the entry in the host DTB and when creating the
dom0 DTB. For dom0 we simply hardcode a 64-bit size, this is acceptable
even for a 32-bit guest.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
---
 xen/arch/arm/domain_build.c   |   19 +++++++++++++------
 xen/common/device_tree.c      |   26 ++++++++++++++++++++++----
 xen/include/xen/device_tree.h |    8 +++++++-
 3 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 7b9031b..aac24eb 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -222,11 +222,12 @@ static int write_properties(struct domain *d, struct kernel_info *kinfo,
          */
         if ( early_info.modules.module[MOD_INITRD].size )
         {
-            res = fdt_property_cell(kinfo->fdt, "linux,initrd-start", 0);
+            u64 a = 0;
+            res = fdt_property(kinfo->fdt, "linux,initrd-start", &a, sizeof(a));
             if ( res )
                 return res;
 
-            res = fdt_property_cell(kinfo->fdt, "linux,initrd-end", 0);
+            res = fdt_property(kinfo->fdt, "linux,initrd-end", &a, sizeof(a));
             if ( res )
                 return res;
         }
@@ -923,6 +924,8 @@ static void initrd_load(struct kernel_info *kinfo)
     unsigned long offs;
     int node;
     int res;
+    u32 val[2];
+    __be32 *cellp;
 
     if ( !len )
         return;
@@ -935,13 +938,17 @@ static void initrd_load(struct kernel_info *kinfo)
     if ( node < 0 )
         panic("Cannot find the /chosen node");
 
-    res = fdt_setprop_inplace_cell(kinfo->fdt, node, "linux,initrd-start",
-                                   load_addr);
+    cellp = (__be32 *)val;
+    dt_set_cell(&cellp, ARRAY_SIZE(val), load_addr);
+    res = fdt_setprop_inplace(kinfo->fdt, node, "linux,initrd-start",
+                              val, sizeof(val));
     if ( res )
         panic("Cannot fix up \"linux,initrd-start\" property");
 
-    res = fdt_setprop_inplace_cell(kinfo->fdt, node, "linux,initrd-end",
-                                   load_addr + len);
+    cellp = (__be32 *)val;
+    dt_set_cell(&cellp, ARRAY_SIZE(val), load_addr + len);
+    res = fdt_setprop_inplace(kinfo->fdt, node, "linux,initrd-end",
+                              val, sizeof(val));
     if ( res )
         panic("Cannot fix up \"linux,initrd-end\" property");
 
diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index 943b181..2b1b364 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -390,18 +390,36 @@ static void __init process_chosen_node(const void *fdt, int node,
                                        const char *name,
                                        u32 address_cells, u32 size_cells)
 {
+    const struct fdt_property *prop;
     struct dt_mb_module *mod = &early_info.modules.module[MOD_INITRD];
-    u32 start, end;
+    paddr_t start, end;
+    int len;
 
     dt_printk("Checking for initrd in /chosen\n");
 
-    start = device_tree_get_u32(fdt, node, "linux,initrd-start", 0);
-    end = device_tree_get_u32(fdt, node, "linux,initrd-end", 0);
+    prop = fdt_get_property(fdt, node, "linux,initrd-start", &len);
+    if ( !prop || len < sizeof(u32) || len > sizeof(u64) )
+    {
+        dt_printk("err start %p len %d %ld %ld\n", prop, len, sizeof(u32), sizeof(u64));
+        return;
+    }
+    start = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
+
+    prop = fdt_get_property(fdt, node, "linux,initrd-end", &len);
+    if ( !prop || len < sizeof(u32) || len > sizeof(u64) )
+    {
+        dt_printk("err end %p len %d %ld %ld\n", prop, len, sizeof(u32), sizeof(u64));
+        return;
+    }
+    end = dt_read_number((void *)&prop->data, dt_size_to_cells(len));
 
     if ( !start || !end || (start >= end) )
+    {
+        dt_printk("err limits\n");
         return;
+    }
 
-    dt_printk("Initrd 0x%x-0x%x\n", start, end);
+    dt_printk("Initrd %"PRIpaddr"-%"PRIpaddr"\n", start, end);
 
     mod->start = start;
     mod->size = end - start;
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index da78c9f..9f23b07 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -256,12 +256,18 @@ static inline u64 dt_read_number(const __be32 *cell, int size)
     return r;
 }
 
-/* Helper to convert a number of cells in bytes */
+/* Helper to convert a number of cells to bytes */
 static inline int dt_cells_to_size(int size)
 {
     return (size * sizeof (u32));
 }
 
+/* Helper to convert a number of bytes to cells  */
+static inline int dt_size_to_cells(int cells)
+{
+    return (cells / sizeof(u32));
+}
+
 static inline u64 dt_next_cell(int s, const __be32 **cellp)
 {
     const __be32 *p = *cellp;
-- 
1.7.10.4

             reply	other threads:[~2013-12-05 14:42 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-12-05 14:42 Ian Campbell [this message]
2013-12-06 15:50 ` [PATCH] xen: arm: handle initrd addresses above the 4G boundary Julien Grall
2013-12-06 16:58   ` Ian Campbell
2013-12-06 17:39     ` Julien Grall
2013-12-09 11:15       ` Ian Campbell
2013-12-09 13:52         ` Julien Grall
2013-12-09 14:00           ` Ian Campbell
2013-12-09 14:11             ` Julien Grall
2013-12-09 14:15               ` Ian Campbell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1386254540-14231-1-git-send-email-ian.campbell@citrix.com \
    --to=ian.campbell@citrix.com \
    --cc=julien.grall@linaro.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).