IOMMU: only try to share IOMMU and HAP tables for domains with P2M.
authorTim Deegan <tim@xen.org>
Tue, 23 Aug 2011 09:43:25 +0000 (10:43 +0100)
committerTim Deegan <tim@xen.org>
Tue, 23 Aug 2011 09:43:25 +0000 (10:43 +0100)
This makes the check more precise, and brings VTd in line with AMD code.

Signed-off-by: Tim Deegan <tim@xen.org>
xen/drivers/passthrough/amd/iommu_map.c
xen/drivers/passthrough/amd/pci_amd_iommu.c
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/vtd/iommu.c
xen/include/xen/iommu.h

index 9effc61c8fa2324d8ae3777520fa6ef3dea54d91..6a8619c0efaa7d14adaa214b9288ef322ddfbd37 100644 (file)
@@ -758,7 +758,7 @@ int amd_iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn,
 
     BUG_ON( !hd->root_table );
 
-    if ( iommu_hap_pt_share && is_hvm_domain(d) )
+    if ( iommu_use_hap_pt(d) )
         return 0;
 
     memset(pt_mfn, 0, sizeof(pt_mfn));
@@ -835,7 +835,7 @@ int amd_iommu_unmap_page(struct domain *d, unsigned long gfn)
 
     BUG_ON( !hd->root_table );
 
-    if ( iommu_hap_pt_share && is_hvm_domain(d) )
+    if ( iommu_use_hap_pt(d) )
         return 0;
 
     memset(pt_mfn, 0, sizeof(pt_mfn));
@@ -935,7 +935,7 @@ void amd_iommu_share_p2m(struct domain *d)
 
     ASSERT( is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled );
 
-    if ( !iommu_hap_pt_share )
+    if ( !iommu_use_hap_pt(d) )
         return;
 
     pgd_mfn = pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)));
index 6af9477076ed7479cb18df8666ef7953a433053e..555ee0506d1d16d6ffe366efc0725fb7a9d209cd 100644 (file)
@@ -21,6 +21,7 @@
 #include <xen/sched.h>
 #include <xen/pci.h>
 #include <xen/pci_regs.h>
+#include <xen/paging.h>
 #include <asm/hvm/iommu.h>
 #include <asm/amd-iommu.h>
 #include <asm/hvm/svm/amd-iommu-proto.h>
@@ -388,7 +389,7 @@ static void deallocate_iommu_page_tables(struct domain *d)
 {
     struct hvm_iommu *hd  = domain_hvm_iommu(d);
 
-    if ( iommu_hap_pt_share )
+    if ( iommu_use_hap_pt(d) )
         return;
 
     spin_lock(&hd->mapping_lock);
index 83ac344871f8ea3816e511b41c7aca6055d3180e..be5cb246bfb2d6c590997154410e2ad41d36d4ca 100644 (file)
@@ -180,7 +180,7 @@ int assign_device(struct domain *d, u8 bus, u8 devfn)
     if ( has_arch_pdevs(d) && !need_iommu(d) )
     {
         d->need_iommu = 1;
-        if ( !iommu_hap_pt_share )
+        if ( !iommu_use_hap_pt(d) )
             rc = iommu_populate_page_table(d);
         goto done;
     }
index 3bcfe59602a254776cf5c8e22e70a290e83d0091..c9557d12d5891da07ff144613801fa64537ffa36 100644 (file)
@@ -1613,7 +1613,7 @@ void iommu_domain_teardown(struct domain *d)
     if ( list_empty(&acpi_drhd_units) )
         return;
 
-    if ( iommu_hap_pt_share )
+    if ( iommu_use_hap_pt(d) )
         return;
 
     spin_lock(&hd->mapping_lock);
@@ -1635,7 +1635,7 @@ static int intel_iommu_map_page(
     int iommu_domid;
 
     /* Do nothing if VT-d shares EPT page table */
-    if ( iommu_hap_pt_share )
+    if ( iommu_use_hap_pt(d) )
         return 0;
 
     /* do nothing if dom0 and iommu supports pass thru */
@@ -1760,7 +1760,7 @@ void iommu_set_pgd(struct domain *d)
 
     ASSERT( is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled );
 
-    if ( !iommu_hap_pt_share )
+    if ( !iommu_use_hap_pt(d) )
         return;
 
     pgd_mfn = pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)));
index a8a60f9ae3cbb3ae6a176ed9f320284856520db5..ade8690417b9331a66657ed92e60f83616d513df 100644 (file)
@@ -34,6 +34,9 @@ extern bool_t iommu_hap_pt_share;
 extern bool_t iommu_debug;
 extern bool_t amd_iommu_perdev_intremap;
 
+/* Does this domain have a P2M table we can use as its IOMMU pagetable? */
+#define iommu_use_hap_pt(d) (paging_mode_hap(d) && iommu_hap_pt_share)
+
 extern struct rangeset *mmio_ro_ranges;
 
 #define domain_hvm_iommu(d)     (&d->arch.hvm_domain.hvm_iommu)