diff mbox series

[RFC,14/84] x86/mm: rewrite xen_to_virt_l2e

Message ID 022d5088caa43d0eaf35f55630e0b66987b4fdea.1569489002.git.hongyax@amazon.com (mailing list archive)
State New, archived
Headers show
Series Remove direct map from Xen | expand

Commit Message

Xia, Hongyan Sept. 26, 2019, 9:45 a.m. UTC
From: Wei Liu <wei.liu2@citrix.com>

Rewrite that function to use the new APIs. Modify its callers to unmap
the pointer returned.

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 xen/arch/x86/mm.c | 46 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 37 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 1dcd4289d1..ad0d7a0b80 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4952,6 +4952,10 @@  static l3_pgentry_t *virt_to_xen_l3e(unsigned long v)
     return pl3e;
 }
 
+/*
+ * Given a virtual address, return a pointer to xen's L2 entry. Caller
+ * needs to unmap the pointer.
+ */
 static l2_pgentry_t *virt_to_xen_l2e(unsigned long v)
 {
     l3_pgentry_t *pl3e;
@@ -4964,27 +4968,44 @@  static l2_pgentry_t *virt_to_xen_l2e(unsigned long v)
     if ( !(l3e_get_flags(*pl3e) & _PAGE_PRESENT) )
     {
         bool locking = system_state > SYS_STATE_boot;
-        l2_pgentry_t *l2t = alloc_xen_pagetable();
+        l2_pgentry_t *l2t;
+        mfn_t mfn;
 
-        if ( !l2t )
+        mfn = alloc_xen_pagetable_new();
+        if ( mfn_eq(mfn, INVALID_MFN) )
             goto out;
 
+        l2t = map_xen_pagetable_new(mfn);
+
         if ( locking )
             spin_lock(&map_pgdir_lock);
         if ( !(l3e_get_flags(*pl3e) & _PAGE_PRESENT) )
         {
             clear_page(l2t);
-            l3e_write(pl3e, l3e_from_paddr(__pa(l2t), __PAGE_HYPERVISOR));
+            l3e_write(pl3e, l3e_from_mfn(mfn, __PAGE_HYPERVISOR));
+            pl2e = l2t + l2_table_offset(v);
             l2t = NULL;
         }
         if ( locking )
             spin_unlock(&map_pgdir_lock);
+
         if ( l2t )
-            free_xen_pagetable(l2t);
+        {
+            ASSERT(!pl2e);
+            ASSERT(!mfn_eq(mfn, INVALID_MFN));
+            UNMAP_XEN_PAGETABLE_NEW(l2t);
+            free_xen_pagetable_new(mfn);
+        }
     }
 
     BUG_ON(l3e_get_flags(*pl3e) & _PAGE_PSE);
-    pl2e = l3e_to_l2e(*pl3e) + l2_table_offset(v);
+
+    if ( !pl2e )
+    {
+        ASSERT(l3e_get_flags(*pl3e) & _PAGE_PRESENT);
+        pl2e = (l2_pgentry_t *)map_xen_pagetable_new(l3e_get_mfn(*pl3e))
+            + l2_table_offset(v);
+    }
 
  out:
     UNMAP_XEN_PAGETABLE_NEW(pl3e);
@@ -4994,10 +5015,11 @@  static l2_pgentry_t *virt_to_xen_l2e(unsigned long v)
 l1_pgentry_t *virt_to_xen_l1e(unsigned long v)
 {
     l2_pgentry_t *pl2e;
+    l1_pgentry_t *pl1e = NULL;
 
     pl2e = virt_to_xen_l2e(v);
     if ( !pl2e )
-        return NULL;
+        goto out;
 
     if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
     {
@@ -5005,7 +5027,7 @@  l1_pgentry_t *virt_to_xen_l1e(unsigned long v)
         l1_pgentry_t *l1t = alloc_xen_pagetable();
 
         if ( !l1t )
-            return NULL;
+            goto out;
         if ( locking )
             spin_lock(&map_pgdir_lock);
         if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
@@ -5021,7 +5043,11 @@  l1_pgentry_t *virt_to_xen_l1e(unsigned long v)
     }
 
     BUG_ON(l2e_get_flags(*pl2e) & _PAGE_PSE);
-    return l2e_to_l1e(*pl2e) + l1_table_offset(v);
+    pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(v);
+
+ out:
+    UNMAP_XEN_PAGETABLE_NEW(pl2e);
+    return pl1e;
 }
 
 /* Convert to from superpage-mapping flags for map_pages_to_xen(). */
@@ -5045,7 +5071,7 @@  int map_pages_to_xen(
 {
     bool locking = system_state > SYS_STATE_boot;
     l3_pgentry_t *pl3e = NULL, ol3e;
-    l2_pgentry_t *pl2e, ol2e;
+    l2_pgentry_t *pl2e = NULL, ol2e;
     l1_pgentry_t *pl1e, ol1e;
     unsigned int  i;
     int rc = -ENOMEM;
@@ -5421,6 +5447,7 @@  int map_pages_to_xen(
                 spin_unlock(&map_pgdir_lock);
         }
     end_of_loop:
+        UNMAP_XEN_PAGETABLE_NEW(pl2e);
         UNMAP_XEN_PAGETABLE_NEW(pl3e);
     }
 
@@ -5429,6 +5456,7 @@  int map_pages_to_xen(
     rc = 0;
 
  out:
+    UNMAP_XEN_PAGETABLE_NEW(pl2e);
     UNMAP_XEN_PAGETABLE_NEW(pl3e);
     return rc;
 }