]> xenbits.xensource.com Git - xen.git/commitdiff
xen/arm: p2m: Introduce p2m_get_root_pointer and use it in __p2m_lookup
authorJulien Grall <julien.grall@arm.com>
Thu, 15 Sep 2016 11:28:27 +0000 (12:28 +0100)
committerStefano Stabellini <sstabellini@kernel.org>
Wed, 28 Sep 2016 01:13:58 +0000 (18:13 -0700)
Mapping the root table is always done the same way. To avoid duplicating
the code in a later patch, move the code in a separate helper.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Tested-by: Tamas K Lengyel <tamas@tklengyel.com>
xen/arch/arm/p2m.c
xen/include/asm-arm/page.h

index 6a100c81df25a5d317aa6dce0856749e197697a8..679aedba6e63f4a778ab42e2189585d7b37fa52e 100644 (file)
@@ -36,6 +36,8 @@ static const paddr_t level_masks[] =
     { ZEROETH_MASK, FIRST_MASK, SECOND_MASK, THIRD_MASK };
 static const uint8_t level_shifts[] =
     { ZEROETH_SHIFT, FIRST_SHIFT, SECOND_SHIFT, THIRD_SHIFT };
+static const uint8_t level_orders[] =
+    { ZEROETH_ORDER, FIRST_ORDER, SECOND_ORDER, THIRD_ORDER };
 
 static bool_t p2m_valid(lpae_t pte)
 {
@@ -203,6 +205,37 @@ static void p2m_flush_tlb_sync(struct p2m_domain *p2m)
     p2m->need_flush = false;
 }
 
+/*
+ * Find and map the root page table. The caller is responsible for
+ * unmapping the table.
+ *
+ * The function will return NULL if the offset of the root table is
+ * invalid.
+ */
+static lpae_t *p2m_get_root_pointer(struct p2m_domain *p2m,
+                                    gfn_t gfn)
+{
+    unsigned int root_table;
+
+    if ( P2M_ROOT_PAGES == 1 )
+        return __map_domain_page(p2m->root);
+
+    /*
+     * Concatenated root-level tables. The table number will be the
+     * offset at the previous level. It is not possible to
+     * concatenate a level-0 root.
+     */
+    ASSERT(P2M_ROOT_LEVEL > 0);
+
+    root_table = gfn_x(gfn) >> (level_orders[P2M_ROOT_LEVEL - 1]);
+    root_table &= LPAE_ENTRY_MASK;
+
+    if ( root_table >= P2M_ROOT_PAGES )
+        return NULL;
+
+    return __map_domain_page(p2m->root + root_table);
+}
+
 /*
  * Lookup the MFN corresponding to a domain's GFN.
  *
@@ -226,7 +259,7 @@ static mfn_t __p2m_lookup(struct domain *d, gfn_t gfn, p2m_type_t *t)
     mfn_t mfn = INVALID_MFN;
     paddr_t mask = 0;
     p2m_type_t _t;
-    unsigned int level, root_table;
+    unsigned int level;
 
     ASSERT(p2m_is_locked(p2m));
     BUILD_BUG_ON(THIRD_MASK != PAGE_MASK);
@@ -236,22 +269,9 @@ static mfn_t __p2m_lookup(struct domain *d, gfn_t gfn, p2m_type_t *t)
 
     *t = p2m_invalid;
 
-    if ( P2M_ROOT_PAGES > 1 )
-    {
-        /*
-         * Concatenated root-level tables. The table number will be
-         * the offset at the previous level. It is not possible to
-         * concatenate a level-0 root.
-         */
-        ASSERT(P2M_ROOT_LEVEL > 0);
-        root_table = offsets[P2M_ROOT_LEVEL - 1];
-        if ( root_table >= P2M_ROOT_PAGES )
-            goto err;
-    }
-    else
-        root_table = 0;
-
-    map = __map_domain_page(p2m->root + root_table);
+    map = p2m_get_root_pointer(p2m, gfn);
+    if ( !map )
+        return INVALID_MFN;
 
     ASSERT(P2M_ROOT_LEVEL < 4);
 
@@ -286,7 +306,6 @@ static mfn_t __p2m_lookup(struct domain *d, gfn_t gfn, p2m_type_t *t)
         *t = pte.p2m.type;
     }
 
-err:
     return mfn;
 }
 
index 015ed6307a7b704a790882f3d160849111b42c4c..f25d221cdb5cba0d19ea42d769f910f137a033af 100644 (file)
@@ -468,15 +468,19 @@ static inline int gva_to_ipa(vaddr_t va, paddr_t *paddr, unsigned int flags)
 #define LPAE_ENTRY_MASK (LPAE_ENTRIES - 1)
 
 #define THIRD_SHIFT    (PAGE_SHIFT)
+#define THIRD_ORDER    (THIRD_SHIFT - PAGE_SHIFT)
 #define THIRD_SIZE     ((paddr_t)1 << THIRD_SHIFT)
 #define THIRD_MASK     (~(THIRD_SIZE - 1))
 #define SECOND_SHIFT   (THIRD_SHIFT + LPAE_SHIFT)
+#define SECOND_ORDER   (SECOND_SHIFT - PAGE_SHIFT)
 #define SECOND_SIZE    ((paddr_t)1 << SECOND_SHIFT)
 #define SECOND_MASK    (~(SECOND_SIZE - 1))
 #define FIRST_SHIFT    (SECOND_SHIFT + LPAE_SHIFT)
+#define FIRST_ORDER    (FIRST_SHIFT - PAGE_SHIFT)
 #define FIRST_SIZE     ((paddr_t)1 << FIRST_SHIFT)
 #define FIRST_MASK     (~(FIRST_SIZE - 1))
 #define ZEROETH_SHIFT  (FIRST_SHIFT + LPAE_SHIFT)
+#define ZEROETH_ORDER  (ZEROETH_SHIFT - PAGE_SHIFT)
 #define ZEROETH_SIZE   ((paddr_t)1 << ZEROETH_SHIFT)
 #define ZEROETH_MASK   (~(ZEROETH_SIZE - 1))