On 2021-11-11 06:50, Christoph Hellwig wrote:
We must never unencryped memory go back into the general page pool.
So if we fail to set it back to encrypted when freeing DMA memory, leak
the memory insted and warn the user.

Nit: typos of "unencrypted" and "instead". Plus presumably the first sentence was meant to have a "let" or similar in there too.

Reviewed-by: Robin Murphy <robin.mur...@arm.com>

Signed-off-by: Christoph Hellwig <h...@lst.de>
---
  kernel/dma/direct.c | 14 ++++++++++----
  1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
index 996ba4edb2fa3..d7a489be48470 100644
--- a/kernel/dma/direct.c
+++ b/kernel/dma/direct.c
@@ -84,9 +84,14 @@ static int dma_set_decrypted(struct device *dev, void 
*vaddr, size_t size)
static int dma_set_encrypted(struct device *dev, void *vaddr, size_t size)
  {
+       int ret;
+
        if (!force_dma_unencrypted(dev))
                return 0;
-       return set_memory_encrypted((unsigned long)vaddr, 1 << get_order(size));
+       ret = set_memory_encrypted((unsigned long)vaddr, 1 << get_order(size));
+       if (ret)
+               pr_warn_ratelimited("leaking DMA memory that can't be 
re-encrypted\n");
+       return ret;
  }
static void __dma_direct_free_pages(struct device *dev, struct page *page,
@@ -261,7 +266,6 @@ void *dma_direct_alloc(struct device *dev, size_t size,
        return ret;
out_encrypt_pages:
-       /* If memory cannot be re-encrypted, it must be leaked */
        if (dma_set_encrypted(dev, page_address(page), size))
                return NULL;
  out_free_pages:
@@ -307,7 +311,8 @@ void dma_direct_free(struct device *dev, size_t size,
        } else {
                if (IS_ENABLED(CONFIG_ARCH_HAS_DMA_CLEAR_UNCACHED))
                        arch_dma_clear_uncached(cpu_addr, size);
-               dma_set_encrypted(dev, cpu_addr, 1 << page_order);
+               if (dma_set_encrypted(dev, cpu_addr, 1 << page_order))
+                       return;
        }
__dma_direct_free_pages(dev, dma_direct_to_page(dev, dma_addr), size);
@@ -361,7 +366,8 @@ void dma_direct_free_pages(struct device *dev, size_t size,
            dma_free_from_pool(dev, vaddr, size))
                return;
- dma_set_encrypted(dev, vaddr, 1 << page_order);
+       if (dma_set_encrypted(dev, vaddr, 1 << page_order))
+               return;
        __dma_direct_free_pages(dev, page, size);
  }
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to