All of lore.kernel.org
 help / color / mirror / Atom feed
From: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
To: Robin Murphy <robin.murphy@arm.com>,
	iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
	linux-coco@lists.linux.dev
Cc: Marek Szyprowski <m.szyprowski@samsung.com>,
	steven.price@arm.com, Suzuki K Poulose <suzuki.poulose@arm.com>
Subject: Re: [PATCH] dma-direct: swiotlb: Skip encryption toggles for swiotlb allocations
Date: Fri, 09 Jan 2026 08:21:17 +0530	[thread overview]
Message-ID: <yq5a7btr5wii.fsf@kernel.org> (raw)
In-Reply-To: <cddcaeff-9652-4685-ba6c-0fda79bd8680@arm.com>

Robin Murphy <robin.murphy@arm.com> writes:

> On 2026-01-02 3:54 pm, Aneesh Kumar K.V (Arm) wrote:
>> Swiotlb backing pages are already mapped decrypted via
>> swiotlb_update_mem_attributes(), so dma-direct does not need to call
>> set_memory_decrypted() during allocation or re-encrypt the memory on
>> free.
>> 
>> Handle swiotlb-backed buffers explicitly: obtain the DMA address and
>> zero the linear mapping for lowmem pages, and bypass the decrypt/encrypt
>> transitions when allocating/freeing from the swiotlb pool (detected via
>> swiotlb_find_pool()).
>
> swiotlb_update_mem_attributes() only applies to the default SWIOTLB 
> buffer, while the dma_direct_alloc_swiotlb() path is only for private 
> restricted pools (because the whole point is that restricted DMA devices 
> cannot use the regular allocator/default pools). There is no redundancy 
> here AFAICS.
>

But rmem_swiotlb_device_init() is also marking the entire pool decrypted

	set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
			     rmem->size >> PAGE_SHIFT);

-aneesh

>
> Thanks,
> Robin.
>
>> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
>> ---
>>   kernel/dma/direct.c | 56 +++++++++++++++++++++++++++++++++++++--------
>>   1 file changed, 46 insertions(+), 10 deletions(-)
>> 
>> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
>> index faf1e41afde8..c4ef4457bd74 100644
>> --- a/kernel/dma/direct.c
>> +++ b/kernel/dma/direct.c
>> @@ -104,15 +104,27 @@ static void __dma_direct_free_pages(struct device *dev, struct page *page,
>>   	dma_free_contiguous(dev, page, size);
>>   }
>>   
>> -static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size)
>> +static struct page *dma_direct_alloc_swiotlb(struct device *dev, size_t size,
>> +					     dma_addr_t *dma_handle)
>>   {
>> -	struct page *page = swiotlb_alloc(dev, size);
>> +	void *lm_addr;
>> +	struct page *page;
>> +
>> +	page = swiotlb_alloc(dev, size);
>> +	if (!page)
>> +		return NULL;
>>   
>> -	if (page && !dma_coherent_ok(dev, page_to_phys(page), size)) {
>> +	if (!dma_coherent_ok(dev, page_to_phys(page), size)) {
>>   		swiotlb_free(dev, page, size);
>>   		return NULL;
>>   	}
>> +	/* If HighMem let caller take care of creating a mapping */
>> +	if (PageHighMem(page))
>> +		return page;
>>   
>> +	lm_addr = page_address(page);
>> +	memset(lm_addr, 0, size);
>> +	*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
>>   	return page;
>>   }
>>   
>> @@ -125,9 +137,6 @@ static struct page *__dma_direct_alloc_pages(struct device *dev, size_t size,
>>   
>>   	WARN_ON_ONCE(!PAGE_ALIGNED(size));
>>   
>> -	if (is_swiotlb_for_alloc(dev))
>> -		return dma_direct_alloc_swiotlb(dev, size);
>> -
>>   	gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
>>   	page = dma_alloc_contiguous(dev, size, gfp);
>>   	if (page) {
>> @@ -204,6 +213,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>   		dma_addr_t *dma_handle, gfp_t gfp, unsigned long attrs)
>>   {
>>   	bool remap = false, set_uncached = false;
>> +	bool mark_mem_decrypt = true;
>>   	bool allow_highmem = true;
>>   	struct page *page;
>>   	void *ret;
>> @@ -251,6 +261,14 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>   	    dma_direct_use_pool(dev, gfp))
>>   		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
>>   
>> +	if (is_swiotlb_for_alloc(dev)) {
>> +		page = dma_direct_alloc_swiotlb(dev, size, dma_handle);
>> +		if (page) {
>> +			mark_mem_decrypt = false;
>> +			goto setup_page;
>> +		}
>> +		return NULL;
>> +	}
>>   
>>   	if (force_dma_unencrypted(dev))
>>   		/*
>> @@ -266,6 +284,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>   	if (!page)
>>   		return NULL;
>>   
>> +setup_page:
>>   	/*
>>   	 * dma_alloc_contiguous can return highmem pages depending on a
>>   	 * combination the cma= arguments and per-arch setup.  These need to be
>> @@ -295,7 +314,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>   		ret = page_address(page);
>>   	}
>>   
>> -	if (force_dma_unencrypted(dev)) {
>> +	if (mark_mem_decrypt && force_dma_unencrypted(dev)) {
>>   		void *lm_addr;
>>   
>>   		lm_addr = page_address(page);
>> @@ -316,7 +335,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>   	return ret;
>>   
>>   out_encrypt_pages:
>> -	if (dma_set_encrypted(dev, page_address(page), size))
>> +	if (mark_mem_decrypt && dma_set_encrypted(dev, page_address(page), size))
>>   		return NULL;
>>   out_free_pages:
>>   	__dma_direct_free_pages(dev, page, size);
>> @@ -328,6 +347,7 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>   void dma_direct_free(struct device *dev, size_t size,
>>   		void *cpu_addr, dma_addr_t dma_addr, unsigned long attrs)
>>   {
>> +	bool mark_mem_encrypted = true;
>>   	unsigned int page_order = get_order(size);
>>   
>>   	if ((attrs & DMA_ATTR_NO_KERNEL_MAPPING) &&
>> @@ -356,6 +376,9 @@ void dma_direct_free(struct device *dev, size_t size,
>>   	    dma_free_from_pool(dev, cpu_addr, PAGE_ALIGN(size)))
>>   		return;
>>   
>> +	if (swiotlb_find_pool(dev, dma_to_phys(dev, dma_addr)))
>> +		mark_mem_encrypted = false;
>> +
>>   	if (is_vmalloc_addr(cpu_addr)) {
>>   		vunmap(cpu_addr);
>>   	} else {
>> @@ -363,7 +386,7 @@ void dma_direct_free(struct device *dev, size_t size,
>>   			arch_dma_clear_uncached(cpu_addr, size);
>>   	}
>>   
>> -	if (force_dma_unencrypted(dev)) {
>> +	if (mark_mem_encrypted && force_dma_unencrypted(dev)) {
>>   		void *lm_addr;
>>   
>>   		lm_addr = phys_to_virt(dma_to_phys(dev, dma_addr));
>> @@ -385,6 +408,15 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
>>   	if (force_dma_unencrypted(dev) && dma_direct_use_pool(dev, gfp))
>>   		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
>>   
>> +	if (is_swiotlb_for_alloc(dev)) {
>> +		page = dma_direct_alloc_swiotlb(dev, size, dma_handle);
>> +		if (page && PageHighMem(page)) {
>> +			swiotlb_free(dev, page, size);
>> +			return NULL;
>> +		}
>> +		return page;
>> +	}
>> +
>>   	page = __dma_direct_alloc_pages(dev, size, gfp, false);
>>   	if (!page)
>>   		return NULL;
>> @@ -404,13 +436,17 @@ void dma_direct_free_pages(struct device *dev, size_t size,
>>   		enum dma_data_direction dir)
>>   {
>>   	void *vaddr = page_address(page);
>> +	bool mark_mem_encrypted = true;
>>   
>>   	/* If cpu_addr is not from an atomic pool, dma_free_from_pool() fails */
>>   	if (IS_ENABLED(CONFIG_DMA_COHERENT_POOL) &&
>>   	    dma_free_from_pool(dev, vaddr, size))
>>   		return;
>>   
>> -	if (dma_set_encrypted(dev, vaddr, size))
>> +	if (swiotlb_find_pool(dev, page_to_phys(page)))
>> +		mark_mem_encrypted = false;
>> +
>> +	if (mark_mem_encrypted && dma_set_encrypted(dev, vaddr, size))
>>   		return;
>>   	__dma_direct_free_pages(dev, page, size);
>>   }

  reply	other threads:[~2026-01-09  2:51 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-02 15:54 [PATCH] dma-direct: swiotlb: Skip encryption toggles for swiotlb allocations Aneesh Kumar K.V (Arm)
2026-01-08 11:01 ` Robin Murphy
2026-01-09  2:51   ` Aneesh Kumar K.V [this message]
2026-01-12 13:25     ` Robin Murphy
2026-01-12 15:42       ` Aneesh Kumar K.V
2026-01-14  9:49         ` Aneesh Kumar K.V
2026-01-19  9:52           ` Marek Szyprowski
2026-01-19 14:28             ` Robin Murphy
2026-01-19 15:53               ` Aneesh Kumar K.V
2026-01-19 16:37                 ` Robin Murphy
2026-01-20  9:33                   ` Aneesh Kumar K.V

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=yq5a7btr5wii.fsf@kernel.org \
    --to=aneesh.kumar@kernel.org \
    --cc=iommu@lists.linux.dev \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=robin.murphy@arm.com \
    --cc=steven.price@arm.com \
    --cc=suzuki.poulose@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.