Jason Gunthorpe <[email protected]> writes:

> On Mon, Jun 29, 2026 at 12:16:30PM +0530, Aneesh Kumar K.V wrote:
>> >> 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?. 
>
> Yes
>
>> > 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. 
>
> Yes
>
>> The current code already does this and uses the swiotlb pool correctly
>> on SME.
>
> Well, through the force_dma_unencrypted() hack...
>
>> 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:
>
>>      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.
>
>> 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

Reply via email to