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

[Xen-devel] [RFC v01 3/3] arm: omap: cleanup iopte allocations



Each allocation for iopte requires 4Kb memory.
All previous allocations from previous MMU reconfiguration
must be cleaned before new reconfigureation cycle.

Change-Id: I6db69a400cdba1170b43d9dc68d0817db77cbf9c
Signed-off-by: Andrii Tseglytskyi <andrii.tseglytskyi@xxxxxxxxxxxxxxx>
---
 xen/arch/arm/omap_iommu.c |   35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/xen/arch/arm/omap_iommu.c b/xen/arch/arm/omap_iommu.c
index 7ec03a2..a5ad3ac 100644
--- a/xen/arch/arm/omap_iommu.c
+++ b/xen/arch/arm/omap_iommu.c
@@ -93,12 +93,18 @@
 #define iopte_is_large(x)      (((x) & 3) == IOPTE_LARGE)
 #define iopte_offset(x)                ((x) & IOPTE_SMALL_MASK)
 
+struct mmu_alloc_node {
+       u32                                     *vptr;
+       struct list_head        node;
+};
+
 struct mmu_info {
        const char                      *name;
        paddr_t                         mem_start;
        u32                                     mem_size;
        u32                                     *pagetable;
        void __iomem            *mem_map;
+       struct list_head        alloc_list;
 };
 
 static struct mmu_info omap_ipu_mmu = {
@@ -222,8 +228,15 @@ static u32 mmu_translate_pgentry(struct domain *dom, u32 
iopgd, u32 da, u32 mask
 static u32 mmu_iopte_alloc(struct mmu_info *mmu, struct domain *dom, u32 
iopgd, u32 sect_num)
 {
        u32 *iopte = NULL;
+       struct mmu_alloc_node *alloc_node;
        u32 i;
 
+       alloc_node = xzalloc_bytes(sizeof(struct mmu_alloc_node));
+       if (!alloc_node) {
+               printk("%s Fail to alloc vptr node\n", mmu->name);
+               return 0;
+       }
+
        iopte = xzalloc_bytes(PAGE_SIZE);
        if (!iopte) {
                printk("%s Fail to alloc 2nd level table\n", mmu->name);
@@ -238,10 +251,27 @@ static u32 mmu_iopte_alloc(struct mmu_info *mmu, struct 
domain *dom, u32 iopgd,
                iopte[i] = vaddr | IOPTE_SMALL;
        }
 
+       /* store pointer for following cleanup */
+       alloc_node->vptr = iopte;
+       list_add(&alloc_node->node, &mmu->alloc_list);
+
        flush_xen_dcache_va_range(iopte, PAGE_SIZE);
        return __pa(iopte) | IOPGD_TABLE;
 }
 
+static void mmu_cleanup_pagetable(struct mmu_info *mmu)
+{
+       struct mmu_alloc_node *mmu_alloc, *tmp;
+
+       ASSERT(mmu);
+
+       list_for_each_entry_safe(mmu_alloc, tmp, &mmu->alloc_list, node) {
+               xfree(mmu_alloc->vptr);
+               list_del(&mmu_alloc->node);
+               xfree(mmu_alloc);
+       }
+}
+
 /*
  * on boot table is empty
  */
@@ -254,6 +284,9 @@ static int mmu_translate_pagetable(struct domain *dom, 
struct mmu_info *mmu)
        ASSERT(dom);
        ASSERT(mmu);
 
+       /* free all previous allocations */
+       mmu_cleanup_pagetable(mmu);
+
        /* copy pagetable from  domain to xen */
        res = mmu_copy_pagetable(mmu);
        if (res) {
@@ -432,6 +465,8 @@ static int mmu_init(struct mmu_info *mmu, u32 data)
        printk("%s: %s private pagetable %lu bytes\n",
                   __func__, mmu->name, IOPGD_TABLE_SIZE);
 
+       INIT_LIST_HEAD(&mmu->alloc_list);
+
        return 0;
 }
 
-- 
1.7.9.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®.