A restricted DMA pool is a firmware-described ownership boundary. Unlike
a pool allocated by SWIOTLB itself, its base cannot be moved and its
size cannot be rounded without claiming memory outside the reserved
region.

Confidential-computing guests may require private/shared state changes
to cover units larger than PAGE_SIZE. Passing a misaligned restricted
region to set_memory_decrypted() can therefore fail.

Validate both the physical base and the complete reserved size with the
common CoCo shared-range helper before allocating SWIOTLB metadata or
performing a state transition. Perform the transition through
cc_make_shared().

Signed-off-by: Aneesh Kumar K.V (Arm) <[email protected]>
---
 kernel/dma/swiotlb.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index 9928d75efc2d..cb67105b8812 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -2010,6 +2010,14 @@ static int rmem_swiotlb_device_init(struct reserved_mem 
*rmem,
                return -EINVAL;
        }
 
+       if (cc_platform_has(CC_ATTR_MEM_ENCRYPT) &&
+           !cc_shared_range_valid(rmem->base, rmem->size)) {
+               dev_err(dev,
+                       "Restricted DMA pool must be aligned to %#zx bytes for 
memory encryption\n",
+                       cc_shared_granule_size());
+               return -EINVAL;
+       }
+
        /*
         * Since multiple devices can share the same pool, the private data,
         * io_tlb_mem struct, will be initialized by the first device attached
@@ -2043,8 +2051,7 @@ static int rmem_swiotlb_device_init(struct reserved_mem 
*rmem,
                        int ret;
 
                        mem->cc_shared = true;
-                       ret = set_memory_decrypted((unsigned 
long)phys_to_virt(rmem->base),
-                                                  rmem->size >> PAGE_SHIFT);
+                       ret = cc_make_shared(phys_to_virt(rmem->base), 
rmem->size);
                        if (ret) {
                                dev_err(dev, "Failed to decrypt restricted DMA 
pool\n");
                                kfree(pool->areas);
-- 
2.43.0

Reply via email to