diff options
| author | Mark Brown <broonie@kernel.org> | 2026-08-21 13:55:39 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-08-21 13:55:39 +0100 |
| commit | 6def83e89a6f662cd95776a19db4770b5fcb9a94 (patch) | |
| tree | e81a7e18e54c993a0595a0f3a910d81f3a6128cd /drivers | |
| parent | a4a7cdb265854960429cda79b53eb350f32ed17d (diff) | |
| parent | 42311aa29e20fdc0157746143c108b08b268f5cb (diff) | |
| download | linux-next-6def83e89a6f662cd95776a19db4770b5fcb9a94.tar.gz linux-next-6def83e89a6f662cd95776a19db4770b5fcb9a94.zip | |
Merge branch 'dma-mapping-for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/mszyprowski/linux.git
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/iommu/dma-iommu.c | 77 | ||||
| -rw-r--r-- | drivers/xen/swiotlb-xen.c | 8 |
2 files changed, 40 insertions, 45 deletions
diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 9a07eb39336e..58c624513cd4 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -1180,7 +1180,7 @@ static phys_addr_t iommu_dma_map_swiotlb(struct device *dev, phys_addr_t phys, trace_swiotlb_bounced(dev, phys, size); phys = swiotlb_tbl_map_single(dev, phys, size, iova_mask(iovad), dir, - attrs); + &attrs); /* * Untrusted devices should not see padding areas with random leftover @@ -1660,9 +1660,14 @@ void *iommu_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, { bool coherent = dev_is_dma_coherent(dev); int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs); + bool is_alloc_cc_shared = attrs & __DMA_ATTR_ALLOC_CC_SHARED; struct page *page = NULL; void *cpu_addr; + /* Not yet supported */ + if (is_alloc_cc_shared) + return NULL; + gfp |= __GFP_ZERO; if (gfpflags_allow_blocking(gfp) && @@ -1671,13 +1676,16 @@ void *iommu_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, } if (IS_ENABLED(CONFIG_DMA_DIRECT_REMAP) && - !gfpflags_allow_blocking(gfp) && !coherent) + !gfpflags_allow_blocking(gfp) && !coherent) { page = dma_alloc_from_pool(dev, PAGE_ALIGN(size), &cpu_addr, - gfp, NULL); - else + gfp, attrs, NULL); + if (!page) + return NULL; + } else { cpu_addr = iommu_dma_alloc_pages(dev, size, &page, gfp, attrs); - if (!cpu_addr) - return NULL; + if (!cpu_addr) + return NULL; + } *handle = __iommu_dma_map(dev, page_to_phys(page), size, ioprot, dev->coherent_dma_mask); @@ -2068,10 +2076,20 @@ static void iommu_dma_iova_unlink_range_slow(struct device *dev, arch_sync_dma_flush(); } -static void __iommu_dma_iova_unlink(struct device *dev, - struct dma_iova_state *state, size_t offset, size_t size, - enum dma_data_direction dir, unsigned long attrs, - bool free_iova) +/** + * dma_iova_unlink - Unlink a range of IOVA space + * @dev: DMA device + * @state: IOVA state + * @offset: offset into the IOVA state to unlink + * @size: size of the buffer + * @dir: DMA direction + * @attrs: attributes of mapping properties + * + * Unlink a range of IOVA space for the given IOVA state. + */ +void dma_iova_unlink(struct device *dev, struct dma_iova_state *state, + size_t offset, size_t size, enum dma_data_direction dir, + unsigned long attrs) { struct iommu_domain *domain = iommu_get_dma_domain(dev); struct iommu_dma_cookie *cookie = domain->iova_cookie; @@ -2087,35 +2105,13 @@ static void __iommu_dma_iova_unlink(struct device *dev, iommu_dma_iova_unlink_range_slow(dev, addr, size, dir, attrs); iommu_iotlb_gather_init(&iotlb_gather); - iotlb_gather.queued = free_iova && READ_ONCE(cookie->fq_domain); size = iova_align(iovad, size + iova_start_pad); addr -= iova_start_pad; unmapped = iommu_unmap_fast(domain, addr, size, &iotlb_gather); WARN_ON(unmapped != size); - if (!iotlb_gather.queued) - iommu_iotlb_sync(domain, &iotlb_gather); - if (free_iova) - iommu_dma_free_iova(domain, addr, size, &iotlb_gather); -} - -/** - * dma_iova_unlink - Unlink a range of IOVA space - * @dev: DMA device - * @state: IOVA state - * @offset: offset into the IOVA state to unlink - * @size: size of the buffer - * @dir: DMA direction - * @attrs: attributes of mapping properties - * - * Unlink a range of IOVA space for the given IOVA state. - */ -void dma_iova_unlink(struct device *dev, struct dma_iova_state *state, - size_t offset, size_t size, enum dma_data_direction dir, - unsigned long attrs) -{ - __iommu_dma_iova_unlink(dev, state, offset, size, dir, attrs, false); + iommu_iotlb_sync(domain, &iotlb_gather); } EXPORT_SYMBOL_GPL(dma_iova_unlink); @@ -2136,14 +2132,13 @@ void dma_iova_destroy(struct device *dev, struct dma_iova_state *state, unsigned long attrs) { if (mapped_len) - __iommu_dma_iova_unlink(dev, state, 0, mapped_len, dir, attrs, - true); - else - /* - * We can be here if first call to dma_iova_link() failed and - * there is nothing to unlink, so let's be more clear. - */ - dma_iova_free(dev, state); + dma_iova_unlink(dev, state, 0, mapped_len, dir, attrs); + + /* + * We can be here if the first call to dma_iova_link() failed and + * there is nothing to unlink, so let's be more clear. + */ + dma_iova_free(dev, state); } EXPORT_SYMBOL_GPL(dma_iova_destroy); diff --git a/drivers/xen/swiotlb-xen.c b/drivers/xen/swiotlb-xen.c index 2cbf2b588f5b..e2538824ef52 100644 --- a/drivers/xen/swiotlb-xen.c +++ b/drivers/xen/swiotlb-xen.c @@ -212,7 +212,7 @@ static dma_addr_t xen_swiotlb_map_phys(struct device *dev, phys_addr_t phys, BUG_ON(dir == DMA_NONE); if (attrs & DMA_ATTR_MMIO) { - if (unlikely(!dma_capable(dev, phys, size, false))) { + if (unlikely(!dma_capable(dev, phys, size, false, attrs))) { dev_err_once( dev, "DMA addr %pa+%zu overflow (mask %llx, bus limit %llx).\n", @@ -231,7 +231,7 @@ static dma_addr_t xen_swiotlb_map_phys(struct device *dev, phys_addr_t phys, * we can safely return the device addr and not worry about bounce * buffering it. */ - if (dma_capable(dev, dev_addr, size, true) && + if (dma_capable(dev, dev_addr, size, true, attrs) && !dma_kmalloc_needs_bounce(dev, size, dir) && !range_straddles_page_boundary(phys, size) && !xen_arch_need_swiotlb(dev, phys, dev_addr) && @@ -243,7 +243,7 @@ static dma_addr_t xen_swiotlb_map_phys(struct device *dev, phys_addr_t phys, */ trace_swiotlb_bounced(dev, dev_addr, size); - map = swiotlb_tbl_map_single(dev, phys, size, 0, dir, attrs); + map = swiotlb_tbl_map_single(dev, phys, size, 0, dir, &attrs); if (map == (phys_addr_t)DMA_MAPPING_ERROR) return DMA_MAPPING_ERROR; @@ -253,7 +253,7 @@ static dma_addr_t xen_swiotlb_map_phys(struct device *dev, phys_addr_t phys, /* * Ensure that the address returned is DMA'ble */ - if (unlikely(!dma_capable(dev, dev_addr, size, true))) { + if (unlikely(!dma_capable(dev, dev_addr, size, true, attrs))) { __swiotlb_tbl_unmap_single(dev, map, size, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC, swiotlb_find_pool(dev, map)); |
