[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |