Fix Intel IOMMU write-buffer flushing
This is the cause of the DMA faults and disk corruption that people have been seeing. Some chipsets neglect to report the RWBF "capability" -- the flag which says that we need to flush the chipset write-buffer when changing the DMA page tables, to ensure that the change is visible to the IOMMU. Override that bit on the affected chipsets, and everything is happy again. Thanks to Chris and Bhavesh and others for helping to debug. Signed-off-by: David Woodhouse <David.Woodhouse@intel.com> Tested-by: Chris Wright <chrisw@sous-sol.org> Reviewed-by: Bhavesh Davda <bhavesh@vmware.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
1a88b5364b
commit
ca77fde8e6
|
@ -61,6 +61,8 @@
|
||||||
/* global iommu list, set NULL for ignored DMAR units */
|
/* global iommu list, set NULL for ignored DMAR units */
|
||||||
static struct intel_iommu **g_iommus;
|
static struct intel_iommu **g_iommus;
|
||||||
|
|
||||||
|
static int rwbf_quirk = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 0: Present
|
* 0: Present
|
||||||
* 1-11: Reserved
|
* 1-11: Reserved
|
||||||
|
@ -785,7 +787,7 @@ static void iommu_flush_write_buffer(struct intel_iommu *iommu)
|
||||||
u32 val;
|
u32 val;
|
||||||
unsigned long flag;
|
unsigned long flag;
|
||||||
|
|
||||||
if (!cap_rwbf(iommu->cap))
|
if (!rwbf_quirk && !cap_rwbf(iommu->cap))
|
||||||
return;
|
return;
|
||||||
val = iommu->gcmd | DMA_GCMD_WBF;
|
val = iommu->gcmd | DMA_GCMD_WBF;
|
||||||
|
|
||||||
|
@ -3137,3 +3139,13 @@ static struct iommu_ops intel_iommu_ops = {
|
||||||
.unmap = intel_iommu_unmap_range,
|
.unmap = intel_iommu_unmap_range,
|
||||||
.iova_to_phys = intel_iommu_iova_to_phys,
|
.iova_to_phys = intel_iommu_iova_to_phys,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
/* Mobile 4 Series Chipset neglects to set RWBF capability,
|
||||||
|
but needs it */
|
||||||
|
printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n");
|
||||||
|
rwbf_quirk = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf);
|
||||||
|
|
Loading…
Reference in a new issue