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

[Xen-devel] [PATCH v4 1/7] xen/arm: introduce early_ioremap



Introduce a function to map a range of physical memory into Xen virtual
memory.
It doesn't need domheap to be setup.
It is going to be used to map the videoram.

Add flush_xen_data_tlb_range_va, that flushes a range of virtual addresses.
Replace all the calls to flush_xen_data_tlb_va with calls to
flush_xen_data_tlb_range_va and remove flush_xen_data_tlb_va.

In the case of the dest_va tlb flush at the beginning of
setup_pagetables, flush the entire 2MB mapping rather than just the
first 4K.


Changes in v4:
- rename flush_xen_data_tlb_range to flush_xen_data_tlb_range_va;
- replace all the calls to flush_xen_data_tlb_va, with calls to
flush_xen_data_tlb_range_va;
- flush the entire 2MB mapping at BOOT_MISC_VIRT_START rather than just
the first 4k;
- remove flush_xen_data_tlb_va;
- fix indentation;
- rename EARLY_VMAP_START/END to EARLY_VMAP_VIRT_START/END;
- mark early_ioremap as __init;
- reduce the amount of casts in early_ioremap.


Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 xen/arch/arm/mm.c            |   40 ++++++++++++++++++++++++++++++++++++----
 xen/include/asm-arm/config.h |    4 ++++
 xen/include/asm-arm/mm.h     |    3 ++-
 xen/include/asm-arm/page.h   |   24 +++++++++++++++++-------
 4 files changed, 59 insertions(+), 12 deletions(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index 855f83d..ca66395 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -112,7 +112,7 @@ void set_fixmap(unsigned map, unsigned long mfn, unsigned 
attributes)
     pte.pt.ai = attributes;
     pte.pt.xn = 1;
     write_pte(xen_fixmap + third_table_offset(FIXMAP_ADDR(map)), pte);
-    flush_xen_data_tlb_va(FIXMAP_ADDR(map));
+    flush_xen_data_tlb_range_va(FIXMAP_ADDR(map), PAGE_SIZE);
 }
 
 /* Remove a mapping from a fixmap entry */
@@ -120,7 +120,7 @@ void clear_fixmap(unsigned map)
 {
     lpae_t pte = {0};
     write_pte(xen_fixmap + third_table_offset(FIXMAP_ADDR(map)), pte);
-    flush_xen_data_tlb_va(FIXMAP_ADDR(map));
+    flush_xen_data_tlb_range_va(FIXMAP_ADDR(map), PAGE_SIZE);
 }
 
 /* Map a page of domheap memory */
@@ -184,7 +184,7 @@ void *map_domain_page(unsigned long mfn)
      * We may not have flushed this specific subpage at map time,
      * since we only flush the 4k page not the superpage
      */
-    flush_xen_data_tlb_va(va);
+    flush_xen_data_tlb_range_va(va, PAGE_SIZE);
 
     return (void *)va;
 }
@@ -219,7 +219,7 @@ void __init setup_pagetables(unsigned long 
boot_phys_offset, paddr_t xen_paddr)
     dest_va = BOOT_MISC_VIRT_START;
     pte = mfn_to_xen_entry(xen_paddr >> PAGE_SHIFT);
     write_pte(xen_second + second_table_offset(dest_va), pte);
-    flush_xen_data_tlb_va(dest_va);
+    flush_xen_data_tlb_range_va(dest_va, SECOND_SIZE);
 
     /* Calculate virt-to-phys offset for the new location */
     phys_offset = xen_paddr - (unsigned long) _start;
@@ -367,6 +367,38 @@ void __init setup_frametable_mappings(paddr_t ps, paddr_t 
pe)
     frametable_virt_end = FRAMETABLE_VIRT_START + (nr_pages * sizeof(struct 
page_info));
 }
 
+/* Map the physical memory range start -  start + len into virtual
+ * memory and return the virtual address of the mapping.
+ * start has to be 2MB aligned.
+ * len has to be < EARLY_VMAP_VIRT_END - EARLY_VMAP_VIRT_START.
+ */
+void* __init early_ioremap(paddr_t start, size_t len, unsigned attributes)
+{
+    static unsigned long virt_start = EARLY_VMAP_VIRT_START;
+    unsigned long ret_addr = virt_start;
+    paddr_t end = start + len;
+
+    ASSERT(!(start & (~SECOND_MASK)));
+    ASSERT(!(virt_start & (~SECOND_MASK)));
+
+    /* The range we need to map is too big */
+    if ( virt_start + len >= EARLY_VMAP_VIRT_END )
+        return NULL;
+
+    while ( start < end )
+    {
+        lpae_t e = mfn_to_xen_entry(start >> PAGE_SHIFT);
+        e.pt.ai = attributes;
+        write_pte(xen_second + second_table_offset(virt_start), e);
+
+        start += SECOND_SIZE;
+        virt_start += SECOND_SIZE;
+    }
+    flush_xen_data_tlb_range_va(ret_addr, len);
+
+    return (void*)ret_addr;
+}
+
 enum mg { mg_clear, mg_ro, mg_rw, mg_rx };
 static void set_pte_flags_on_range(const char *p, unsigned long l, enum mg mg)
 {
diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
index 2a05539..e5dce5e 100644
--- a/xen/include/asm-arm/config.h
+++ b/xen/include/asm-arm/config.h
@@ -60,6 +60,8 @@
  *  6M  -  8M   Early boot misc (see below)
  *
  * 32M - 128M   Frametable: 24 bytes per page for 16GB of RAM
+ * 256M -  1G   VMAP: ioremap and early_ioremap use this virtual address
+ *                    space
  *
  *  1G -   2G   Xenheap: always-mapped memory
  *  2G -   4G   Domheap: on-demand-mapped
@@ -73,9 +75,11 @@
 #define FIXMAP_ADDR(n)        (mk_unsigned_long(0x00400000) + (n) * PAGE_SIZE)
 #define BOOT_MISC_VIRT_START   mk_unsigned_long(0x00600000)
 #define FRAMETABLE_VIRT_START  mk_unsigned_long(0x02000000)
+#define EARLY_VMAP_VIRT_START  mk_unsigned_long(0x10000000)
 #define XENHEAP_VIRT_START     mk_unsigned_long(0x40000000)
 #define DOMHEAP_VIRT_START     mk_unsigned_long(0x80000000)
 
+#define EARLY_VMAP_VIRT_END    XENHEAP_VIRT_START
 #define HYPERVISOR_VIRT_START  XEN_VIRT_START
 
 #define DOMHEAP_ENTRIES        1024  /* 1024 2MB mapping slots */
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index e95ece1..4ed5df6 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -150,7 +150,8 @@ extern void setup_frametable_mappings(paddr_t ps, paddr_t 
pe);
 extern void set_fixmap(unsigned map, unsigned long mfn, unsigned attributes);
 /* Remove a mapping from a fixmap entry */
 extern void clear_fixmap(unsigned map);
-
+/* map a 2MB aligned physical range in virtual memory. */
+void* early_ioremap(paddr_t start, size_t len, unsigned attributes);
 
 #define mfn_valid(mfn)        ({                                              \
     unsigned long __m_f_n = (mfn);                                            \
diff --git a/xen/include/asm-arm/page.h b/xen/include/asm-arm/page.h
index d89261e..fb4febc 100644
--- a/xen/include/asm-arm/page.h
+++ b/xen/include/asm-arm/page.h
@@ -316,16 +316,20 @@ static inline void flush_xen_data_tlb(void)
 }
 
 /*
- * Flush one VA's hypervisor mappings from the data TLB. This is not
+ * Flush a range of VA's hypervisor mappings from the data TLB. This is not
  * sufficient when changing code mappings or for self modifying code.
  */
-static inline void flush_xen_data_tlb_va(unsigned long va)
+static inline void flush_xen_data_tlb_range_va(unsigned long va, unsigned long 
size)
 {
-    asm volatile("dsb;" /* Ensure preceding are visible */
-                 STORE_CP32(0, TLBIMVAH)
-                 "dsb;" /* Ensure completion of the TLB flush */
-                 "isb;"
-                 : : "r" (va) : "memory");
+    unsigned long end = va + size;
+    while ( va < end ) {
+        asm volatile("dsb;" /* Ensure preceding are visible */
+                     STORE_CP32(0, TLBIMVAH)
+                     "dsb;" /* Ensure completion of the TLB flush */
+                     "isb;"
+                     : : "r" (va) : "memory");
+        va += PAGE_SIZE;
+    }
 }
 
 /* Flush all non-hypervisor mappings from the TLB */
@@ -418,8 +422,14 @@ static inline uint64_t gva_to_ipa(uint32_t va)
 #define LPAE_ENTRY_MASK (LPAE_ENTRIES - 1)
 
 #define THIRD_SHIFT  PAGE_SHIFT
+#define THIRD_SIZE   (1u << THIRD_SHIFT)
+#define THIRD_MASK   (~(THIRD_SIZE - 1))
 #define SECOND_SHIFT (THIRD_SHIFT + LPAE_SHIFT)
+#define SECOND_SIZE  (1u << SECOND_SHIFT)
+#define SECOND_MASK  (~(SECOND_SIZE - 1))
 #define FIRST_SHIFT  (SECOND_SHIFT + LPAE_SHIFT)
+#define FIRST_SIZE   (1u << FIRST_SHIFT)
+#define FIRST_MASK   (~(FIRST_SIZE - 1))
 
 /* Calculate the offsets into the pagetables for a given VA */
 #define first_linear_offset(va) (va >> FIRST_SHIFT)
-- 
1.7.2.5


_______________________________________________
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®.