From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
To: Marek Szyprowski <m.szyprowski@samsung.com>,
iommu@lists.linux.dev, linux-kernel@vger.kernel.org
Cc: Marek Szyprowski <m.szyprowski@samsung.com>,
Robin Murphy <robin.murphy@arm.com>,
David Rientjes <rientjes@google.com>,
Jason Gunthorpe <jgg@ziepe.ca>
Subject: Re: [PATCH] dma-pool: decrypt pages before creating the shared remap
Date: Thu, 12 Nov 2026 08:25:53 +0530 [thread overview]
Message-ID: <yq5aeccqrc5i.fsf@kernel.org> (raw)
In-Reply-To: <20261109154403.384434-1-m.szyprowski@samsung.com>
Marek Szyprowski <m.szyprowski@samsung.com> writes:
> atomic_pool_expand() creates the pgprot_decrypted() remap of the pool
> pages before calling set_memory_decrypted() on them. The error path
> when gen_pool_add_virt() fails does the reverse: it re-encrypts the
> pages and only then tears down the decrypted remap. In both cases there
> is a window where a decrypted (shared) kernel mapping points at a page
> that is still private, i.e. encrypted, to the guest.
>
> dma_direct_alloc() gets this right: it converts the pages first, then
> creates the remap, and on error removes the remap before re-encrypting.
> Do the same in atomic_pool_expand(). The pages are now converted before
> arch_dma_prep_coherent() and the remap, and the error path unwinds in
> reverse order.
>
> If set_memory_decrypted() fails, the page state is unknown, so the
> pages are still leaked rather than freed. No remap exists at that point
> any more, so nothing else needs to be undone.
>
Reviewed-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> Closes: https://sashiko.dev/#/bug/linux-9212d9b5-4a56-43e2-bc00-6e69b724078b
> Fixes: 76a19940bd62 ("dma-direct: atomic allocations must come from atomic coherent pools")
> Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> The patch was prepared with LLM assistance.
>
> Best regards
> Marek Szyprowski, PhD
> Samsung R&D Institute Poland
> ---
> kernel/dma/pool.c | 39 ++++++++++++++++++---------------------
> 1 file changed, 18 insertions(+), 21 deletions(-)
>
> diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
> index 381b3cb28368..3c67728a2471 100644
> --- a/kernel/dma/pool.c
> +++ b/kernel/dma/pool.c
> @@ -106,6 +106,17 @@ static int atomic_pool_expand(struct dma_gen_pool *dma_pool, size_t pool_size,
> if (!page)
> goto out;
>
> + /*
> + * Memory in the atomic DMA pools must be unencrypted, the pools do not
> + * shrink so no re-encryption occurs in dma_direct_free().
> + */
> + if (dma_pool->cc_shared) {
> + ret = set_memory_decrypted((unsigned long)page_to_virt(page),
> + 1 << order);
> + if (ret)
> + goto out;
> + }
> +
> arch_dma_prep_coherent(page, pool_size);
>
> #ifdef CONFIG_DMA_DIRECT_REMAP
> @@ -117,41 +128,27 @@ static int atomic_pool_expand(struct dma_gen_pool *dma_pool, size_t pool_size,
> addr = dma_common_contiguous_remap(page, pool_size, prot,
> __builtin_return_address(0));
> if (!addr)
> - goto free_page;
> + goto encrypt_pages;
> #else
> addr = page_to_virt(page);
> #endif
> - /*
> - * Memory in the atomic DMA pools must be unencrypted, the pools do not
> - * shrink so no re-encryption occurs in dma_direct_free().
> - */
> - if (dma_pool->cc_shared) {
> - ret = set_memory_decrypted((unsigned long)page_to_virt(page),
> - 1 << order);
> - if (ret) {
> - leak_pages = true;
> - goto remove_mapping;
> - }
> - }
> -
> ret = gen_pool_add_virt(dma_pool->pool, (unsigned long)addr,
> page_to_phys(page), pool_size, NUMA_NO_NODE);
> if (ret)
> - goto encrypt_mapping;
> + goto remove_mapping;
>
> dma_atomic_pool_size_add(gfp, pool_size);
> return 0;
>
> -encrypt_mapping:
> - if (dma_pool->cc_shared &&
> - set_memory_encrypted((unsigned long)page_to_virt(page), 1 << order))
> - leak_pages = true;
> -
> remove_mapping:
> #ifdef CONFIG_DMA_DIRECT_REMAP
> dma_common_free_remap(addr, pool_size);
> -free_page:
> +encrypt_pages:
> #endif
> + if (dma_pool->cc_shared &&
> + set_memory_encrypted((unsigned long)page_to_virt(page), 1 << order))
> + leak_pages = true;
> +
> if (!leak_pages &&
> !dma_release_from_contiguous(NULL, page, 1 << order))
> __free_pages(page, order);
> --
> 2.43.0
prev parent reply other threads:[~2026-11-12 2:56 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20261109154426eucas1p28dad751a60e6a8cd490b178bbf0400fb@eucas1p2.samsung.com>
2026-11-09 15:44 ` [PATCH] dma-pool: decrypt pages before creating the shared remap Marek Szyprowski
2026-11-12 2:55 ` Aneesh Kumar K.V [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=yq5aeccqrc5i.fsf@kernel.org \
--to=aneesh.kumar@kernel.org \
--cc=iommu@lists.linux.dev \
--cc=jgg@ziepe.ca \
--cc=linux-kernel@vger.kernel.org \
--cc=m.szyprowski@samsung.com \
--cc=rientjes@google.com \
--cc=robin.murphy@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.