vt-d: Some fixes and cleanup of Intel iommu
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 28 Nov 2007 12:34:11 +0000 (12:34 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 28 Nov 2007 12:34:11 +0000 (12:34 +0000)
This patch modifies domain id in __iommu_flush_context() and
__iommu_flush_iotlb() to be consistent consist with domain id set by
context_set_domain_id(), avoids setting NULL to  address space root
and corrects macro cap_ndoms.

Signed-off-by: Weidong Han <weidong.han@intel.com>
xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
xen/include/asm-x86/hvm/vmx/intel-iommu.h

index 080092be857d1d9992f7126b9cd0565e2de16aca..8cd2098036dac62ebd7b01ee2a6d6ab9aac52dad 100644 (file)
@@ -276,6 +276,9 @@ static int __iommu_flush_context(
     unsigned long flag;
     unsigned long start_time;
 
+    /* Domain id in context is 1 based */
+    did++;
+
     /*
      * In the non-present entry flush case, if hardware doesn't cache
      * non-present entry we do nothing and if hardware cache non-present
@@ -360,6 +363,9 @@ static int __iommu_flush_iotlb(struct iommu *iommu, u16 did,
     unsigned long flag;
     unsigned long start_time;
 
+    /* Domain id in context is 1 based */
+    did++;
+
     /*
      * In the non-present entry flush case, if hardware doesn't cache
      * non-present entry we do nothing and if hardware cache non-present
@@ -1037,6 +1043,18 @@ static int domain_context_mapping_one(
         context_set_translation_type(*context, CONTEXT_TT_PASS_THRU);
     else
     {
+        if ( !hd->pgd )
+        {
+            struct dma_pte *pgd = (struct dma_pte *)alloc_xenheap_page();
+            if ( !pgd )
+            {
+                spin_unlock_irqrestore(&hd->mapping_lock, flags);
+                return -ENOMEM;
+            }
+            memset(pgd, 0, PAGE_SIZE);
+            hd->pgd = pgd;
+        }
         context_set_address_root(*context, virt_to_maddr(hd->pgd));
         context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL);
     }
@@ -1429,7 +1447,7 @@ void iommu_domain_teardown(struct domain *d)
     return_devices_to_dom0(d);
 }
 
-static int domain_context_mapped(struct domain *domain, struct pci_dev *pdev)
+static int domain_context_mapped(struct pci_dev *pdev)
 {
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
@@ -1589,7 +1607,7 @@ static int iommu_prepare_rmrr_dev(
     if ( ret )
         return ret;
 
-    if ( domain_context_mapped(d, pdev) == 0 )
+    if ( domain_context_mapped(pdev) == 0 )
     {
         drhd = acpi_find_matched_drhd_unit(pdev);
         ret = domain_context_mapping(d, drhd->iommu, pdev);
index c97cc3a5e63886765e54181062df6f3a99c3ca76..8fd63ce63ee58c69c3de3343f89c5e6e4bb9e08c 100644 (file)
@@ -89,7 +89,8 @@
 #define cap_plmr(c)        (((c) >> 5) & 1)
 #define cap_rwbf(c)        (((c) >> 4) & 1)
 #define cap_afl(c)        (((c) >> 3) & 1)
-#define cap_ndoms(c)        (2 ^ (4 + 2 * ((c) & 0x7)))
+#define cap_ndoms(c)        (1 << (4 + 2 * ((c) & 0x7)))
+
 /*
  * Extended Capability Register
  */