From c095f1cb08936ad2f19dd44550ffcd741f88e310 Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Wed, 7 Nov 2007 09:13:48 +0000 Subject: [PATCH] vt-d: Disable PMR on every vt-d engine. Signed-off-by Gang Wei (Jimmy) Signed-off-by Kevin Tian --- xen/arch/x86/hvm/vmx/vtd/intel-iommu.c | 9 ++++----- xen/arch/x86/hvm/vmx/vtd/utils.c | 15 ++++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c index a6676a439f..ae9a9f26db 100644 --- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c +++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c @@ -688,6 +688,9 @@ static int iommu_enable_translation(struct iommu *iommu) break; cpu_relax(); } + + /* Disable PMRs when VT-d engine takes effect per spec definition */ + disable_pmr(iommu); spin_unlock_irqrestore(&iommu->register_lock, flags); return 0; } @@ -1767,7 +1770,7 @@ int iommu_setup(void) struct hvm_iommu *hd = domain_hvm_iommu(dom0); struct acpi_drhd_unit *drhd; struct iommu *iommu; - unsigned long i, status; + unsigned long i; if ( !vtd_enabled ) return 0; @@ -1797,10 +1800,6 @@ 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: diff --git a/xen/arch/x86/hvm/vmx/vtd/utils.c b/xen/arch/x86/hvm/vmx/vtd/utils.c index 66b3ce18c8..1ef25d4e98 100644 --- a/xen/arch/x86/hvm/vmx/vtd/utils.c +++ b/xen/arch/x86/hvm/vmx/vtd/utils.c @@ -67,25 +67,30 @@ int vtd_hw_check(void) /* Disable vt-d protected memory registers. */ void disable_pmr(struct iommu *iommu) { - unsigned long start_time, status; + unsigned long start_time; unsigned int val; val = dmar_readl(iommu->reg, DMAR_PMEN_REG); + if ( !(val & DMA_PMEN_PRS) ) + return; + dmar_writel(iommu->reg, DMAR_PMEN_REG, val & ~DMA_PMEN_EPM); start_time = jiffies; for ( ; ; ) { - status = dmar_readl(iommu->reg, DMAR_PMEN_REG); - if ( (status & DMA_PMEN_PRS) == 0 ) + val = dmar_readl(iommu->reg, DMAR_PMEN_REG); + if ( (val & DMA_PMEN_PRS) == 0 ) break; + if ( time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT) ) - panic("Cannot set QIE field for queue invalidation\n"); + panic("Disable PMRs timeout\n"); + cpu_relax(); } dprintk(XENLOG_INFO VTDPREFIX, - "disabled protected memory registers\n"); + "Disabled protected memory registers\n"); } #if defined(__x86_64__) -- 2.30.2