# HG changeset patch
# User Keir Fraser <keir@xxxxxxxxxxxxx>
# Date 1192261446 -3600
# Node ID a76f3f7ddca06e5bf33b31028d475f608661bbf7
# Parent 22175cd36a10a418d62328a87ad16dc41213b04e
vt-d: disable protected memory registers after vt-d is enabled.
Signed-off-by: Allen Kay <allen.m.kay@xxxxxxxxx>
---
xen/arch/x86/hvm/vmx/vtd/dmar.h | 7 +++++++
xen/arch/x86/hvm/vmx/vtd/intel-iommu.c | 13 +++++--------
xen/arch/x86/hvm/vmx/vtd/utils.c | 20 ++++++++++++++++++++
xen/include/asm-x86/hvm/vmx/intel-iommu.h | 4 ++++
4 files changed, 36 insertions(+), 8 deletions(-)
diff -r 22175cd36a10 -r a76f3f7ddca0 xen/arch/x86/hvm/vmx/vtd/dmar.h
--- a/xen/arch/x86/hvm/vmx/vtd/dmar.h Fri Oct 12 15:37:13 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/dmar.h Sat Oct 13 08:44:06 2007 +0100
@@ -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_
diff -r 22175cd36a10 -r a76f3f7ddca0 xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Fri Oct 12 15:37:13 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Sat Oct 13 08:44:06 2007 +0100
@@ -40,13 +40,6 @@ extern void print_vtd_entries(struct dom
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;
@@ -1803,6 +1796,10 @@ int iommu_setup(void)
setup_dom0_rmrr();
if ( enable_vtd_translation() )
goto error;
+
+ status = dmar_readl(iommu->reg, DMAR_PMEN_REG);
+ if (status & DMA_PMEN_PRS)
+ disable_pmr(iommu);
return 0;
diff -r 22175cd36a10 -r a76f3f7ddca0 xen/arch/x86/hvm/vmx/vtd/utils.c
--- a/xen/arch/x86/hvm/vmx/vtd/utils.c Fri Oct 12 15:37:13 2007 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/utils.c Sat Oct 13 08:44:06 2007 +0100
@@ -62,6 +62,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__)
diff -r 22175cd36a10 -r a76f3f7ddca0 xen/include/asm-x86/hvm/vmx/intel-iommu.h
--- a/xen/include/asm-x86/hvm/vmx/intel-iommu.h Fri Oct 12 15:37:13 2007 +0100
+++ b/xen/include/asm-x86/hvm/vmx/intel-iommu.h Sat Oct 13 08:44:06 2007 +0100
@@ -145,6 +145,10 @@
#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)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|