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

[PATCH 28/36] xen/arm: introduce xen_map_text_rw



From: Luca Miccio <lucmiccio@xxxxxxxxx>

Introduce two new arm specific functions to temporarily map/unmap the
Xen text read-write (the Xen text is mapped read-only by default by
setup_pagetables): xen_map_text_rw and xen_unmap_text_rw.

There is only one caller in the alternative framework.

The non-colored implementation simply uses __vmap to do the mapping. In
other words, there are no changes to the non-colored case.

The colored implementation calculates Xen text physical addresses
appropriately, according to the coloring configuration.

Export vm_alloc because it is needed by the colored implementation of
xen_map_text_rw.

Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxx>
Signed-off-by: Luca Miccio <lucmiccio@xxxxxxxxx>
---
 xen/arch/arm/alternative.c    |  8 ++------
 xen/arch/arm/include/asm/mm.h |  3 +++
 xen/arch/arm/mm.c             | 38 +++++++++++++++++++++++++++++++++++
 xen/common/vmap.c             |  4 ++--
 xen/include/xen/vmap.h        |  2 ++
 5 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/xen/arch/arm/alternative.c b/xen/arch/arm/alternative.c
index 237c4e5642..2481521c9c 100644
--- a/xen/arch/arm/alternative.c
+++ b/xen/arch/arm/alternative.c
@@ -185,9 +185,6 @@ static int __apply_alternatives_multi_stop(void *unused)
     {
         int ret;
         struct alt_region region;
-        mfn_t xen_mfn = virt_to_mfn(_start);
-        paddr_t xen_size = _end - _start;
-        unsigned int xen_order = get_order_from_bytes(xen_size);
         void *xenmap;
 
         BUG_ON(patched);
@@ -196,8 +193,7 @@ static int __apply_alternatives_multi_stop(void *unused)
          * The text and inittext section are read-only. So re-map Xen to
          * be able to patch the code.
          */
-        xenmap = __vmap(&xen_mfn, 1U << xen_order, 1, 1, PAGE_HYPERVISOR,
-                        VMAP_DEFAULT);
+        xenmap = xen_map_text_rw();
         /* Re-mapping Xen is not expected to fail during boot. */
         BUG_ON(!xenmap);
 
@@ -208,7 +204,7 @@ static int __apply_alternatives_multi_stop(void *unused)
         /* The patching is not expected to fail during boot. */
         BUG_ON(ret != 0);
 
-        vunmap(xenmap);
+        xen_unmap_text_rw(xenmap);
 
         /* Barriers provided by the cache flushing */
         write_atomic(&patched, 1);
diff --git a/xen/arch/arm/include/asm/mm.h b/xen/arch/arm/include/asm/mm.h
index 1422091436..defb1efaad 100644
--- a/xen/arch/arm/include/asm/mm.h
+++ b/xen/arch/arm/include/asm/mm.h
@@ -195,6 +195,9 @@ extern void mmu_init_secondary_cpu(void);
 extern void setup_xenheap_mappings(unsigned long base_mfn, unsigned long 
nr_mfns);
 /* Map a frame table to cover physical addresses ps through pe */
 extern void setup_frametable_mappings(paddr_t ps, paddr_t pe);
+/* Create temporary Xen text read-write mapping */
+extern void *xen_map_text_rw(void);
+extern void xen_unmap_text_rw(void *va);
 /* Map a 4k page in a fixmap entry */
 extern void set_fixmap(unsigned map, mfn_t mfn, unsigned attributes);
 /* Remove a mapping from a fixmap entry */
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 53ea13641b..b18c7cd373 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -637,6 +637,31 @@ static void clear_table(void *table)
 }
 
 #ifdef CONFIG_COLORING
+void* __init xen_map_text_rw(void)
+{
+    paddr_t xen_paddr = __pa(_start);
+    unsigned int xen_size = 1 << get_order_from_bytes(_end - _start);
+    void *va = vm_alloc(xen_size, 1, VMAP_DEFAULT);
+    unsigned long cur = (unsigned long)va;
+    mfn_t mfn_col;
+    unsigned int i;
+
+    for ( i = 0; i < xen_size; i++, cur += PAGE_SIZE )
+    {
+        xen_paddr = next_xen_colored(xen_paddr);
+        mfn_col = maddr_to_mfn(xen_paddr);
+        if ( map_pages_to_xen(cur, mfn_col, 1, PAGE_HYPERVISOR) )
+            return NULL;
+        xen_paddr += PAGE_SIZE;
+    }
+    return va;
+}
+
+void __init xen_unmap_text_rw(void *va)
+{
+    vunmap(va);
+}
+
 /*
  * Translate a Xen (.text) virtual address to the colored physical one
  * depending on the hypervisor configuration.
@@ -796,6 +821,19 @@ void __init setup_pagetables(unsigned long 
boot_phys_offset, paddr_t xen_paddr)
     xen_pt_enforce_wnx();
 }
 #else
+void* __init xen_map_text_rw(void)
+{
+    unsigned int xen_order = get_order_from_bytes(_end - _start);
+    mfn_t xen_mfn = virt_to_mfn(_start);
+    return __vmap(&xen_mfn, 1U << xen_order, 1, 1, PAGE_HYPERVISOR,
+                  VMAP_DEFAULT);
+}
+
+void __init xen_unmap_text_rw(void *va)
+{
+    vunmap(va);
+}
+
 /* 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)
diff --git a/xen/common/vmap.c b/xen/common/vmap.c
index 4fd6b3067e..bedfc9d418 100644
--- a/xen/common/vmap.c
+++ b/xen/common/vmap.c
@@ -45,8 +45,8 @@ void __init vm_init_type(enum vmap_region type, void *start, 
void *end)
     populate_pt_range(va, vm_low[type] - nr);
 }
 
-static void *vm_alloc(unsigned int nr, unsigned int align,
-                      enum vmap_region t)
+void *vm_alloc(unsigned int nr, unsigned int align,
+               enum vmap_region t)
 {
     unsigned int start, bit;
 
diff --git a/xen/include/xen/vmap.h b/xen/include/xen/vmap.h
index b0f7632e89..dcf2be692f 100644
--- a/xen/include/xen/vmap.h
+++ b/xen/include/xen/vmap.h
@@ -12,6 +12,8 @@ enum vmap_region {
 
 void vm_init_type(enum vmap_region type, void *start, void *end);
 
+void *vm_alloc(unsigned int nr, unsigned int align,
+               enum vmap_region t);
 void *__vmap(const mfn_t *mfn, unsigned int granularity, unsigned int nr,
              unsigned int align, unsigned int flags, enum vmap_region);
 void *vmap(const mfn_t *mfn, unsigned int nr);
-- 
2.30.2




 


Rackspace

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