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

[Minios-devel] [PATCH v2 32/47] arm64: implement the mmap/munmap



This patch implements the mmap/munmap by adding:
   map_frames_ex()/unmap_frames/map_zero

flush_tlb_page() is used to invalidate a page.

Signed-off-by: Huang Shijie <shijie.huang@xxxxxxx>
---
 arch/arm/mm.c          | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/arm/arch_mm.h  |  4 +++
 include/arm/arm64/os.h | 16 ++++++++++++
 3 files changed, 87 insertions(+)

diff --git a/arch/arm/mm.c b/arch/arm/mm.c
index 839356d..f998a53 100644
--- a/arch/arm/mm.c
+++ b/arch/arm/mm.c
@@ -322,6 +322,73 @@ void *ioremap(paddr_t paddr, unsigned long size)
     return (void*)addr;
 }
 
+void *map_frames_ex(const unsigned long *f, unsigned long n, unsigned long 
stride,
+                    unsigned long increment, unsigned long alignment, domid_t 
id,
+                    int *err, unsigned long prot)
+{
+    unsigned long addr, va;
+    unsigned long done = 0;
+    unsigned long mfn;
+    int ret;
+
+    if (!f)
+        return NULL;
+
+    addr = allocate_ondemand(n, alignment);
+    if (!addr)
+        return NULL;
+
+    va = addr;
+
+    while (done < n) {
+        mfn = f[done * stride] + done * increment;
+        ret = build_pagetable(va, mfn, 1, prot, alloc_new_page, 3);
+        if (ret)
+            return NULL;
+        done++;
+        va += PAGE_SIZE;
+    }
+
+    return (void *)addr;
+}
+
+static lpae_t *get_ptep(unsigned long vaddr)
+{
+    lpae_t *pgd, *pud, *pmd, *pte;
+
+    pgd = &boot_l0_pgtable[l0_pgt_idx(vaddr)];
+    ASSERT((*pgd) != L0_INVAL);
+
+    pud = (lpae_t *)to_virt((*pgd) & ~ATTR_MASK_L) + l1_pgt_idx(vaddr);
+    ASSERT((*pud) != L0_INVAL);
+
+    pmd = (lpae_t *)to_virt((*pud) & ~ATTR_MASK_L) + l2_pgt_idx(vaddr);
+    ASSERT((*pmd) != L0_INVAL);
+
+    pte = (lpae_t *)to_virt((*pmd) & ~ATTR_MASK_L) + l3_pgt_idx(vaddr);
+    ASSERT((*pte) != L0_INVAL);
+
+    return pte;
+}
+
+int unmap_frames(unsigned long va, unsigned long num_frames)
+{
+    lpae_t *pte;
+
+    ASSERT(!((unsigned long)va & ~PAGE_MASK));
+
+    while (num_frames) {
+        pte = get_ptep(va);
+       *pte = (lpae_t)0;
+
+        flush_tlb_page(va);
+
+        va += PAGE_SIZE;
+        num_frames--;
+    }
+    return 0;
+}
+
 #else
 void arch_mm_preinit(void *dtb_pointer)
 {
diff --git a/include/arm/arch_mm.h b/include/arm/arch_mm.h
index 86d0b3b..e1aed26 100644
--- a/include/arm/arch_mm.h
+++ b/include/arm/arch_mm.h
@@ -49,4 +49,8 @@ void arch_mm_preinit(void *dtb_pointer);
 #define map_frames(f, n) (NULL)
 
 void *ioremap(paddr_t addr, unsigned long size);
+
+extern unsigned long mfn_zero;
+#define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, NULL, 
MEM_RO_ATTR)
+
 #endif
diff --git a/include/arm/arm64/os.h b/include/arm/arm64/os.h
index 03712d0..c1a0df3 100644
--- a/include/arm/arm64/os.h
+++ b/include/arm/arm64/os.h
@@ -51,6 +51,22 @@ static inline void local_irq_enable(void)
 #define wmb()           dsb(st) /* Full system memory barrier store */
 #define rmb()           dsb(ld) /* Full system memory barrier load */
 
+/* Flush a page in innershareable doman */
+static inline void flush_tlb_page(unsigned long va)
+{
+    unsigned long xt;
+
+    /* xt[43:0] to save VA[55:12] */
+    xt = va >> 12;
+
+    __asm__ __volatile__(
+        "dsb sy;"
+        "tlbi vale1is, %0;"
+        "dsb sy;"
+        "isb;"
+        ::"r"(xt): "memory");
+}
+
 #endif
 
 /* The Callee-saved registers : x19 ~ x29 */
-- 
2.7.4


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

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