Re: [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths
From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Date: 2026-07-01 03:09:31
Also in:
linux-arm-kernel, linux-coco, linux-iommu, linux-s390, lkml
Jason Gunthorpe [off-list ref] writes:
On Mon, Jun 29, 2026 at 12:16:30PM +0530, Aneesh Kumar K.V wrote:quoted
quoted
quoted
Thinking about this more, I guess we should mark the swiotlb as cc_shared only with CC_ATTR_GUEST_MEM_ENCRYPT instead of CC_ATTR_MEM_ENCRYPT as we have below.The name cc_shared should be used for GUEST scenarios only. I guess there is some merit in keeping swiotlb using "decrypted" to mean it usinig pgprot_decrypted and set_memory_decyped() which AMD gives meaning to on both host and guest.Are you suggesting to change the struct io_tlb_mem::cc_shared back to struct io_tlb_mem::unencrypted?.Yesquoted
quoted
IDK what AMD should do on the host by default. I guess it should setup a swiotlb pool of low dma addrs "unencrypted", but not "cc_shared"?If by low DMA address you mean using an address with the C-bit cleared.Yesquoted
The current code already does this and uses the swiotlb pool correctly on SME.Well, through the force_dma_unencrypted() hack...quoted
The challenge arises when we want to force SWIOTLB bouncing even for devices that can handle encrypted DMA addresses (more on that below). For such a config force_dma_uencrypted(dev) will return false and swiotlb will be marked cc_shared/decrypted = true; This trip the new check we added.Yes, because cc_shared (guest) and unencrypted (host) are very different things and we've mixed them:quoted
if (unlikely(mem->cc_shared != force_dma_unencrypted(dev)))I'm aruging force_dma_unencrypted should mean cc_shared and be guest_only, but the SME hack breaks this.quoted
We can also do if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { /* swiotlb pool is incorrect for this device */ if (unlikely(mem->cc_shared != force_dma_unencrypted(dev))) return (phys_addr_t)DMA_MAPPING_ERROR; /* Force attrs to match the kind of memory in the pool */ if (mem->cc_shared) *attrs |= DMA_ATTR_CC_SHARED; else *attrs &= ~DMA_ATTR_CC_SHARED; } else { /* * Host memory encryption where device requires an * unencrypted dma_addr_t due to dma mask limit */ if (force_dma_unencrypted(dev)) *attrs |= DMA_ATTR_CC_SHARED; else *attrs &= ~DMA_ATTR_CC_SHARED; }If we do this I would like to split the force_dma_.. functions into guest and host, ie force_dma_cc_shared() and force_host_decrypted() To make it clear there are two very different things here.
I have now folded the below change into modified kernel/dma/swiotlb.c
@@ -1514,9 +1514,23 @@ 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->cc_shared != force_dma_unencrypted(dev))) - return (phys_addr_t)DMA_MAPPING_ERROR; + if (cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT)) { + + /* swiotlb pool is incorrect for this device */ + if (unlikely(mem->cc_shared != force_dma_unencrypted(dev))) + return (phys_addr_t)DMA_MAPPING_ERROR; + + } else if (cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT)) { + /* + * On hosts with memory encryption, SWIOTLB-backed memory is + * unencrypted. DMA addresses returned for bounce buffers must + * therefore be marked unencrypted, even for devices that can + * address encrypted memory. This also preserves swiotlb=force + * behavior for those devices. + */ + if (unlikely(!mem->cc_shared)) + return (phys_addr_t)DMA_MAPPING_ERROR; + }
[PATCH] dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED This is the only code path where we need to special-case host memory encryption. For this reason, I have avoided renaming io_tlb_mem::cc_shared to io_tlb_mem::unencrypted. I can send a v7 with the above and we can review the changes based on that? -aneesh