diff mbox series

[v2,15/55] x86/mm: rewrite virt_to_xen_l1e

Message ID 18d6bbf165484f7e97a03fed849cdca77f2842af.1569833766.git.hongyax@amazon.com (mailing list archive)
State New, archived
Headers show
Series Switch to domheap for Xen PTEs | expand

Commit Message

Xia, Hongyan Sept. 30, 2019, 10:33 a.m. UTC
From: Wei Liu <wei.liu2@citrix.com>

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

Signed-off-by: Wei Liu <wei.liu2@citrix.com>
---
 xen/arch/x86/domain_page.c | 10 ++++++----
 xen/arch/x86/mm.c          | 30 +++++++++++++++++++++++++-----
 2 files changed, 31 insertions(+), 9 deletions(-)
diff mbox series

Patch

diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c
index 4a07cfb18e..24083e9a86 100644
--- a/xen/arch/x86/domain_page.c
+++ b/xen/arch/x86/domain_page.c
@@ -333,21 +333,23 @@  void unmap_domain_page_global(const void *ptr)
 mfn_t domain_page_map_to_mfn(const void *ptr)
 {
     unsigned long va = (unsigned long)ptr;
-    const l1_pgentry_t *pl1e;
+    l1_pgentry_t l1e;
 
     if ( va >= DIRECTMAP_VIRT_START )
         return _mfn(virt_to_mfn(ptr));
 
     if ( va >= VMAP_VIRT_START && va < VMAP_VIRT_END )
     {
-        pl1e = virt_to_xen_l1e(va);
+        l1_pgentry_t *pl1e = virt_to_xen_l1e(va);
         BUG_ON(!pl1e);
+        l1e = *pl1e;
+        UNMAP_XEN_PAGETABLE_NEW(pl1e);
     }
     else
     {
         ASSERT(va >= MAPCACHE_VIRT_START && va < MAPCACHE_VIRT_END);
-        pl1e = &__linear_l1_table[l1_linear_offset(va)];
+        l1e = __linear_l1_table[l1_linear_offset(va)];
     }
 
-    return l1e_get_mfn(*pl1e);
+    return l1e_get_mfn(l1e);
 }
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index ad0d7a0b80..f7fd0e6bad 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -5024,26 +5024,44 @@  l1_pgentry_t *virt_to_xen_l1e(unsigned long v)
     if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
     {
         bool locking = system_state > SYS_STATE_boot;
-        l1_pgentry_t *l1t = alloc_xen_pagetable();
+        l1_pgentry_t *l1t;
+        mfn_t mfn;
 
-        if ( !l1t )
+        mfn = alloc_xen_pagetable_new();
+        if ( mfn_eq(mfn, INVALID_MFN) )
             goto out;
+
+        l1t = map_xen_pagetable_new(mfn);
+
         if ( locking )
             spin_lock(&map_pgdir_lock);
         if ( !(l2e_get_flags(*pl2e) & _PAGE_PRESENT) )
         {
             clear_page(l1t);
-            l2e_write(pl2e, l2e_from_paddr(__pa(l1t), __PAGE_HYPERVISOR));
+            l2e_write(pl2e, l2e_from_mfn(mfn, __PAGE_HYPERVISOR));
+            pl1e = l1t + l1_table_offset(v);
             l1t = NULL;
         }
         if ( locking )
             spin_unlock(&map_pgdir_lock);
+
         if ( l1t )
-            free_xen_pagetable(l1t);
+        {
+            ASSERT(!pl1e);
+            ASSERT(!mfn_eq(mfn, INVALID_MFN));
+            UNMAP_XEN_PAGETABLE_NEW(l1t);
+            free_xen_pagetable_new(mfn);
+        }
     }
 
     BUG_ON(l2e_get_flags(*pl2e) & _PAGE_PSE);
-    pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(v);
+
+    if ( !pl1e )
+    {
+        ASSERT(l2e_get_flags(*pl2e) & _PAGE_PRESENT);
+        pl1e = (l1_pgentry_t *)map_xen_pagetable_new(l2e_get_mfn(*pl2e))
+            + l1_table_offset(v);
+    }
 
  out:
     UNMAP_XEN_PAGETABLE_NEW(pl2e);
@@ -5447,6 +5465,7 @@  int map_pages_to_xen(
                 spin_unlock(&map_pgdir_lock);
         }
     end_of_loop:
+        UNMAP_XEN_PAGETABLE_NEW(pl1e);
         UNMAP_XEN_PAGETABLE_NEW(pl2e);
         UNMAP_XEN_PAGETABLE_NEW(pl3e);
     }
@@ -5456,6 +5475,7 @@  int map_pages_to_xen(
     rc = 0;
 
  out:
+    UNMAP_XEN_PAGETABLE_NEW(pl1e);
     UNMAP_XEN_PAGETABLE_NEW(pl2e);
     UNMAP_XEN_PAGETABLE_NEW(pl3e);
     return rc;