Re: [PATCH v4 04/13] dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED
From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Date: 2026-05-21 17:21:11
Also in:
linux-arm-kernel, linux-coco, linux-iommu, linux-s390, lkml
Mostafa Saleh [off-list ref] writes:
On Tue, May 12, 2026 at 10:05 AM Aneesh Kumar K.V (Arm) [off-list ref] wrote:quoted
@@ -1411,6 +1436,16 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) pr_warn_once("Memory encryption is active and system is using DMA bounce buffers\n"); + /* + * if we are trying to swiotlb map a decrypted paddr or the paddr is encrypted + * but the device is forcing decryption, use decrypted io_tlb_mem + */ + if ((attrs & DMA_ATTR_CC_SHARED) || force_dma_unencrypted(dev))I don't think swiotlb needs to know about force_dma_unencrypted(), the dma/direct caller should have all the information to pass the appropriate flags. Thanks. Mostafaquoted
+ require_decrypted = true; + + if (require_decrypted != mem->unencrypted) + return (phys_addr_t)DMA_MAPPING_ERROR; +
Based on other email threads, this is now updated to
@@ -1372,9 +1417,19 @@ static unsigned long mem_used(struct io_tlb_mem *mem) * any pre- or post-padding for alignment * @alloc_align_mask: Required start and end alignment of the allocated buffer * @dir: DMA direction - * @attrs: Optional DMA attributes for the map operation + * @attrs: Optional DMA attributes for the map operation, updated + * to match the selected SWIOTLB pool * * Find and allocate a suitable sequence of IO TLB slots for the request. + * The device's SWIOTLB pool must match the device's current DMA encryption + * requirements. If the device requires decrypted DMA, bouncing is done through + * an unencrypted pool and the mapping is marked shared. If the device can DMA + * to encrypted memory, bouncing is done through an encrypted pool even when the + * original DMA address was unencrypted. Enabling encrypted DMA for a device is + * therefore expected to update its default io_tlb_mem to an encrypted pool, so + * later bounce mappings for both encrypted and decrypted original memory use + * that encrypted pool. + * * The allocated space starts at an alignment specified by alloc_align_mask, * and the size of the allocated space is rounded up so that the total amount * of allocated space is a multiple of (alloc_align_mask + 1). If
@@ -1411,6 +1466,16 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr, if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) pr_warn_once("Memory encryption is active and system is using DMA bounce buffers\n"); + /* swiotlb pool is incorrect for this device */ + if (unlikely(mem->unencrypted != force_dma_unencrypted(dev))) + return (phys_addr_t)DMA_MAPPING_ERROR; + + /* Force attrs to match the kind of memory in the pool */ + if (mem->unencrypted) + *attrs |= DMA_ATTR_CC_SHARED; + else + *attrs &= ~DMA_ATTR_CC_SHARED; + /* * The default swiotlb memory pool is allocated with PAGE_SIZE * alignment. If a mapping is requested with larger alignment,
@@ -1608,8 +1673,11 @@ dma_addr_t swiotlb_map(struct device *dev, phys_addr_t paddr, size_t size, if (swiotlb_addr == (phys_addr_t)DMA_MAPPING_ERROR) return DMA_MAPPING_ERROR; - /* Ensure that the address returned is DMA'ble */ - dma_addr = phys_to_dma_unencrypted(dev, swiotlb_addr); + if (attrs & DMA_ATTR_CC_SHARED) + dma_addr = phys_to_dma_unencrypted(dev, swiotlb_addr); + else + dma_addr = phys_to_dma_encrypted(dev, swiotlb_addr); + if (unlikely(!dma_capable(dev, dma_addr, size, true))) { __swiotlb_tbl_unmap_single(dev, swiotlb_addr, size, dir, attrs | DMA_ATTR_SKIP_CPU_SYNC,
@@ -1773,7 +1841,7 @@ static inline void swiotlb_create_debugfs_files(struct io_tlb_mem *mem,