[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v2 6/9] xen/arm: Support dtb /memreserve/ regions



This requires a mapping of the DTB during setup_mm. Previously this was in the
BOOT_MISC slot, which is clobbered by setup_pagetables. Split it out into its
own slot which can be preserved.

Also handle these regions as part of consider_modules() and when adding pages
to the heaps to ensure we do not locate any part of Xen or the heaps over
them.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
v2: drop accidentally included debug prints
    fixed handling of avoid reserved regions with heaps
    don't discard initial modules, since the FDT can (but is not required to)
    be reserved
---
 xen/arch/arm/arm32/head.S    |    2 +-
 xen/arch/arm/arm64/head.S    |    2 +-
 xen/arch/arm/mm.c            |   10 ++++++-
 xen/arch/arm/setup.c         |   67 +++++++++++++++++++++++++++++++++++++++---
 xen/arch/arm/traps.c         |    1 -
 xen/common/device_tree.c     |   13 +++++++-
 xen/include/asm-arm/config.h |    7 +++--
 xen/include/asm-arm/mm.h     |    2 ++
 8 files changed, 92 insertions(+), 12 deletions(-)

diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S
index 79e95b6..5072e2a 100644
--- a/xen/arch/arm/arm32/head.S
+++ b/xen/arch/arm/arm32/head.S
@@ -301,7 +301,7 @@ cpu_init_done:
         orr   r2, r2, #PT_UPPER(MEM)
         orr   r2, r2, #PT_LOWER(MEM) /* r2:r3 := 2MB RAM incl. DTB */
         add   r4, r4, #8
-        strd  r2, r3, [r1, r4]       /* Map it in the early boot slot */
+        strd  r2, r3, [r1, r4]       /* Map it in the early fdt slot */
 
 pt_ready:
         PRINT("- Turning on paging -\r\n")
diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S
index 21b7e4d..33ff489 100644
--- a/xen/arch/arm/arm64/head.S
+++ b/xen/arch/arm/arm64/head.S
@@ -255,7 +255,7 @@ skip_bss:
         mov   x3, #PT_MEM            /* x2 := 2MB RAM incl. DTB */
         orr   x2, x2, x3
         add   x4, x4, #8
-        str   x2, [x1, x4]           /* Map it in the early boot slot */
+        str   x2, [x1, x4]           /* Map it in the early fdt slot */
 
 pt_ready:
         PRINT("- Turning on paging -\r\n")
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 69c157a..86e3207 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -361,6 +361,13 @@ static inline lpae_t pte_of_xenaddr(vaddr_t va)
     return mfn_to_xen_entry(mfn);
 }
 
+void __init remove_early_mappings(void)
+{
+    lpae_t pte = {0};
+    write_pte(xen_second + second_table_offset(BOOT_FDT_VIRT_START), pte);
+    flush_xen_data_tlb_range_va(BOOT_FDT_VIRT_START, SECOND_SIZE);
+}
+
 /* Boot-time pagetable setup.
  * Changes here may need matching changes in head.S */
 void __init setup_pagetables(unsigned long boot_phys_offset, paddr_t xen_paddr)
@@ -401,7 +408,8 @@ void __init setup_pagetables(unsigned long 
boot_phys_offset, paddr_t xen_paddr)
         p[second_linear_offset(va)].bits = 0;
     }
     for ( i = 0; i < 4 * LPAE_ENTRIES; i++)
-        if ( p[i].pt.valid )
+        /* The FDT is not relocated */
+        if ( p[i].pt.valid && i != second_linear_offset(BOOT_FDT_VIRT_START) )
             p[i].pt.base += (phys_offset - boot_phys_offset) >> PAGE_SHIFT;
 
     /* Change pagetables to the copy in the relocated Xen */
diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c
index 0d9eaf7..5a47bda 100644
--- a/xen/arch/arm/setup.c
+++ b/xen/arch/arm/setup.c
@@ -35,6 +35,7 @@
 #include <xen/cpu.h>
 #include <xen/pfn.h>
 #include <xen/vmap.h>
+#include <xen/libfdt/libfdt.h>
 #include <asm/page.h>
 #include <asm/current.h>
 #include <asm/setup.h>
@@ -147,6 +148,33 @@ static void __init processor_id(void)
     }
 }
 
+static void dt_unreserved_regions(paddr_t s, paddr_t e,
+                                  void (*cb)(paddr_t, paddr_t), int first)
+{
+    int i, nr = fdt_num_mem_rsv(device_tree_flattened);
+
+    for ( i = first; i < nr ; i++ )
+    {
+        paddr_t r_s, r_e;
+
+        if ( fdt_get_mem_rsv(device_tree_flattened, i, &r_s, &r_e ) < 0 )
+            /* If we can't read it, pretend it doesn't exist... */
+            continue;
+
+        r_e += r_s; /* fdt_get_mem_rsc returns length */
+
+
+        if ( s < r_e && r_s < e )
+        {
+            dt_unreserved_regions(r_e, e, cb, i+1);
+            dt_unreserved_regions(s, r_s, cb, i+1);
+            return;
+        }
+    }
+
+    cb(s, e);
+}
+
 void __init discard_initial_modules(void)
 {
     struct dt_module_info *mi = &early_info.modules;
@@ -157,10 +185,12 @@ void __init discard_initial_modules(void)
         paddr_t s = mi->module[i].start;
         paddr_t e = s + PAGE_ALIGN(mi->module[i].size);
 
-        init_domheap_pages(s, e);
+        dt_unreserved_regions(s, e, init_domheap_pages, 0);
     }
 
     mi->nr_mods = 0;
+
+    remove_early_mappings();
 }
 
 /*
@@ -177,6 +207,7 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e,
 {
     const struct dt_module_info *mi = &early_info.modules;
     int i;
+    int nr_rsvd;
 
     s = (s+align-1) & ~(align-1);
     e = e & ~(align-1);
@@ -184,6 +215,7 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t e,
     if ( s > e ||  e - s < size )
         return 0;
 
+    /* First check the boot modules */
     for ( i = first_mod; i <= mi->nr_mods; i++ )
     {
         paddr_t mod_s = mi->module[i].start;
@@ -199,6 +231,32 @@ static paddr_t __init consider_modules(paddr_t s, paddr_t 
e,
         }
     }
 
+    /* Now check any fdt reserved areas. */
+
+    nr_rsvd = fdt_num_mem_rsv(device_tree_flattened);
+
+    for ( ; i < mi->nr_mods + nr_rsvd; i++ )
+    {
+        paddr_t mod_s, mod_e;
+
+        if ( fdt_get_mem_rsv(device_tree_flattened,
+                             i - mi->nr_mods,
+                             &mod_s, &mod_e ) < 0 )
+            /* If we can't read it, pretend it doesn't exist... */
+            continue;
+
+        /* fdt_get_mem_rsv returns length */
+        mod_e += mod_s;
+
+        if ( s < mod_e && mod_s < e )
+        {
+            mod_e = consider_modules(mod_e, e, size, align, i+1);
+            if ( mod_e )
+                return mod_e;
+
+            return consider_modules(s, mod_s, size, align, i+1);
+        }
+    }
     return e;
 }
 
@@ -226,6 +284,7 @@ static paddr_t __init next_module(paddr_t s, paddr_t *n)
         lowest = mod_s;
         *n = mod_e;
     }
+
     return lowest;
 }
 
@@ -401,7 +460,7 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t 
dtb_size)
             n = pfn_to_paddr(xenheap_mfn_start+xenheap_pages);
         }
 
-        init_boot_pages(s, e);
+        dt_unreserved_regions(s, e, init_boot_pages, 0);
 
         s = n;
     }
@@ -460,7 +519,7 @@ static void __init setup_mm(unsigned long dtb_paddr, size_t 
dtb_size)
 
             xenheap_mfn_end = e;
 
-            init_boot_pages(s, e);
+            dt_unreserved_regions(s, e, init_boot_pages, 0);
             s = n;
         }
     }
@@ -524,7 +583,7 @@ void __init start_xen(unsigned long boot_phys_offset,
     smp_clear_cpu_maps();
 
     /* This is mapped by head.S */
-    device_tree_flattened = (void *)BOOT_MISC_VIRT_START
+    device_tree_flattened = (void *)BOOT_FDT_VIRT_START
         + (fdt_paddr & ((1 << SECOND_SHIFT) - 1));
     fdt_size = device_tree_early_init(device_tree_flattened, fdt_paddr);
 
diff --git a/xen/arch/arm/traps.c b/xen/arch/arm/traps.c
index 0e9a141..aacbd18 100644
--- a/xen/arch/arm/traps.c
+++ b/xen/arch/arm/traps.c
@@ -810,7 +810,6 @@ void vcpu_show_execution_state(struct vcpu *v)
 
 void do_unexpected_trap(const char *msg, struct cpu_user_regs *regs)
 {
-    printk("CPU%d: Unexpected Trap: %s\n", smp_processor_id(), msg);
     show_execution_state(regs);
     while(1);
 }
diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index 9e0c224..132a2bd 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -489,7 +489,7 @@ static void __init early_print_info(void)
 {
     struct dt_mem_info *mi = &early_info.mem;
     struct dt_module_info *mods = &early_info.modules;
-    int i;
+    int i, nr_rsvd;
 
     for ( i = 0; i < mi->nr_banks; i++ )
         early_printk("RAM: %"PRIpaddr" - %"PRIpaddr"\n",
@@ -502,6 +502,17 @@ static void __init early_print_info(void)
                      mods->module[i].start,
                      mods->module[i].start + mods->module[i].size,
                      mods->module[i].cmdline);
+    nr_rsvd = fdt_num_mem_rsv(device_tree_flattened);
+    for ( i = 0; i < nr_rsvd; i++ )
+    {
+        paddr_t s, e;
+        if ( fdt_get_mem_rsv(device_tree_flattened, i, &s, &e) < 0 )
+            continue;
+        /* fdt_get_mem_rsv returns length */
+        e += s;
+        early_printk(" RESVD[%d]: %"PRIpaddr" - %"PRIpaddr"\n",
+                     i, s, e);
+    }
 }
 
 /**
diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
index 624c73e..efeb952 100644
--- a/xen/include/asm-arm/config.h
+++ b/xen/include/asm-arm/config.h
@@ -80,10 +80,10 @@
  *   0  -   2M   Unmapped
  *   2M -   4M   Xen text, data, bss
  *   4M -   6M   Fixmap: special-purpose 4K mapping slots
- *   6M -   8M   Early boot misc (see below)
+ *   6M -   8M   Early boot mapping of FDT
+ *   8M -  10M   Early boot misc (see below)
  *
  * The early boot misc area is used:
- *   - in head.S for the DTB for device_tree_early_init().
  *   - in setup_pagetables() when relocating Xen.
  *
  * ARM32 layout:
@@ -116,7 +116,8 @@
 
 #define XEN_VIRT_START         _AT(vaddr_t,0x00200000)
 #define FIXMAP_ADDR(n)        (_AT(vaddr_t,0x00400000) + (n) * PAGE_SIZE)
-#define BOOT_MISC_VIRT_START   _AT(vaddr_t,0x00600000)
+#define BOOT_FDT_VIRT_START    _AT(vaddr_t,0x00600000)
+#define BOOT_MISC_VIRT_START   _AT(vaddr_t,0x00800000)
 
 #define HYPERVISOR_VIRT_START  XEN_VIRT_START
 
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 97c2ee0..467687a 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -155,6 +155,8 @@ extern unsigned long total_pages;
 
 /* Boot-time pagetable setup */
 extern void setup_pagetables(unsigned long boot_phys_offset, paddr_t 
xen_paddr);
+/* Remove early mappings */
+extern void remove_early_mappings(void);
 /* Allocate and initialise pagetables for a secondary CPU */
 extern int __cpuinit init_secondary_pagetables(int cpu);
 /* Switch secondary CPUS to its own pagetables and finalise MMU setup */
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.