aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-08-06 09:37:01 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-08-06 09:37:01 +0100
commit1aa11cfc4ffabcfca137ed0a0fb6f72d1614660f (patch)
treed96b79f067a5fc6c5897936fd84b14cc419cfd34
parent66e56e754b601d56be639370fdfcae3231a35b2c (diff)
downloadxen-1aa11cfc4ffabcfca137ed0a0fb6f72d1614660f.tar.gz
xen-1aa11cfc4ffabcfca137ed0a0fb6f72d1614660f.tar.bz2
xen-1aa11cfc4ffabcfca137ed0a0fb6f72d1614660f.zip
vtd: cleanups
- Flush iotlb in iommu_page_mapping() after page mapping - Change BUG_ON() to ASSERT() in iommu_flush_iotlb_psi() - Add iommu_flush_write_buffer() if iommu_flush_iotlb_psi() fails in dma_pte_clear_one() - Change panic() message to easily know where panic happens Signed-off-by: Weidong Han <weidong.han@intel.com>
-rw-r--r--xen/drivers/passthrough/vtd/iommu.c50
1 files changed, 35 insertions, 15 deletions
diff --git a/xen/drivers/passthrough/vtd/iommu.c b/xen/drivers/passthrough/vtd/iommu.c
index e573bafd44..1895cb6081 100644
--- a/xen/drivers/passthrough/vtd/iommu.c
+++ b/xen/drivers/passthrough/vtd/iommu.c
@@ -279,8 +279,8 @@ static void iommu_flush_write_buffer(struct iommu *iommu)
if ( !(val & DMA_GSTS_WBFS) )
break;
if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
- panic("DMAR hardware is malfunctional,"
- " please disable IOMMU\n");
+ panic("%s: DMAR hardware is malfunctional,"
+ " please disable IOMMU\n", __func__);
cpu_relax();
}
spin_unlock_irqrestore(&iommu->register_lock, flag);
@@ -340,7 +340,8 @@ static int flush_context_reg(
if ( !(val & DMA_CCMD_ICC) )
break;
if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
- panic("DMAR hardware is malfunctional, please disable IOMMU\n");
+ panic("%s: DMAR hardware is malfunctional,"
+ " please disable IOMMU\n", __func__);
cpu_relax();
}
spin_unlock_irqrestore(&iommu->register_lock, flag);
@@ -437,20 +438,20 @@ static int flush_iotlb_reg(void *_iommu, u16 did,
if ( !(val & DMA_TLB_IVT) )
break;
if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
- panic("DMAR hardware is malfunctional, please disable IOMMU\n");
+ panic("%s: DMAR hardware is malfunctional,"
+ " please disable IOMMU\n", __func__);
cpu_relax();
}
spin_unlock_irqrestore(&iommu->register_lock, flag);
/* check IOTLB invalidation granularity */
if ( DMA_TLB_IAIG(val) == 0 )
- printk(KERN_ERR VTDPREFIX "IOMMU: flush IOTLB failed\n");
+ dprintk(XENLOG_ERR VTDPREFIX, "IOMMU: flush IOTLB failed\n");
-#ifdef VTD_DEBUG
if ( DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type) )
- printk(KERN_ERR VTDPREFIX "IOMMU: tlb flush request %x, actual %x\n",
+ dprintk(XENLOG_INFO VTDPREFIX,
+ "IOMMU: tlb flush request %x, actual %x\n",
(u32)DMA_TLB_IIRG(type), (u32)DMA_TLB_IAIG(val));
-#endif
/* flush context entry will implictly flush write buffer */
return 0;
}
@@ -493,8 +494,8 @@ static int inline iommu_flush_iotlb_psi(
unsigned int align;
struct iommu_flush *flush = iommu_get_flush(iommu);
- BUG_ON(addr & (~PAGE_MASK_4K));
- BUG_ON(pages == 0);
+ ASSERT(!(addr & (~PAGE_MASK_4K)));
+ ASSERT(pages > 0);
/* Fallback to domain selective flush if no PSI support */
if ( !cap_pgsel_inv(iommu->cap) )
@@ -561,8 +562,9 @@ static void dma_pte_clear_one(struct domain *domain, u64 addr)
{
iommu = drhd->iommu;
if ( test_bit(iommu->index, &hd->iommu_bitmap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
- addr, 1, 0);
+ if ( iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
+ addr, 1, 0))
+ iommu_flush_write_buffer(iommu);
}
unmap_vtd_domain_page(page);
@@ -649,7 +651,8 @@ static int iommu_set_root_entry(struct iommu *iommu)
if ( sts & DMA_GSTS_RTPS )
break;
if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
- panic("DMAR hardware is malfunctional, please disable IOMMU\n");
+ panic("%s: DMAR hardware is malfunctional,"
+ " please disable IOMMU\n", __func__);
cpu_relax();
}
@@ -677,7 +680,8 @@ static int iommu_enable_translation(struct iommu *iommu)
if ( sts & DMA_GSTS_TES )
break;
if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
- panic("DMAR hardware is malfunctional, please disable IOMMU\n");
+ panic("%s: DMAR hardware is malfunctional,"
+ " please disable IOMMU\n", __func__);
cpu_relax();
}
@@ -705,7 +709,8 @@ int iommu_disable_translation(struct iommu *iommu)
if ( !(sts & DMA_GSTS_TES) )
break;
if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT )
- panic("DMAR hardware is malfunctional, please disable IOMMU\n");
+ panic("%s: DMAR hardware is malfunctional,"
+ " please disable IOMMU\n", __func__);
cpu_relax();
}
spin_unlock_irqrestore(&iommu->register_lock, flags);
@@ -1512,6 +1517,9 @@ int intel_iommu_unmap_page(struct domain *d, unsigned long gfn)
int iommu_page_mapping(struct domain *domain, paddr_t iova,
paddr_t hpa, size_t size, int prot)
{
+ struct hvm_iommu *hd = domain_hvm_iommu(domain);
+ struct acpi_drhd_unit *drhd;
+ struct iommu *iommu;
u64 start_pfn, end_pfn;
struct dma_pte *page = NULL, *pte = NULL;
int index;
@@ -1539,6 +1547,18 @@ int iommu_page_mapping(struct domain *domain, paddr_t iova,
index++;
}
+ if ( index > 0 )
+ {
+ for_each_drhd_unit ( drhd )
+ {
+ iommu = drhd->iommu;
+ if ( test_bit(iommu->index, &hd->iommu_bitmap) )
+ if ( iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
+ iova, index, 1))
+ iommu_flush_write_buffer(iommu);
+ }
+ }
+
return 0;
}