Linux s390 Architecture development
 help / color / mirror / Atom feed
* [RFC PATCH] dma: swiotlb: Size shared default pools for memory encryption
@ 2026-08-11 13:40 Aneesh Kumar K.V (Arm)
  2026-08-12 10:01 ` Catalin Marinas
  0 siblings, 1 reply; 4+ messages in thread
From: Aneesh Kumar K.V (Arm) @ 2026-08-11 13:40 UTC (permalink / raw)
  To: iommu, linux-arm-kernel, linux-kernel, linux-coco
  Cc: Robin Murphy, Marek Szyprowski, Will Deacon, Marc Zyngier,
	Steven Price, Suzuki K Poulose, Catalin Marinas, Jiri Pirko,
	Jason Gunthorpe, Mostafa Saleh, Petr Tesarik,
	Alexey Kardashevskiy, Dan Williams, Xu Yilun, linuxppc-dev,
	linux-s390, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, Aneesh Kumar K.V (Arm)

Systems with memory encryption use swiotlb to provide shared or
unencrypted buffers for device DMA. Confidential guests may route all
DMA through these buffers, while SME hosts use them for devices that
cannot address encrypted memory. The default swiotlb pool can therefore
be exhausted under I/O-intensive workloads.

Let architectures mark the default swiotlb pool as shared before
swiotlb_init(). Move the existing x86 sizing policy into generic swiotlb
code and add early pool marking for arm64 Realm guests, powerpc secure
guests, s390 protected-virtualization guests, and x86 memory-encryption
platforms. Use CC_ATTR_MEM_ENCRYPT on x86 to include host SME, whose
swiotlb pool must also be decrypted for devices that cannot address
encrypted memory.

Move the powerpc secure-guest swiotlb enablement before initialization
so that the shared pool is allocated with the required flags. pKVM
guests continue to use a restricted DMA pool instead of the default
swiotlb pool.

Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
---
 arch/arm64/mm/init.c                 |  6 ++-
 arch/powerpc/mm/mem.c                |  7 +++
 arch/powerpc/platforms/pseries/svm.c | 10 ----
 arch/s390/mm/init.c                  |  2 +
 arch/x86/mm/mem_encrypt.c            | 27 ++--------
 include/linux/swiotlb.h              |  7 ++-
 kernel/dma/swiotlb.c                 | 73 ++++++++++++++++++++++------
 7 files changed, 82 insertions(+), 50 deletions(-)

diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
index e308a7cabd12..4c022e8aed43 100644
--- a/arch/arm64/mm/init.c
+++ b/arch/arm64/mm/init.c
@@ -338,8 +338,12 @@ void __init arch_setup_zero_pages(void)
 void __init arch_mm_preinit(void)
 {
 	unsigned int flags = SWIOTLB_VERBOSE;
+	/* pKVM uses restricted-dma-pool */
+	bool cc_guest = is_realm_world();
 
-	if (max_pfn <= PFN_DOWN(arm64_dma_phys_limit)) {
+	if (cc_guest) {
+		swiotlb_mark_default_cc_shared();
+	} else if (max_pfn <= PFN_DOWN(arm64_dma_phys_limit)) {
 		/*
 		 * If no bouncing needed for ZONE_DMA, reduce the swiotlb
 		 * buffer for kmalloc() bouncing to 1MB per 1GB of RAM.
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 4c1afab91996..39246ac66ad4 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -287,6 +287,13 @@ void __init arch_mm_preinit(void)
 	BUILD_BUG_ON(MMU_PAGE_COUNT > 16);
 
 #ifdef CONFIG_SWIOTLB
+	if (is_secure_guest()) {
+		/* The host can access DMA buffers only through the SWIOTLB. */
+		swiotlb_mark_default_cc_shared();
+		ppc_swiotlb_enable = 1;
+		ppc_swiotlb_flags |= SWIOTLB_ANY;
+	}
+
 	/*
 	 * Some platforms (e.g. 85xx) limit DMA-able memory way below
 	 * 4G. We force memblock to bottom-up mode to ensure that the
diff --git a/arch/powerpc/platforms/pseries/svm.c b/arch/powerpc/platforms/pseries/svm.c
index 7a403dbd35ee..4a0be631dc6d 100644
--- a/arch/powerpc/platforms/pseries/svm.c
+++ b/arch/powerpc/platforms/pseries/svm.c
@@ -21,16 +21,6 @@ static int __init init_svm(void)
 	if (!is_secure_guest())
 		return 0;
 
-	/* Don't release the SWIOTLB buffer. */
-	ppc_swiotlb_enable = 1;
-
-	/*
-	 * Since the guest memory is inaccessible to the host, devices always
-	 * need to use the SWIOTLB buffer for DMA even if dma_capable() says
-	 * otherwise.
-	 */
-	ppc_swiotlb_flags |= SWIOTLB_ANY;
-
 	/* Share the SWIOTLB buffer with the host. */
 	swiotlb_update_mem_attributes();
 
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 8d1de5a2e554..d88578fa550c 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -163,6 +163,8 @@ static void __init pv_init(void)
 	if (!is_prot_virt_guest())
 		return;
 
+	swiotlb_mark_default_cc_shared();
+
 	virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
 
 	/* make sure bounce buffers are shared */
diff --git a/arch/x86/mm/mem_encrypt.c b/arch/x86/mm/mem_encrypt.c
index 95bae74fdab2..9fa4c97b34e0 100644
--- a/arch/x86/mm/mem_encrypt.c
+++ b/arch/x86/mm/mem_encrypt.c
@@ -101,9 +101,6 @@ void __init mem_encrypt_init(void)
 
 void __init mem_encrypt_setup_arch(void)
 {
-	phys_addr_t total_mem = memblock_phys_mem_size();
-	unsigned long size;
-
 	/*
 	 * Do RMP table fixups after the e820 tables have been setup by
 	 * e820__memory_setup().
@@ -111,30 +108,12 @@ void __init mem_encrypt_setup_arch(void)
 	if (cc_platform_has(CC_ATTR_HOST_SEV_SNP))
 		snp_fixup_e820_tables();
 
+	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
+		swiotlb_mark_default_cc_shared();
+
 	if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
 		return;
 
-	/*
-	 * For SEV and TDX, all DMA has to occur via shared/unencrypted pages.
-	 * Kernel uses SWIOTLB to make this happen without changing device
-	 * drivers. However, depending on the workload being run, the
-	 * default 64MB of SWIOTLB may not be enough and SWIOTLB may
-	 * run out of buffers for DMA, resulting in I/O errors and/or
-	 * performance degradation especially with high I/O workloads.
-	 *
-	 * Adjust the default size of SWIOTLB using a percentage of guest
-	 * memory for SWIOTLB buffers. Also, as the SWIOTLB bounce buffer
-	 * memory is allocated from low memory, ensure that the adjusted size
-	 * is within the limits of low available memory.
-	 *
-	 * The percentage of guest memory used here for SWIOTLB buffers
-	 * is more of an approximation of the static adjustment which
-	 * 64MB for <1G, and ~128M to 256M for 1G-to-4G, i.e., the 6%
-	 */
-	size = total_mem * 6 / 100;
-	size = clamp_val(size, IO_TLB_DEFAULT_SIZE, SZ_1G);
-	swiotlb_adjust_size(size);
-
 	/* Set restricted memory access for virtio. */
 	virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
 }
diff --git a/include/linux/swiotlb.h b/include/linux/swiotlb.h
index 277b9aa2edaa..324859ecb5cd 100644
--- a/include/linux/swiotlb.h
+++ b/include/linux/swiotlb.h
@@ -189,7 +189,8 @@ void swiotlb_dev_init(struct device *dev);
 size_t swiotlb_max_mapping_size(struct device *dev);
 bool is_swiotlb_allocated(void);
 bool is_swiotlb_active(struct device *dev);
-void __init swiotlb_adjust_size(unsigned long size);
+void __init swiotlb_mark_default_cc_shared(void);
+void swiotlb_adjust_size(unsigned long size);
 phys_addr_t default_swiotlb_base(void);
 phys_addr_t default_swiotlb_limit(void);
 #else
@@ -228,6 +229,10 @@ static inline bool is_swiotlb_active(struct device *dev)
 	return false;
 }
 
+static inline void swiotlb_mark_default_cc_shared(void)
+{
+}
+
 static inline void swiotlb_adjust_size(unsigned long size)
 {
 }
diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
index 897aba538c5b..bc67d427f995 100644
--- a/kernel/dma/swiotlb.c
+++ b/kernel/dma/swiotlb.c
@@ -208,7 +208,7 @@ unsigned long swiotlb_size_or_default(void)
 	return default_nslabs << IO_TLB_SHIFT;
 }
 
-void __init swiotlb_adjust_size(unsigned long size)
+void swiotlb_adjust_size(unsigned long size)
 {
 	/*
 	 * If swiotlb parameter has not been specified, give a chance to
@@ -274,24 +274,15 @@ static void swiotlb_mark_pool_used(struct io_tlb_pool *pool)
 void __init swiotlb_update_mem_attributes(void)
 {
 	struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
-	unsigned long bytes;
-
-	/*
-	 * if platform support memory encryption, swiotlb buffers are
-	 * shared by default.
-	 */
-	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
-		io_tlb_default_mem.cc_shared = true;
-	else
-		io_tlb_default_mem.cc_shared = false;
 
 	if (!mem->nslabs || mem->late_alloc)
 		return;
-	bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
 
 	if (io_tlb_default_mem.cc_shared) {
 		int ret;
+		unsigned long bytes;
 
+		bytes = PAGE_ALIGN(mem->nslabs << IO_TLB_SHIFT);
 		ret = set_memory_decrypted((unsigned long)mem->vaddr,
 					   bytes >> PAGE_SHIFT);
 		if (ret) {
@@ -382,6 +373,42 @@ static void __init *swiotlb_memblock_alloc(unsigned long nslabs,
 	return tlb;
 }
 
+void __init swiotlb_mark_default_cc_shared(void)
+{
+	io_tlb_default_mem.cc_shared = true;
+}
+
+static void swiotlb_adjust_cc_attributes(void)
+{
+	unsigned long size;
+	phys_addr_t total_mem = memblock_phys_mem_size();
+
+	/*
+	 * For SEV and TDX and CCA, all DMA has to occur via
+	 * shared/unencrypted pages. Kernel uses SWIOTLB to make this
+	 * happen without changing device drivers. However, depending on
+	 * the workload being run, the default 64MB of SWIOTLB may not be
+	 * enough and SWIOTLB may run out of buffers for DMA, resulting in
+	 * I/O errors and/or performance degradation especially with high
+	 * I/O workloads.
+	 *
+	 * Adjust the default size of SWIOTLB using a percentage of guest
+	 * memory for SWIOTLB buffers. Also, as the SWIOTLB bounce buffer
+	 * memory is allocated from low memory, ensure that the adjusted
+	 * size is within the limits of low available memory.
+	 *
+	 * The percentage of guest memory used here for SWIOTLB buffers is
+	 * more of an approximation of the static adjustment which 64MB for
+	 * <1G, and ~128M to 256M for 1G-to-4G, i.e., the 6%
+	 */
+	size = total_mem * 6 / 100;
+	size = clamp_val(size, IO_TLB_DEFAULT_SIZE, SZ_1G);
+	swiotlb_adjust_size(size);
+
+	if (!IS_ENABLED(CONFIG_SWIOTLB_DYNAMIC))
+		pr_info("Consider enabling CONFIG_SWIOTLB_DYNAMIC for memory-encrypted systems\n");
+}
+
 /*
  * Statically reserve bounce buffer space and initialize bounce buffer data
  * structures for the software IO TLB used to implement the DMA API.
@@ -395,8 +422,14 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
 	size_t alloc_size;
 	void *tlb;
 
-	if (!addressing_limit && !swiotlb_force_bounce)
+	/*
+	 * A shared pool is required for DMA on memory-encrypted systems even
+	 * when all devices are otherwise able to address memory directly.
+	 */
+	if (!addressing_limit && !swiotlb_force_bounce &&
+	    !io_tlb_default_mem.cc_shared)
 		return;
+
 	if (swiotlb_force_disable)
 		return;
 
@@ -411,6 +444,9 @@ void __init swiotlb_init_remap(bool addressing_limit, unsigned int flags,
 		io_tlb_default_mem.phys_limit = ARCH_LOW_ADDRESS_LIMIT;
 #endif
 
+	if (io_tlb_default_mem.cc_shared)
+		swiotlb_adjust_cc_attributes();
+
 	if (!default_nareas)
 		swiotlb_adjust_nareas(num_possible_cpus());
 
@@ -465,7 +501,7 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
 		int (*remap)(void *tlb, unsigned long nslabs))
 {
 	struct io_tlb_pool *mem = &io_tlb_default_mem.defpool;
-	unsigned long nslabs = ALIGN(size >> IO_TLB_SHIFT, IO_TLB_SEGSIZE);
+	unsigned long nslabs;
 	unsigned int order, area_order, slot_order;
 	bool leak_pages = false;
 	unsigned int nareas;
@@ -479,6 +515,15 @@ int swiotlb_init_late(size_t size, gfp_t gfp_mask,
 	if (swiotlb_force_disable)
 		return 0;
 
+	/* Apply the shared-pool default sizing before deriving nslabs. */
+	if (io_tlb_default_mem.cc_shared &&
+	    size == swiotlb_size_or_default()) {
+		swiotlb_adjust_cc_attributes();
+		size = swiotlb_size_or_default();
+	}
+
+	nslabs = ALIGN(size >> IO_TLB_SHIFT, IO_TLB_SEGSIZE);
+
 	io_tlb_default_mem.force_bounce = swiotlb_force_bounce;
 
 #ifdef CONFIG_SWIOTLB_DYNAMIC
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] dma: swiotlb: Size shared default pools for memory encryption
  2026-08-11 13:40 [RFC PATCH] dma: swiotlb: Size shared default pools for memory encryption Aneesh Kumar K.V (Arm)
@ 2026-08-12 10:01 ` Catalin Marinas
  2026-08-12 11:08   ` Aneesh Kumar K.V
  2026-08-12 11:31   ` Aneesh Kumar K.V
  0 siblings, 2 replies; 4+ messages in thread
From: Catalin Marinas @ 2026-08-12 10:01 UTC (permalink / raw)
  To: Aneesh Kumar K.V (Arm)
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
	Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
	Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
	Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
	linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86

On Tue, Aug 11, 2026 at 07:10:56PM +0530, Aneesh Kumar K.V (Arm) wrote:
> Systems with memory encryption use swiotlb to provide shared or
> unencrypted buffers for device DMA. Confidential guests may route all
> DMA through these buffers, while SME hosts use them for devices that
> cannot address encrypted memory. The default swiotlb pool can therefore
> be exhausted under I/O-intensive workloads.
> 
> Let architectures mark the default swiotlb pool as shared before
> swiotlb_init().

I thought we wanted even this decision to be moved out of the arch code.

> Move the existing x86 sizing policy into generic swiotlb
> code and add early pool marking for arm64 Realm guests, powerpc secure
> guests, s390 protected-virtualization guests, and x86 memory-encryption
> platforms. Use CC_ATTR_MEM_ENCRYPT on x86 to include host SME, whose
> swiotlb pool must also be decrypted for devices that cannot address
> encrypted memory.

That's a functional change for x86. For now, I'd keep it to
CC_ATTR_GUEST_MEM_ENCRYPT.

BTW, why does arm64 report CC_ATTR_MEM_ENCRYPT instead of the GUEST
option in realms?

> Move the powerpc secure-guest swiotlb enablement before initialization
> so that the shared pool is allocated with the required flags. pKVM
> guests continue to use a restricted DMA pool instead of the default
> swiotlb pool.
> 
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
>  arch/arm64/mm/init.c                 |  6 ++-
>  arch/powerpc/mm/mem.c                |  7 +++
>  arch/powerpc/platforms/pseries/svm.c | 10 ----
>  arch/s390/mm/init.c                  |  2 +
>  arch/x86/mm/mem_encrypt.c            | 27 ++--------
>  include/linux/swiotlb.h              |  7 ++-
>  kernel/dma/swiotlb.c                 | 73 ++++++++++++++++++++++------
>  7 files changed, 82 insertions(+), 50 deletions(-)
> 
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index e308a7cabd12..4c022e8aed43 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -338,8 +338,12 @@ void __init arch_setup_zero_pages(void)
>  void __init arch_mm_preinit(void)
>  {
>  	unsigned int flags = SWIOTLB_VERBOSE;
> +	/* pKVM uses restricted-dma-pool */
> +	bool cc_guest = is_realm_world();
>  
> -	if (max_pfn <= PFN_DOWN(arm64_dma_phys_limit)) {
> +	if (cc_guest) {
> +		swiotlb_mark_default_cc_shared();
> +	} else if (max_pfn <= PFN_DOWN(arm64_dma_phys_limit)) {
>  		/*
>  		 * If no bouncing needed for ZONE_DMA, reduce the swiotlb
>  		 * buffer for kmalloc() bouncing to 1MB per 1GB of RAM.

With your other reworking, doesn't the core code know the swiotlb will
be shared? Can it not make the decision to resize at that point based
solely on CC_ATTR_GUEST_MEM_ENCRYPT?

I also wonder whether we could address Will's pKVM request not to
allocate a bounce buffer once pKVM guests will start reporting
CC_ATTR_GUEST_MEM_ENCRYPT. Some simple heuristic: if a
restricted-dma-pool is advertised in DT (it will end up in
rmem_swiotlb_setup()), skip resizing the default swiotlb. It's not
perfect but the bounce buffer can be overridden on the command line.

-- 
Catalin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] dma: swiotlb: Size shared default pools for memory encryption
  2026-08-12 10:01 ` Catalin Marinas
@ 2026-08-12 11:08   ` Aneesh Kumar K.V
  2026-08-12 11:31   ` Aneesh Kumar K.V
  1 sibling, 0 replies; 4+ messages in thread
From: Aneesh Kumar K.V @ 2026-08-12 11:08 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
	Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
	Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
	Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
	linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86

Catalin Marinas <catalin.marinas@arm.com> writes:

> On Tue, Aug 11, 2026 at 07:10:56PM +0530, Aneesh Kumar K.V (Arm) wrote:
>> Systems with memory encryption use swiotlb to provide shared or
>> unencrypted buffers for device DMA. Confidential guests may route all
>> DMA through these buffers, while SME hosts use them for devices that
>> cannot address encrypted memory. The default swiotlb pool can therefore
>> be exhausted under I/O-intensive workloads.
>> 
>> Let architectures mark the default swiotlb pool as shared before
>> swiotlb_init().
>
> I thought we wanted even this decision to be moved out of the arch code.
>

Architectures may want to use an unencrypted swiotlb pool for different
reasons, one of them being CC_ATTR_GUEST_MEM_ENCRYPT. x86 hosts also
require unencrypted pool to support SME. We can cover both cases using
CC_ATTR_MEM_ENCRYPT. However, pKVM does not want an unencrypted SWIOTLB
pool. So I was thinking it would be much cleaner to let the architecture
code drive that decision.

>
>> Move the existing x86 sizing policy into generic swiotlb
>> code and add early pool marking for arm64 Realm guests, powerpc secure
>> guests, s390 protected-virtualization guests, and x86 memory-encryption
>> platforms. Use CC_ATTR_MEM_ENCRYPT on x86 to include host SME, whose
>> swiotlb pool must also be decrypted for devices that cannot address
>> encrypted memory.
>
> That's a functional change for x86. For now, I'd keep it to
> CC_ATTR_GUEST_MEM_ENCRYPT.
>
> BTW, why does arm64 report CC_ATTR_MEM_ENCRYPT instead of the GUEST
> option in realms?
>
>> Move the powerpc secure-guest swiotlb enablement before initialization
>> so that the shared pool is allocated with the required flags. pKVM
>> guests continue to use a restricted DMA pool instead of the default
>> swiotlb pool.
>> 
>> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
>> ---
>>  arch/arm64/mm/init.c                 |  6 ++-
>>  arch/powerpc/mm/mem.c                |  7 +++
>>  arch/powerpc/platforms/pseries/svm.c | 10 ----
>>  arch/s390/mm/init.c                  |  2 +
>>  arch/x86/mm/mem_encrypt.c            | 27 ++--------
>>  include/linux/swiotlb.h              |  7 ++-
>>  kernel/dma/swiotlb.c                 | 73 ++++++++++++++++++++++------
>>  7 files changed, 82 insertions(+), 50 deletions(-)
>> 
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index e308a7cabd12..4c022e8aed43 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -338,8 +338,12 @@ void __init arch_setup_zero_pages(void)
>>  void __init arch_mm_preinit(void)
>>  {
>>  	unsigned int flags = SWIOTLB_VERBOSE;
>> +	/* pKVM uses restricted-dma-pool */
>> +	bool cc_guest = is_realm_world();
>>  
>> -	if (max_pfn <= PFN_DOWN(arm64_dma_phys_limit)) {
>> +	if (cc_guest) {
>> +		swiotlb_mark_default_cc_shared();
>> +	} else if (max_pfn <= PFN_DOWN(arm64_dma_phys_limit)) {
>>  		/*
>>  		 * If no bouncing needed for ZONE_DMA, reduce the swiotlb
>>  		 * buffer for kmalloc() bouncing to 1MB per 1GB of RAM.
>
> With your other reworking, doesn't the core code know the swiotlb will
> be shared? Can it not make the decision to resize at that point based
> solely on CC_ATTR_GUEST_MEM_ENCRYPT?
>
> I also wonder whether we could address Will's pKVM request not to
> allocate a bounce buffer once pKVM guests will start reporting
> CC_ATTR_GUEST_MEM_ENCRYPT. Some simple heuristic: if a
> restricted-dma-pool is advertised in DT (it will end up in
> rmem_swiotlb_setup()), skip resizing the default swiotlb. It's not
> perfect but the bounce buffer can be overridden on the command line.
>

For the same reason I mentioned above, architectures may have different
reasons for setting cc_shared = true. IMHO, it is cleaner to let the
architecture code make that decision before swiotlb_init().

-aneesh

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC PATCH] dma: swiotlb: Size shared default pools for memory encryption
  2026-08-12 10:01 ` Catalin Marinas
  2026-08-12 11:08   ` Aneesh Kumar K.V
@ 2026-08-12 11:31   ` Aneesh Kumar K.V
  1 sibling, 0 replies; 4+ messages in thread
From: Aneesh Kumar K.V @ 2026-08-12 11:31 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
	Marek Szyprowski, Will Deacon, Marc Zyngier, Steven Price,
	Suzuki K Poulose, Jiri Pirko, Jason Gunthorpe, Mostafa Saleh,
	Petr Tesarik, Alexey Kardashevskiy, Dan Williams, Xu Yilun,
	linuxppc-dev, linux-s390, Madhavan Srinivasan, Michael Ellerman,
	Nicholas Piggin, Christophe Leroy, Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86

Catalin Marinas <catalin.marinas@arm.com> writes:

>
> I also wonder whether we could address Will's pKVM request not to
> allocate a bounce buffer once pKVM guests will start reporting
> CC_ATTR_GUEST_MEM_ENCRYPT. Some simple heuristic: if a
> restricted-dma-pool is advertised in DT (it will end up in
> rmem_swiotlb_setup()), skip resizing the default swiotlb. It's not
> perfect but the bounce buffer can be overridden on the command line.

I have a follow-up cleanup patch where I switch the swiotlb
initialization reason to a flag value. With that, we now have
SWIOTLB_INIT_CC_SHARED.

The challenge is that it is still not clear when pKVM would want to use
an unencrypted swiotlb pool for DMA bouncing. I would expect pKVM to
have some additional condition based on which it chooses either the
restricted-dma-pool or the default swiotlb pool.

Using the presence of a restricted-dma-pool to decide whether the
default swiotlb pool should be unencrypted is one option, but I am not
sure that is the right abstraction.

modified   arch/arm64/mm/init.c
@@ -342,7 +342,7 @@ void __init arch_mm_preinit(void)
 	bool cc_guest = is_realm_world();
 
 	if (cc_guest)
-		swiotlb_mark_default_cc_shared();
+		flags |= SWIOTLB_INIT_CC_SHARED;
 	else if (max_pfn > PFN_DOWN(arm64_dma_phys_limit))
 		flags |= SWIOTLB_INIT_ADDRESSING_LIMIT;
 
modified   arch/powerpc/mm/mem.c
@@ -289,9 +289,8 @@ void __init arch_mm_preinit(void)
 #ifdef CONFIG_SWIOTLB
 	if (is_secure_guest()) {
 		/* The host can access DMA buffers only through the SWIOTLB. */
-		swiotlb_mark_default_cc_shared();
 		ppc_swiotlb_enable = 1;
-		ppc_swiotlb_flags |= SWIOTLB_ANY;
+		ppc_swiotlb_flags |= SWIOTLB_INIT_CC_SHARED | SWIOTLB_ANY;
 	}
 
 	/*
modified   arch/s390/mm/init.c
@@ -163,12 +163,10 @@ static void __init pv_init(void)
 	if (!is_prot_virt_guest())
 		return;
 
-	swiotlb_mark_default_cc_shared();
-
 	virtio_set_mem_acc_cb(virtio_require_restricted_mem_acc);
 
 	/* make sure bounce buffers are shared */
-	swiotlb_init(SWIOTLB_VERBOSE);
+	swiotlb_init(SWIOTLB_VERBOSE | SWIOTLB_INIT_CC_SHARED);
 	swiotlb_update_mem_attributes();
 }
 
modified   arch/x86/mm/mem_encrypt.c
@@ -14,6 +14,7 @@
 #include <linux/mem_encrypt.h>
 #include <linux/virtio_anchor.h>
 
+#include <asm/iommu.h>
 #include <asm/sev.h>
 
 /* Override for DMA direct allocation check - ARCH_HAS_FORCE_DMA_UNENCRYPTED */
@@ -109,7 +110,7 @@ void __init mem_encrypt_setup_arch(void)
 		snp_fixup_e820_tables();
 
 	if (cc_platform_has(CC_ATTR_MEM_ENCRYPT))
-		swiotlb_mark_default_cc_shared();
+		x86_swiotlb_flags |= SWIOTLB_INIT_CC_SHARED;
 
 	if (!cc_platform_has(CC_ATTR_GUEST_MEM_ENCRYPT))
 		return;
modified   include/linux/swiotlb.h
@@ -18,6 +18,8 @@ struct scatterlist;
 #define SWIOTLB_ANY	(1 << 1) /* allow any memory for the buffer */
 /* Initialize a default-sized pool for devices with limited DMA addressing. */
 #define SWIOTLB_INIT_ADDRESSING_LIMIT	(1 << 2)
+/* Initialize a shared default pool for confidential-computing systems. */
+#define SWIOTLB_INIT_CC_SHARED		(1 << 3)
 
 /*
  * Maximum allowable number of contiguous slabs to map,
@@ -191,7 +193,6 @@ void swiotlb_dev_init(struct device *dev);
 size_t swiotlb_max_mapping_size(struct device *dev);
 bool is_swiotlb_allocated(void);
 bool is_swiotlb_active(struct device *dev);
-void __init swiotlb_mark_default_cc_shared(void);
 void __init swiotlb_adjust_size(unsigned long size);
 phys_addr_t default_swiotlb_base(void);
 phys_addr_t default_swiotlb_limit(void);
@@ -231,10 +232,6 @@ static inline bool is_swiotlb_active(struct device *dev)
 	return false;
 }
 
-static inline void swiotlb_mark_default_cc_shared(void)
-{
-}
-
 static inline void swiotlb_adjust_size(unsigned long size)
 {
 }
modified   kernel/dma/swiotlb.c
@@ -373,11 +373,6 @@ static void __init *swiotlb_memblock_alloc(unsigned long nslabs,
 	return tlb;
 }
 
-void __init swiotlb_mark_default_cc_shared(void)
-{
-	io_tlb_default_mem.cc_shared = true;
-}
-
 static void __init swiotlb_adjust_cc_attributes(void)
 {
 	unsigned long size;
@@ -429,7 +424,7 @@ static bool __init swiotlb_should_init(unsigned int flags)
 	if (swiotlb_force_bounce)
 		return true;
 
-	if (io_tlb_default_mem.cc_shared)
+	if (flags & SWIOTLB_INIT_CC_SHARED)
 		return true;
 
 	return false;
@@ -451,6 +446,9 @@ void __init swiotlb_init_remap(unsigned int flags,
 	if (!swiotlb_should_init(flags))
 		return;
 
+	if (flags & SWIOTLB_INIT_CC_SHARED)
+		io_tlb_default_mem.cc_shared = true;
+
 	io_tlb_default_mem.force_bounce = swiotlb_force_bounce;
 
 #ifdef CONFIG_SWIOTLB_DYNAMIC

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-08-12 11:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 13:40 [RFC PATCH] dma: swiotlb: Size shared default pools for memory encryption Aneesh Kumar K.V (Arm)
2026-08-12 10:01 ` Catalin Marinas
2026-08-12 11:08   ` Aneesh Kumar K.V
2026-08-12 11:31   ` Aneesh Kumar K.V

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox