Skip to content

Commit e8bb910

Browse files
Alex WilliamsonDavid Woodhouse
authored andcommitted
intel-iommu: Obey coherent_dma_mask for alloc_coherent on passthrough
The model for IOMMU passthrough is that decent devices that can cope with DMA to all of memory get passthrough; crappy devices with a limited dma_mask don't -- they get to use the IOMMU anyway. This is done on the basis that IOMMU passthrough is usually wanted for performance reasons, and it's only the decent PCI devices that you really care about performance for, while the crappy 32-bit ones like your USB controller can just use the IOMMU and you won't really care. Unfortunately, the check for this was only looking at dev->dma_mask, not at dev->coherent_dma_mask. And some devices have a 32-bit coherent_dma_mask even though they have a full 64-bit dma_mask. Even more unfortunately, fixing that simple oversight would upset certain broken HP devices. Not only do they have a 32-bit coherent_dma_mask, but they also have a tendency to do stray DMA to unmapped addresses. And then they die when they take the DMA fault they so richly deserve. So if we do the 'correct' fix, it'll mean that affected users have to disable IOMMU support completely on "a large percentage of servers from a major vendor." Personally, I have little sympathy -- given that this is the _same_ 'major vendor' who is shipping machines which claim to have IOMMU support but have obviously never _once_ booted a VT-d capable OS to do any form of QA. But strictly speaking, it _would_ be a regression even though it only ever worked by fluke. For 2.6.33, we'll come up with a quirk which gives swiotlb support for this particular device, and other devices with an inadequate coherent_dma_mask will just get normal IOMMU mapping. The simplest fix for 2.6.32, though, is just to jump through some hoops to try to allocate coherent DMA memory for such devices in a place that they can reach. We'd use dma_generic_alloc_coherent() for this if it existed on IA64. Signed-off-by: Alex Williamson <alex.williamson@hp.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
1 parent 86cf898 commit e8bb910

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

drivers/pci/intel-iommu.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2767,7 +2767,15 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size,
27672767

27682768
size = PAGE_ALIGN(size);
27692769
order = get_order(size);
2770-
flags &= ~(GFP_DMA | GFP_DMA32);
2770+
2771+
if (!iommu_no_mapping(hwdev))
2772+
flags &= ~(GFP_DMA | GFP_DMA32);
2773+
else if (hwdev->coherent_dma_mask < dma_get_required_mask(hwdev)) {
2774+
if (hwdev->coherent_dma_mask < DMA_BIT_MASK(32))
2775+
flags |= GFP_DMA;
2776+
else
2777+
flags |= GFP_DMA32;
2778+
}
27712779

27722780
vaddr = (void *)__get_free_pages(flags, order);
27732781
if (!vaddr)

0 commit comments

Comments
 (0)