All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][VTD] bug fix for EPT/VT-d table sharing
@ 2011-01-05 19:36 Kay, Allen M
  2011-01-06  8:43 ` Jan Beulich
  0 siblings, 1 reply; 9+ messages in thread
From: Kay, Allen M @ 2011-01-05 19:36 UTC (permalink / raw)
  To: xen-devel@lists.xensource.com; +Cc: Keir Fraser, Tim Deegan

[-- Attachment #1: Type: text/plain, Size: 439 bytes --]

This patch makes following changes: 1) Moves EPT/VT-d sharing initialization back to when it is actually needed to make sure vmx_ept_vpid_cap has been initialized.  2) added page order parameter to iommu_pte_flush() to tell VT-d what size of page to flush.  3) added hap_2mb flag to ease performance studies between base 4KB EPT size and when 2MB and 1GB page size support are enabled.

Signed-off-by: Allen Kay <allen.m.kay@intel.com>

[-- Attachment #2: share0105.patch --]
[-- Type: application/octet-stream, Size: 7017 bytes --]

diff -r 39194f457534 xen/arch/x86/mm/hap/p2m-ept.c
--- a/xen/arch/x86/mm/hap/p2m-ept.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/xen/arch/x86/mm/hap/p2m-ept.c	Thu Dec 23 05:51:20 2010 -0800
@@ -413,7 +413,7 @@
     if ( rv && iommu_enabled && need_iommu(p2m->domain) && need_modify_vtd_table )
     {
         if ( iommu_hap_pt_share )
-            iommu_pte_flush(d, gfn, (u64*)ept_entry, vtd_pte_present);
+            iommu_pte_flush(d, gfn, (u64*)ept_entry, order, vtd_pte_present);
         else
         {
             if ( p2mt == p2m_ram_rw )
diff -r 39194f457534 xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/xen/arch/x86/mm/p2m.c	Thu Dec 23 05:51:20 2010 -0800
@@ -43,6 +43,9 @@
 static bool_t __read_mostly opt_hap_1gb = 1;
 boolean_param("hap_1gb", opt_hap_1gb);
 
+static bool_t __read_mostly opt_hap_2mb = 1;
+boolean_param("hap_2mb", opt_hap_2mb);
+
 /* Printouts */
 #define P2M_PRINTK(_f, _a...)                                \
     debugtrace_printk("p2m: %s(): " _f, __func__, ##_a)
@@ -1772,7 +1775,7 @@
             order = ( (((gfn | mfn_x(mfn) | todo) & ((1ul << 18) - 1)) == 0) &&
                       hvm_hap_has_1gb(d) && opt_hap_1gb ) ? 18 :
                       ((((gfn | mfn_x(mfn) | todo) & ((1ul << 9) - 1)) == 0) &&
-                      hvm_hap_has_2mb(d)) ? 9 : 0;
+                      hvm_hap_has_2mb(d) && opt_hap_2mb) ? 9 : 0;
         else
             order = 0;
 
diff -r 39194f457534 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c	Wed Jan 05 09:57:15 2011 +0000
+++ b/xen/drivers/passthrough/vtd/iommu.c	Thu Dec 23 05:51:20 2010 -0800
@@ -535,7 +535,7 @@
 
 static int inline iommu_flush_iotlb_psi(
     struct iommu *iommu, u16 did, u64 addr, unsigned int pages,
-    int flush_non_present_entry, int flush_dev_iotlb)
+    int page_shift, int flush_non_present_entry, int flush_dev_iotlb)
 {
     unsigned int align;
     struct iommu_flush *flush = iommu_get_flush(iommu);
@@ -552,13 +552,14 @@
      * PSI requires page size is 2 ^ x, and the base address is naturally
      * aligned to the size
      */
-    align = get_alignment(addr >> PAGE_SHIFT_4K, pages);
+    align = get_alignment(addr >> page_shift, pages);
+
     /* Fallback to domain selective flush if size is too big */
     if ( align > cap_max_amask_val(iommu->cap) )
         return iommu_flush_iotlb_dsi(iommu, did, flush_non_present_entry, flush_dev_iotlb);
 
-    addr >>= PAGE_SHIFT_4K + align;
-    addr <<= PAGE_SHIFT_4K + align;
+    addr >>= page_shift + align;
+    addr <<= page_shift + align;
 
     /* apply platform specific errata workarounds */
     vtd_ops_preamble_quirk(iommu);
@@ -635,7 +636,8 @@
             if ( iommu_domid == -1 )
                 continue;
             if ( iommu_flush_iotlb_psi(iommu, iommu_domid,
-                                       addr, 1, 0, flush_dev_iotlb) )
+                                       addr, 1, PAGE_SHIFT_4K,
+                                       0, flush_dev_iotlb) )
                 iommu_flush_write_buffer(iommu);
         }
     }
@@ -1711,6 +1713,7 @@
             continue;
         if ( iommu_flush_iotlb_psi(iommu, iommu_domid,
                                    (paddr_t)gfn << PAGE_SHIFT_4K, 1,
+                                   PAGE_SHIFT_4K,
                                    !dma_pte_present(old), flush_dev_iotlb) )
             iommu_flush_write_buffer(iommu);
     }
@@ -1729,13 +1732,15 @@
     return 0;
 }
 
-void iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte, int present)
+void iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte,
+                     u32 order, int present)
 {
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu = NULL;
     struct hvm_iommu *hd = domain_hvm_iommu(d);
     int flush_dev_iotlb;
     int iommu_domid;
+    int page_shift = (order == 0) ? PAGE_SHIFT_4K : PAGE_SHIFT_4K + order;
 
     iommu_flush_cache_entry(pte, sizeof(struct dma_pte));
 
@@ -1750,8 +1755,8 @@
         if ( iommu_domid == -1 )
             continue;
         if ( iommu_flush_iotlb_psi(iommu, iommu_domid,
-                                   (paddr_t)gfn << PAGE_SHIFT_4K, 1,
-                                   !present, flush_dev_iotlb) )
+                                   (paddr_t)gfn << page_shift, 1,
+                                   page_shift, !present, flush_dev_iotlb) )
             iommu_flush_write_buffer(iommu);
     }
 }
@@ -1769,6 +1774,28 @@
     return 1;
 }
 
+static bool_t vtd_ept_share(void)
+{
+    struct acpi_drhd_unit *drhd;
+    struct iommu *iommu;
+    bool_t share = TRUE;
+
+    /* sharept defaults to 0 for now, default to 1 when feature matures */
+    if ( !sharept )
+        share = FALSE;
+
+    /*
+     * Determine whether EPT and VT-d page tables can be shared or not.
+     */
+    for_each_drhd_unit ( drhd )
+    {
+        iommu = drhd->iommu;
+        if ( !vtd_ept_page_compatible(drhd->iommu) )
+            share = FALSE;
+    }
+    return share;
+}
+
 /*
  * set VT-d page table directory to EPT table if allowed
  */
@@ -1779,11 +1806,13 @@
 
     ASSERT( is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled );
 
-    if ( !iommu_hap_pt_share )
-        return;
-
+    iommu_hap_pt_share = vtd_ept_share();
     pgd_mfn = pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)));
     hd->pgd_maddr = pagetable_get_paddr(pagetable_from_mfn(pgd_mfn));
+
+    dprintk(XENLOG_INFO VTDPREFIX,
+            "VT-d page table %s with EPT table\n",
+            iommu_hap_pt_share ? "shares" : "not sharing");
 }
 
 static int domain_rmrr_mapped(struct domain *d,
@@ -2036,27 +2065,6 @@
         }
     }
     iommu_flush_all();
-
-    /*
-     * Determine whether EPT and VT-d page tables can be shared or not.
-     */
-    iommu_hap_pt_share = TRUE;
-    for_each_drhd_unit ( drhd )
-    {
-        iommu = drhd->iommu;
-        if ( (drhd->iommu->nr_pt_levels != VTD_PAGE_TABLE_LEVEL_4) ||
-              !vtd_ept_page_compatible(drhd->iommu) )
-            iommu_hap_pt_share = FALSE;
-    }
-
-    /* keep boot flag sharept as safe fallback. remove after feature matures */
-    if ( !sharept )
-        iommu_hap_pt_share = FALSE;
-
-    dprintk(XENLOG_INFO VTDPREFIX,
-            "VT-d page table %sshared with EPT table\n",
-            iommu_hap_pt_share ? "" : "not ");
-
     return 0;
 }
 
diff -r 39194f457534 xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h	Wed Jan 05 09:57:15 2011 +0000
+++ b/xen/include/xen/iommu.h	Thu Dec 23 05:51:20 2010 -0800
@@ -85,7 +85,7 @@
 int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn,
                    unsigned int flags);
 int iommu_unmap_page(struct domain *d, unsigned long gfn);
-void iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte, int present);
+void iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte, u32 order, int present);
 void iommu_set_pgd(struct domain *d);
 void iommu_domain_teardown(struct domain *d);
 int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq);

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2011-01-10 10:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-05 19:36 [PATCH][VTD] bug fix for EPT/VT-d table sharing Kay, Allen M
2011-01-06  8:43 ` Jan Beulich
2011-01-07  2:49   ` Kay, Allen M
2011-01-07  8:25     ` Jan Beulich
2011-01-07 18:55       ` Kay, Allen M
2011-01-10  8:25         ` Jan Beulich
2011-01-10  8:38         ` Keir Fraser
2011-01-10  9:52         ` Olaf Hering
2011-01-10 10:32           ` Keir Fraser

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.