x86 EPT: Only flush EPT TLB if the previous entry was valid
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 26 May 2010 07:08:46 +0000 (08:08 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 26 May 2010 07:08:46 +0000 (08:08 +0100)
Original patch from George Dunlap <george.dunlap@eu.citrix.com>
Signed-off-by: Tim Deegan <Tim.Deegan@citrix.com>
xen/arch/x86/mm/hap/p2m-ept.c

index dbdbd7aaeeaadc76dbb04bccbe154aca599c4aee..798f4cceddbc42924c50adeb6973700e3a846e2f 100644 (file)
@@ -242,6 +242,7 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
     int direct_mmio = (p2mt == p2m_mmio_direct);
     uint8_t ipat = 0;
     int need_modify_vtd_table = 1;
+    int needs_sync = 1;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
 
     if (  order != 0 )
@@ -276,6 +277,11 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
     if ( i == walk_level )
     {
         /* We reached the level we're looking for */
+
+        /* No need to flush if the old entry wasn't valid */
+        if ( !(ept_entry->epte & 7) )
+            needs_sync = 0;
+
         if ( mfn_valid(mfn_x(mfn)) || direct_mmio || p2m_is_paged(p2mt) ||
              (p2mt == p2m_ram_paging_in_start) )
         {
@@ -336,7 +342,8 @@ ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
 out:
     unmap_domain_page(table);
 
-    ept_sync_domain(d);
+    if ( needs_sync )
+        ept_sync_domain(d);
 
     /* Now the p2m table is not shared with vt-d page table */
     if ( rv && iommu_enabled && need_iommu(d) && need_modify_vtd_table )