# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1216991039 -3600
# Node ID de80bf7a55cf1993514bea5ed39dbf28ec10503a
# Parent d51dae1c04881e97e79d2939d6295d0d544bcaff
vt-d: add timeout in the infinite loop.
This changeset is back-ported from xen-unstable.
The original description of the changeset is:
vt-d: Fix a bug in addr_to_dma_page_maddr(), and add timeout in
infinite loop
In addr_to_dma_page_maddr(), pte should not be used after
unmap_vtd_domain_page(parent). In addition, timeout is added in some
infinite loops.
Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx>
xen-unstable changeset: 17491:da261c25f160ae3cddea1a4e5d1b045cceb7e03b
xen-unstable date: Tue Apr 22 10:20:05 2008 +0100
Considering Xen 3.2, we have no bug in addr_to_dma_page(); for the
timeout, we still use the jiffies based method.
Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
xen/arch/x86/hvm/vmx/vtd/intel-iommu.c | 19 +++++++++++++++++--
1 files changed, 17 insertions(+), 2 deletions(-)
diff -r d51dae1c0488 -r de80bf7a55cf xen/arch/x86/hvm/vmx/vtd/intel-iommu.c
--- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Fri Jul 25 14:03:36 2008 +0100
+++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c Fri Jul 25 14:03:59 2008 +0100
@@ -609,7 +609,7 @@ void dma_pte_free_pagetable(struct domai
struct dma_pte *pte;
int total = agaw_to_level(hd->agaw);
int level;
- u32 tmp;
+ u64 tmp;
struct page_info *pg = NULL;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
@@ -630,7 +630,10 @@ void dma_pte_free_pagetable(struct domai
{
pg = dma_addr_level_page(domain, tmp, level);
if ( !pg )
- return;
+ {
+ tmp += level_size(level);
+ continue;
+ }
pte = (struct dma_pte *)map_domain_page(page_to_mfn(pg));
pte += address_level_offset(tmp, level);
dma_clear_pte(*pte);
@@ -658,6 +661,7 @@ static int iommu_set_root_entry(struct i
u32 cmd, sts;
struct root_entry *root;
unsigned long flags;
+ unsigned long start_time;
if ( iommu == NULL )
{
@@ -689,11 +693,14 @@ static int iommu_set_root_entry(struct i
dmar_writel(iommu->reg, DMAR_GCMD_REG, cmd);
/* Make sure hardware complete it */
+ start_time = jiffies;
for ( ; ; )
{
sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
if ( sts & DMA_GSTS_RTPS )
break;
+ if ( time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT) )
+ panic("DMAR hardware is malfunctional, please disable IOMMU\n");
cpu_relax();
}
@@ -706,6 +713,7 @@ static int iommu_enable_translation(stru
{
u32 sts;
unsigned long flags;
+ unsigned long start_time;
dprintk(XENLOG_INFO VTDPREFIX,
"iommu_enable_translation: enabling vt-d translation\n");
@@ -713,11 +721,14 @@ static int iommu_enable_translation(stru
iommu->gcmd |= DMA_GCMD_TE;
dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
/* Make sure hardware complete it */
+ start_time = jiffies;
for ( ; ; )
{
sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
if ( sts & DMA_GSTS_TES )
break;
+ if ( time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT) )
+ panic("DMAR hardware is malfunctional, please disable IOMMU\n");
cpu_relax();
}
@@ -731,17 +742,21 @@ int iommu_disable_translation(struct iom
{
u32 sts;
unsigned long flags;
+ unsigned long start_time;
spin_lock_irqsave(&iommu->register_lock, flags);
iommu->gcmd &= ~ DMA_GCMD_TE;
dmar_writel(iommu->reg, DMAR_GCMD_REG, iommu->gcmd);
/* Make sure hardware complete it */
+ start_time = jiffies;
for ( ; ; )
{
sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
if ( !(sts & DMA_GSTS_TES) )
break;
+ if ( time_after(jiffies, start_time + DMAR_OPERATION_TIMEOUT) )
+ panic("DMAR hardware is malfunctional, please disable IOMMU\n");
cpu_relax();
}
spin_unlock_irqrestore(&iommu->register_lock, flags);
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|