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

[Xen-devel] [PATCH 1 of 2] x86/mm: Split ept_set_entry()



 xen/arch/x86/mm/p2m-ept.c |  60 ++++++++++++++++++++++++++++------------------
 1 files changed, 37 insertions(+), 23 deletions(-)


Split ept_set_entry() such that mapping and unmapping of the page tables and 
ept_sync occurrs outside of it.

Signed-off-by: Aravindh Puthiyaparambil <aravindh@xxxxxxxxxxxx>

diff -r 63eb1343cbdb -r f12cf785738f xen/arch/x86/mm/p2m-ept.c
--- a/xen/arch/x86/mm/p2m-ept.c Wed Apr 25 19:29:53 2012 -0700
+++ b/xen/arch/x86/mm/p2m-ept.c Wed Apr 25 19:29:54 2012 -0700
@@ -272,14 +272,15 @@ static int ept_next_level(struct p2m_dom
 }
 
 /*
- * ept_set_entry() computes 'need_modify_vtd_table' for itself,
+ * __ept_set_entry() computes 'need_modify_vtd_table' for itself,
  * by observing whether any gfn->mfn translations are modified.
  */
 static int
-ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, 
-              unsigned int order, p2m_type_t p2mt, p2m_access_t p2ma)
+__ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn,
+                unsigned int order, p2m_type_t p2mt, p2m_access_t p2ma,
+                ept_entry_t *table, ept_entry_t *old_entry, bool_t *needs_sync)
 {
-    ept_entry_t *table, *ept_entry = NULL;
+    ept_entry_t *ept_entry = NULL;
     unsigned long gfn_remainder = gfn;
     unsigned long offset = 0;
     u32 index;
@@ -288,11 +289,9 @@ ept_set_entry(struct p2m_domain *p2m, un
     int ret = 0;
     bool_t direct_mmio = (p2mt == p2m_mmio_direct);
     uint8_t ipat = 0;
-    int need_modify_vtd_table = 1;
-    int vtd_pte_present = 0;
-    int needs_sync = 1;
+    bool_t need_modify_vtd_table = 1;
+    bool_t vtd_pte_present = 0;
     struct domain *d = p2m->domain;
-    ept_entry_t old_entry = { .epte = 0 };
 
     /*
      * the caller must make sure:
@@ -305,12 +304,6 @@ ept_set_entry(struct p2m_domain *p2m, un
          (order % EPT_TABLE_ORDER) )
         return 0;
 
-    ASSERT((target == 2 && hvm_hap_has_1gb(d)) ||
-           (target == 1 && hvm_hap_has_2mb(d)) ||
-           (target == 0));
-
-    table = map_domain_page(ept_get_asr(d));
-
     for ( i = ept_get_wl(d); i > target; i-- )
     {
         ret = ept_next_level(p2m, 0, &table, &gfn_remainder, i);
@@ -327,7 +320,7 @@ ept_set_entry(struct p2m_domain *p2m, un
 
     ept_entry = table + index;
 
-    /* In case VT-d uses same page table, this flag is needed by VT-d */ 
+    /* In case VT-d uses same page table, this flag is needed by VT-d */
     vtd_pte_present = is_epte_present(ept_entry) ? 1 : 0;
 
     /*
@@ -352,7 +345,7 @@ ept_set_entry(struct p2m_domain *p2m, un
          * the intermediate tables will be freed below after the ept flush
          *
          * Read-then-write is OK because we hold the p2m lock. */
-        old_entry = *ept_entry;
+        old_entry->epte = ept_entry->epte;
 
         if ( mfn_valid(mfn_x(mfn)) || direct_mmio || p2m_is_paged(p2mt) ||
              (p2mt == p2m_ram_paging_in) )
@@ -369,7 +362,7 @@ ept_set_entry(struct p2m_domain *p2m, un
 
             new_entry.mfn = mfn_x(mfn);
 
-            if ( old_entry.mfn == new_entry.mfn )
+            if ( old_entry->mfn == new_entry.mfn )
                 need_modify_vtd_table = 0;
 
             ept_p2m_type_to_flags(&new_entry, p2mt, p2ma);
@@ -435,12 +428,7 @@ ept_set_entry(struct p2m_domain *p2m, un
     /* Success */
     rv = 1;
 
-out:
-    unmap_domain_page(table);
-
-    if ( needs_sync )
-        ept_sync_domain(p2m->domain);
-
+ out:
     if ( rv && iommu_enabled && need_iommu(p2m->domain) && 
need_modify_vtd_table )
     {
         if ( iommu_hap_pt_share )
@@ -473,6 +461,32 @@ out:
         }
     }
 
+    return rv;
+}
+
+static int
+ept_set_entry(struct p2m_domain *p2m, unsigned long gfn, mfn_t mfn, 
+              unsigned int order, p2m_type_t p2mt, p2m_access_t p2ma)
+{
+    ept_entry_t *table;
+    int target = order / EPT_TABLE_ORDER;
+    int rv = 0;
+    bool_t needs_sync = 1;
+    struct domain *d = p2m->domain;
+    ept_entry_t old_entry = { .epte = 0 };
+
+    ASSERT((target == 2 && hvm_hap_has_1gb(d)) ||
+           (target == 1 && hvm_hap_has_2mb(d)) ||
+           (target == 0));
+
+    table = map_domain_page(ept_get_asr(d));
+    rv = __ept_set_entry(p2m, gfn, mfn, order, p2mt, p2ma, table, &old_entry,
+                         &needs_sync);
+    unmap_domain_page(table);
+
+    if ( needs_sync )
+        ept_sync_domain(p2m->domain);
+
     /* Release the old intermediate tables, if any.  This has to be the
        last thing we do, after the ept_sync_domain() and removal
        from the iommu tables, so as to avoid a potential

_______________________________________________
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®.