Messages in this thread Patch in this message | | | Subject | [PATCH] intel-iommu: Fix alloc_coherent for pass-through devices | From | Alex Williamson <> | Date | Wed, 21 Oct 2009 21:41:50 -0600 |
| |
After 19943b0e (intel-iommu: Unify hardware and software passthrough support) hardware pass-through mode devices make use of intel_dma_ops rather than swiotlb_dma_ops. The problem is that intel_alloc_coherent ignores the device coherent_dma_mask when allocating the page since it expects to remap the page and provide the device with an iova within the coherent mask. This breaks when we use pass-through.
The patch below crudely works around the problem, but I hope we can come up with something better without reintroducing the dependency on swiotlb. The device hitting this problem is an HP smart array controller on a Proliant G6 system. It uses a default 32bit coherent DMA mask, and stalls, presumably waiting on control data to change in the wrong address space, when it gets a coherent buffer above 4G. This device also doesn't exactly play nice when using VT-d in anything other than pass-through mode, so switching it into mapped mode is not really an option.
Signed-off-by: Alex Williamson <alex.williamson@hp.com> ---
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index b1e97e6..7a739ac 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2767,7 +2767,11 @@ static void *intel_alloc_coherent(struct device *hwdev, size_t size, size = PAGE_ALIGN(size); order = get_order(size); - flags &= ~(GFP_DMA | GFP_DMA32); + + if (iommu_no_mapping(hwdev)) + flags |= (GFP_DMA | GFP_DMA32); + else + flags &= ~(GFP_DMA | GFP_DMA32); vaddr = (void *)__get_free_pages(flags, order); if (!vaddr)
| |