]> xenbits.xensource.com Git - xen.git/commitdiff
vt-d: disable protected memory registers after vt-d is enabled.
authorKeir Fraser <keir@xensource.com>
Sat, 13 Oct 2007 07:44:06 +0000 (08:44 +0100)
committerKeir Fraser <keir@xensource.com>
Sat, 13 Oct 2007 07:44:06 +0000 (08:44 +0100)
Signed-off-by: Allen Kay <allen.m.kay@intel.com>
xen/arch/x86/hvm/vmx/vtd/dmar.h
xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
xen/arch/x86/hvm/vmx/vtd/utils.c
xen/include/asm-x86/hvm/vmx/intel-iommu.h

index e6cdf62fab72a9f6aefc17eb2a91610c966fbe50..5c90ad118a88cc6019eef1a9532323986d8ded53 100644 (file)
@@ -87,6 +87,13 @@ struct acpi_ioapic_unit {
     }ioapic;
 };
 
+#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
+#define time_after(a,b)         \
+        (typecheck(unsigned long, a) && \
+         typecheck(unsigned long, b) && \
+         ((long)(b) - (long)(a) < 0))
+
 int vtd_hw_check(void);
+void disable_pmr(struct iommu *iommu);
 
 #endif // _DMAR_H_
index 85e3786aac3f8a1961c4cbb0d1e921c317b0ef57..f8e3b09d6837aac60754aa27439484341481febb 100644 (file)
@@ -40,13 +40,6 @@ extern void print_iommu_regs(struct acpi_drhd_unit *drhd);
 extern void print_vtd_entries(struct domain *d, int bus, int devfn,
                               unsigned long gmfn);
 
-#define DMAR_OPERATION_TIMEOUT (HZ*60) /* 1m */
-
-#define time_after(a,b)         \
-        (typecheck(unsigned long, a) && \
-         typecheck(unsigned long, b) && \
-         ((long)(b) - (long)(a) < 0))
-
 unsigned int x86_clflush_size;
 void clflush_cache_range(void *adr, int size)
 {
@@ -1774,7 +1767,7 @@ int iommu_setup(void)
     struct hvm_iommu *hd  = domain_hvm_iommu(dom0);
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
-    unsigned long i;
+    unsigned long i, status;
 
     if ( !vtd_enabled )
         return 0;
@@ -1804,6 +1797,10 @@ int iommu_setup(void)
     if ( enable_vtd_translation() )
         goto error;
 
+    status = dmar_readl(iommu->reg, DMAR_PMEN_REG);
+    if (status & DMA_PMEN_PRS)
+        disable_pmr(iommu);
+
     return 0;
 
  error:
index fa907a544e4b6f98446cd277eaec16e6a968d8f6..57964b2b6e0c1e92edcda042d8e6dec30c6d80c7 100644 (file)
@@ -64,6 +64,26 @@ int vtd_hw_check(void)
     return 0;
 }
 
+/* disable vt-d protected memory registers */
+void disable_pmr(struct iommu *iommu)
+{
+    unsigned long start_time, status;
+
+    gdprintk(XENLOG_INFO VTDPREFIX,
+        "disabling protected memory registers\n");
+
+    dmar_writel(iommu->reg, DMAR_PMEN_REG, 0);
+    start_time = jiffies;
+    while (1) {
+        status = dmar_readl(iommu->reg, DMAR_PMEN_REG);
+        if ( (status & DMA_PMEN_PRS) == 0 )
+            break;
+        if (time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT))
+            panic("Cannot set QIE field for queue invalidation\n");
+        cpu_relax();
+    }
+}
+
 #if defined(__x86_64__)
 void print_iommu_regs(struct acpi_drhd_unit *drhd)
 {
index b8bf433f6a1824f8ea745c31772ff406d902cc64..893cfaa70abca39ef1bc08929d1f6ec172ec23d3 100644 (file)
 #define DMA_GSTS_QIES   (((u64)1) <<26)
 #define DMA_GSTS_IRES   (((u64)1) <<25)
 
+/* PMEN_REG */
+#define DMA_PMEN_EPM   (((u32)1) << 31)
+#define DMA_PMEN_PRS   (((u32)1) << 1)
+
 /* CCMD_REG */
 #define DMA_CCMD_INVL_GRANU_OFFSET  61
 #define DMA_CCMD_ICC (((u64)1) << 63)