Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dma-mapping-4.18-3' of git://git.infradead.org/users/hch/dma-mapping

Pull dma-mapping fix from Christoph Hellwig:
"Revert an incorrect dma-mapping commit for 4.18-rc"

* tag 'dma-mapping-4.18-3' of git://git.infradead.org/users/hch/dma-mapping:
Revert "iommu/intel-iommu: Enable CONFIG_DMA_DIRECT_OPS=y and clean up intel_{alloc,free}_coherent()"

+46 -17
-1
drivers/iommu/Kconfig
··· 142 142 config INTEL_IOMMU 143 143 bool "Support for Intel IOMMU using DMA Remapping Devices" 144 144 depends on PCI_MSI && ACPI && (X86 || IA64_GENERIC) 145 - select DMA_DIRECT_OPS 146 145 select IOMMU_API 147 146 select IOMMU_IOVA 148 147 select NEED_DMA_MAP_STATE
+46 -16
drivers/iommu/intel-iommu.c
··· 31 31 #include <linux/pci.h> 32 32 #include <linux/dmar.h> 33 33 #include <linux/dma-mapping.h> 34 - #include <linux/dma-direct.h> 35 34 #include <linux/mempool.h> 36 35 #include <linux/memory.h> 37 36 #include <linux/cpu.h> ··· 3712 3713 dma_addr_t *dma_handle, gfp_t flags, 3713 3714 unsigned long attrs) 3714 3715 { 3715 - void *vaddr; 3716 + struct page *page = NULL; 3717 + int order; 3716 3718 3717 - vaddr = dma_direct_alloc(dev, size, dma_handle, flags, attrs); 3718 - if (iommu_no_mapping(dev) || !vaddr) 3719 - return vaddr; 3719 + size = PAGE_ALIGN(size); 3720 + order = get_order(size); 3720 3721 3721 - *dma_handle = __intel_map_single(dev, virt_to_phys(vaddr), 3722 - PAGE_ALIGN(size), DMA_BIDIRECTIONAL, 3723 - dev->coherent_dma_mask); 3724 - if (!*dma_handle) 3725 - goto out_free_pages; 3726 - return vaddr; 3722 + if (!iommu_no_mapping(dev)) 3723 + flags &= ~(GFP_DMA | GFP_DMA32); 3724 + else if (dev->coherent_dma_mask < dma_get_required_mask(dev)) { 3725 + if (dev->coherent_dma_mask < DMA_BIT_MASK(32)) 3726 + flags |= GFP_DMA; 3727 + else 3728 + flags |= GFP_DMA32; 3729 + } 3727 3730 3728 - out_free_pages: 3729 - dma_direct_free(dev, size, vaddr, *dma_handle, attrs); 3731 + if (gfpflags_allow_blocking(flags)) { 3732 + unsigned int count = size >> PAGE_SHIFT; 3733 + 3734 + page = dma_alloc_from_contiguous(dev, count, order, flags); 3735 + if (page && iommu_no_mapping(dev) && 3736 + page_to_phys(page) + size > dev->coherent_dma_mask) { 3737 + dma_release_from_contiguous(dev, page, count); 3738 + page = NULL; 3739 + } 3740 + } 3741 + 3742 + if (!page) 3743 + page = alloc_pages(flags, order); 3744 + if (!page) 3745 + return NULL; 3746 + memset(page_address(page), 0, size); 3747 + 3748 + *dma_handle = __intel_map_single(dev, page_to_phys(page), size, 3749 + DMA_BIDIRECTIONAL, 3750 + dev->coherent_dma_mask); 3751 + if (*dma_handle) 3752 + return page_address(page); 3753 + if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT)) 3754 + __free_pages(page, order); 3755 + 3730 3756 return NULL; 3731 3757 } 3732 3758 3733 3759 static void intel_free_coherent(struct device *dev, size_t size, void *vaddr, 3734 3760 dma_addr_t dma_handle, unsigned long attrs) 3735 3761 { 3736 - if (!iommu_no_mapping(dev)) 3737 - intel_unmap(dev, dma_handle, PAGE_ALIGN(size)); 3738 - dma_direct_free(dev, size, vaddr, dma_handle, attrs); 3762 + int order; 3763 + struct page *page = virt_to_page(vaddr); 3764 + 3765 + size = PAGE_ALIGN(size); 3766 + order = get_order(size); 3767 + 3768 + intel_unmap(dev, dma_handle, size); 3769 + if (!dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT)) 3770 + __free_pages(page, order); 3739 3771 } 3740 3772 3741 3773 static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist,