public inbox for linuxppc-dev@ozlabs.org 
 help / color / mirror / Atom feed
From: Petr Tesarik <ptesarik@suse•com>
To: "Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel•org>
Cc: iommu@lists•linux.dev, linux-arm-kernel@lists•infradead.org,
	linux-kernel@vger•kernel.org, linux-coco@lists•linux.dev,
	Robin Murphy <robin.murphy@arm•com>,
	Marek Szyprowski <m.szyprowski@samsung•com>,
	Will Deacon <will@kernel•org>, Marc Zyngier <maz@kernel•org>,
	Steven Price <steven.price@arm•com>,
	Suzuki K Poulose <Suzuki.Poulose@arm•com>,
	Catalin Marinas <catalin.marinas@arm•com>,
	Jiri Pirko <jiri@resnulli•us>, Jason Gunthorpe <jgg@ziepe•ca>,
	Mostafa Saleh <smostafa@google•com>,
	Alexey Kardashevskiy <aik@amd•com>,
	Dan Williams <dan.j.williams@intel•com>,
	Xu Yilun <yilun.xu@linux•intel.com>,
	linuxppc-dev@lists•ozlabs.org, linux-s390@vger•kernel.org,
	Madhavan Srinivasan <maddy@linux•ibm.com>,
	Michael Ellerman <mpe@ellerman•id.au>,
	Nicholas Piggin <npiggin@gmail•com>,
	"Christophe Leroy (CS GROUP)" <chleroy@kernel•org>,
	Alexander Gordeev <agordeev@linux•ibm.com>,
	Gerald Schaefer <gerald.schaefer@linux•ibm.com>,
	Heiko Carstens <hca@linux•ibm.com>,
	Vasily Gorbik <gor@linux•ibm.com>,
	Christian Borntraeger <borntraeger@linux•ibm.com>,
	Sven Schnelle <svens@linux•ibm.com>,
	x86@kernel•org, Michael Kelley <mhklinux@outlook•com>
Subject: Re: [PATCH v6 17/20] dma: swiotlb: handle set_memory_decrypted() failures
Date: Tue, 9 Jun 2026 15:32:55 +0200	[thread overview]
Message-ID: <20260609153255.4b9e9373@mordecai> (raw)
In-Reply-To: <20260604083959.1265923-18-aneesh.kumar@kernel.org>

On Thu,  4 Jun 2026 14:09:56 +0530
"Aneesh Kumar K.V (Arm)" <aneesh.kumar@kernel•org> wrote:

> Check the return value when converting swiotlb pools between encrypted and
> decrypted mappings. If the default pool cannot be decrypted after early
> initialization, mark the pool fully used so it cannot satisfy future bounce
> allocations.
> 
> For late initialization, return the `set_memory_decrypted()` failure. For
> restricted DMA pools, fail device initialization if the reserved pool
> cannot be decrypted.
> 
> This prevents swiotlb from using pools whose encryption attributes do not
> match their metadata, and avoids returning pages with uncertain encryption
> state back to the allocator.

This works fine, but instead of effectively leaking the memory, we
could return it to the buddy allocator and reset nslabs to zero as if
SWIOTLB was not even initialized.

OTOH I don't want to overthink this, because the system is probably not
too useful after such a boot-time failure, so unless you _want_ to
improve the error path, you can simply add:

Reviewed-by: Petr Tesarik <ptesarik@suse•com>

Petr T

> Tested-by: Michael Kelley <mhklinux@outlook•com>
> Tested-by: Mostafa Saleh <smostafa@google•com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel•org>
> ---
>  kernel/dma/swiotlb.c | 80 +++++++++++++++++++++++++++++++++++---------
>  1 file changed, 65 insertions(+), 15 deletions(-)
> 
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index 4c56f64602ea..14d834ca298b 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -248,6 +248,23 @@ static inline unsigned long nr_slots(u64 val)
>  	return DIV_ROUND_UP(val, IO_TLB_SIZE);
>  }
>  
> +static void swiotlb_mark_pool_used(struct io_tlb_pool *pool)
> +{
> +	unsigned long i;
> +
> +	for (i = 0; i < pool->nareas; i++) {
> +		pool->areas[i].index = 0;
> +		pool->areas[i].used = pool->area_nslabs;
> +	}
> +
> +	for (i = 0; i < pool->nslabs; i++) {
> +		pool->slots[i].list = 0;
> +		pool->slots[i].orig_addr = INVALID_PHYS_ADDR;
> +		pool->slots[i].alloc_size = 0;
> +		pool->slots[i].pad_slots = 0;
> +	}
> +}
> +
>  /*
>   * Early SWIOTLB allocation may be too early to allow an architecture to
>   * perform the desired operations.  This function allows the architecture to
> @@ -272,8 +289,16 @@ void __init swiotlb_update_mem_attributes(void)
>  		return;
>  	bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
>  
> -	if (io_tlb_default_mem.unencrypted)
> -		set_memory_decrypted((unsigned long)mem->vaddr, bytes >> PAGE_SHIFT);
> +	if (io_tlb_default_mem.unencrypted) {
> +		int ret;
> +
> +		ret = set_memory_decrypted((unsigned long)mem->vaddr,
> +					   bytes >> PAGE_SHIFT);
> +		if (ret) {
> +			pr_warn("Failed to decrypt default memory pool, disabling it\n");
> +			swiotlb_mark_pool_used(mem);
> +		}
> +	}
>  }
>  
>  static void swiotlb_init_io_tlb_pool(struct io_tlb_pool *mem, phys_addr_t start,
> @@ -442,9 +467,10 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
>  {
>  	struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
>  	unsigned long nslabs = ALIGN(size >> IO_TLB_SHIFT, IO_TLB_SEGSIZE);
> +	unsigned int order, area_order, slot_order;
> +	bool leak_pages = false;
>  	unsigned int nareas;
>  	unsigned char *vstart = NULL;
> -	unsigned int order, area_order;
>  	bool retried = false;
>  	int rc = 0;
>  
> @@ -504,6 +530,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
>  			(PAGE_SIZE << order) >> 20);
>  	}
>  
> +	rc = -ENOMEM;
>  	nareas = limit_nareas(default_nareas, nslabs);
>  	area_order = get_order(array_size(sizeof(*mem->areas), nareas));
>  	mem->areas = (struct io_tlb_area *)
> @@ -511,14 +538,20 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
>  	if (!mem->areas)
>  		goto error_area;
>  
> +	slot_order = get_order(array_size(sizeof(*mem->slots), nslabs));
>  	mem->slots = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
> -		get_order(array_size(sizeof(*mem->slots), nslabs)));
> +					      slot_order);
>  	if (!mem->slots)
>  		goto error_slots;
>  
> -	if (io_tlb_default_mem.unencrypted)
> -		set_memory_decrypted((unsigned long)vstart,
> -				     (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
> +	if (io_tlb_default_mem.unencrypted) {
> +		rc = set_memory_decrypted((unsigned long)vstart,
> +					  (nslabs << IO_TLB_SHIFT) >> PAGE_SHIFT);
> +		if (rc) {
> +			leak_pages = true;
> +			goto error_decrypt;
> +		}
> +	}
>  
>  	swiotlb_init_io_tlb_pool(mem, virt_to_phys(vstart), nslabs, true,
>  				 nareas);
> @@ -527,16 +560,20 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
>  	swiotlb_print_info();
>  	return 0;
>  
> +error_decrypt:
> +	free_pages((unsigned long)mem->slots, slot_order);
>  error_slots:
>  	free_pages((unsigned long)mem->areas, area_order);
>  error_area:
> -	free_pages((unsigned long)vstart, order);
> -	return -ENOMEM;
> +	if (!leak_pages)
> +		free_pages((unsigned long)vstart, order);
> +	return rc;
>  }
>  
>  void __init swiotlb_exit(void)
>  {
>  	struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
> +	bool leak_pages = false;
>  	unsigned long tbl_vaddr;
>  	size_t tbl_size, slots_size;
>  	unsigned int area_order;
> @@ -552,19 +589,23 @@ void __init swiotlb_exit(void)
>  	tbl_size = PAGE_ALIGN(mem->end - mem->start);
>  	slots_size = PAGE_ALIGN(array_size(sizeof(*mem->slots), mem->nslabs));
>  
> -	if (io_tlb_default_mem.unencrypted)
> -		set_memory_encrypted(tbl_vaddr, tbl_size >> PAGE_SHIFT);
> +	if (io_tlb_default_mem.unencrypted) {
> +		if (set_memory_encrypted(tbl_vaddr, tbl_size >> PAGE_SHIFT))
> +			leak_pages = true;
> +	}
>  
>  	if (mem->late_alloc) {
>  		area_order = get_order(array_size(sizeof(*mem->areas),
>  			mem->nareas));
>  		free_pages((unsigned long)mem->areas, area_order);
> -		free_pages(tbl_vaddr, get_order(tbl_size));
> +		if (!leak_pages)
> +			free_pages(tbl_vaddr, get_order(tbl_size));
>  		free_pages((unsigned long)mem->slots, get_order(slots_size));
>  	} else {
>  		memblock_free(mem->areas,
>  			array_size(sizeof(*mem->areas), mem->nareas));
> -		memblock_phys_free(mem->start, tbl_size);
> +		if (!leak_pages)
> +			memblock_phys_free(mem->start, tbl_size);
>  		memblock_free(mem->slots, slots_size);
>  	}
>  
> @@ -1938,9 +1979,18 @@ static int rmem_swiotlb_device_init(struct reserved_mem *rmem,
>  		 * restricted mem pool is decrypted by default
>  		 */
>  		if (cc_platform_has(CC_ATTR_MEM_ENCRYPT)) {
> +			int ret;
> +
>  			mem->unencrypted = true;
> -			set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
> -					     rmem->size >> PAGE_SHIFT);
> +			ret = set_memory_decrypted((unsigned long)phys_to_virt(rmem->base),
> +						   rmem->size >> PAGE_SHIFT);
> +			if (ret) {
> +				dev_err(dev, "Failed to decrypt restricted DMA pool\n");
> +				kfree(pool->areas);
> +				kfree(pool->slots);
> +				kfree(mem);
> +				return ret;
> +			}
>  		} else {
>  			mem->unencrypted = false;
>  		}



  reply	other threads:[~2026-06-09 13:33 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-04  8:39 [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths Aneesh Kumar K.V (Arm)
2026-06-04  8:39 ` [PATCH v6 01/20] s390: Expose protected virtualization through cc_platform_has() Aneesh Kumar K.V (Arm)
2026-06-06  0:34   ` JAEHOON KIM
2026-06-09 13:44   ` Catalin Marinas
2026-06-04  8:39 ` [PATCH v6 02/20] dma-direct: swiotlb: handle swiotlb alloc/free outside __dma_direct_alloc_pages Aneesh Kumar K.V (Arm)
2026-06-09 12:15   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 03/20] dma-direct: use DMA_ATTR_CC_SHARED in alloc/free paths Aneesh Kumar K.V (Arm)
2026-06-09 12:18   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 04/20] dma-pool: track decrypted atomic pools and select them via attrs Aneesh Kumar K.V (Arm)
2026-06-09 12:23   ` Petr Tesarik
2026-06-09 14:32   ` Jason Gunthorpe
2026-06-04  8:39 ` [PATCH v6 05/20] dma: swiotlb: pass mapping attributes by reference Aneesh Kumar K.V (Arm)
2026-06-09 12:21   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 06/20] dma: swiotlb: track pool encryption state and honor DMA_ATTR_CC_SHARED Aneesh Kumar K.V (Arm)
2026-06-09 12:48   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 07/20] dma-mapping: make dma_pgprot() " Aneesh Kumar K.V (Arm)
2026-06-04  8:39 ` [PATCH v6 08/20] dma-direct: pass attrs to dma_capable() for DMA_ATTR_CC_SHARED checks Aneesh Kumar K.V (Arm)
2026-06-09 12:50   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 09/20] dma-direct: make dma_direct_map_phys() honor DMA_ATTR_CC_SHARED Aneesh Kumar K.V (Arm)
2026-06-04  8:39 ` [PATCH v6 10/20] dma-direct: set decrypted flag for remapped DMA allocations Aneesh Kumar K.V (Arm)
2026-06-04  8:39 ` [PATCH v6 11/20] dma-direct: select DMA address encoding from DMA_ATTR_CC_SHARED Aneesh Kumar K.V (Arm)
2026-06-04  8:39 ` [PATCH v6 12/20] dma-pool: fix page leak in atomic_pool_expand() cleanup Aneesh Kumar K.V (Arm)
2026-06-04  8:39 ` [PATCH v6 13/20] dma-direct: rename ret to cpu_addr in alloc helpers Aneesh Kumar K.V (Arm)
2026-06-09 12:54   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 14/20] dma-direct: return struct page from dma_direct_alloc_from_pool() Aneesh Kumar K.V (Arm)
2026-06-09 13:12   ` Petr Tesarik
2026-06-09 13:45   ` Catalin Marinas
2026-06-09 14:15   ` Jason Gunthorpe
2026-06-04  8:39 ` [PATCH v6 15/20] iommu/dma: Check atomic pool allocation result directly Aneesh Kumar K.V (Arm)
2026-06-09 13:13   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 16/20] dma: swiotlb: free dynamic pools from process context Aneesh Kumar K.V (Arm)
2026-06-09 13:23   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 17/20] dma: swiotlb: handle set_memory_decrypted() failures Aneesh Kumar K.V (Arm)
2026-06-09 13:32   ` Petr Tesarik [this message]
2026-06-04  8:39 ` [PATCH v6 18/20] dma: free atomic pool pages by physical address Aneesh Kumar K.V (Arm)
2026-06-04  8:39 ` [PATCH v6 19/20] swiotlb: Preserve allocation virtual address for dynamic pools Aneesh Kumar K.V (Arm)
2026-06-09 13:40   ` Petr Tesarik
2026-06-04  8:39 ` [PATCH v6 20/20] swiotlb: remove unused SWIOTLB_FORCE flag Aneesh Kumar K.V (Arm)
2026-06-09 13:44   ` Petr Tesarik
2026-06-09 13:43 ` [PATCH v6 00/20] dma-mapping: Use DMA_ATTR_CC_SHARED through direct, pool and swiotlb paths Catalin Marinas
2026-06-09 14:47   ` Jason Gunthorpe

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=20260609153255.4b9e9373@mordecai \
    --to=ptesarik@suse$(echo .)com \
    --cc=Suzuki.Poulose@arm$(echo .)com \
    --cc=agordeev@linux$(echo .)ibm.com \
    --cc=aik@amd$(echo .)com \
    --cc=aneesh.kumar@kernel$(echo .)org \
    --cc=borntraeger@linux$(echo .)ibm.com \
    --cc=catalin.marinas@arm$(echo .)com \
    --cc=chleroy@kernel$(echo .)org \
    --cc=dan.j.williams@intel$(echo .)com \
    --cc=gerald.schaefer@linux$(echo .)ibm.com \
    --cc=gor@linux$(echo .)ibm.com \
    --cc=hca@linux$(echo .)ibm.com \
    --cc=iommu@lists$(echo .)linux.dev \
    --cc=jgg@ziepe$(echo .)ca \
    --cc=jiri@resnulli$(echo .)us \
    --cc=linux-arm-kernel@lists$(echo .)infradead.org \
    --cc=linux-coco@lists$(echo .)linux.dev \
    --cc=linux-kernel@vger$(echo .)kernel.org \
    --cc=linux-s390@vger$(echo .)kernel.org \
    --cc=linuxppc-dev@lists$(echo .)ozlabs.org \
    --cc=m.szyprowski@samsung$(echo .)com \
    --cc=maddy@linux$(echo .)ibm.com \
    --cc=maz@kernel$(echo .)org \
    --cc=mhklinux@outlook$(echo .)com \
    --cc=mpe@ellerman$(echo .)id.au \
    --cc=npiggin@gmail$(echo .)com \
    --cc=robin.murphy@arm$(echo .)com \
    --cc=smostafa@google$(echo .)com \
    --cc=steven.price@arm$(echo .)com \
    --cc=svens@linux$(echo .)ibm.com \
    --cc=will@kernel$(echo .)org \
    --cc=x86@kernel$(echo .)org \
    --cc=yilun.xu@linux$(echo .)intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox