Linux Confidential Computing Development
 help / color / mirror / Atom feed
* Re: [PATCH v10 2/6] x86/sev: Initialize RMPOPT configuration MSRs
From: Kalra, Ashish @ 2026-07-20 22:38 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: tglx, mingo, dave.hansen, x86, hpa, seanjc, peterz,
	thomas.lendacky, herbert, davem, ardb, pbonzini, aik,
	Michael.Roth, KPrateek.Nayak, Tycho.Andersen, Nathan.Fontenot,
	ackerleytng, jackyli, pgonda, rientjes, jacobhxu, xin,
	pawan.kumar.gupta, babu.moger, dyoung, nikunj, john.allen, darwi,
	linux-kernel, linux-crypto, kvm, linux-coco
In-Reply-To: <20260720221725.GDal6edYI3uHrDruHj@fat_crate.local>

Hello Boris,

On 7/20/2026 5:17 PM, Borislav Petkov wrote:
> On Tue, Jun 30, 2026 at 06:10:13PM +0000, Ashish Kalra wrote:
>> @@ -490,6 +494,11 @@ static bool __init setup_rmptable(void)
>>  	if (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) {
>>  		if (!setup_segmented_rmptable())
>>  			return false;
>> +		/*
>> +		 * RMPOPT requires a segmented RMP, so indicate that the
>> +		 * system is capable of configuring and running RMPOPT.
>> +		 */
>> +		rmpopt_capable = true;
> 
> So we're capable of doing RMPOPT when setup_segmented_rmptable() has
> succeeded. Which means, when rmp_segment_table is not NULL, i.e., when we have
> a segmented table.
> 
> Which means that instead of testing rmpopt_capable, you need to test
> CC_ATTR_HOST_SEV_SNP and rmp_segment_table != NULL and you can put that in
> a helper local to arch/x86/virt/svm/sev.c
> 
> Which means, you don't need that bool.
> 

Agreed on dropping the bool — I'll derive it in a local helper.

One issue though: rmp_segment_table != NULL isn't segmented-only. setup_contiguous_rmptable() also allocates rmp_segment_table
(the contiguous RMP is stored as a single segment in the same table), so it's non-NULL for the contiguous case too.

To keep it segmented-only, I'll also need to gate on the segmented-RMP mode, something like: 

  static bool rmpopt_capable(void)
  {
        return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
               cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
               (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) &&
               rmp_segment_table;
  }

The CC_ATTR_HOST_SEV_SNP check also handles SNP being disabled at runtime, so snp_clear_rmpopt_capable() and its caller go away as well.

Thanks,
Ashish

^ permalink raw reply

* Re: [PATCH v10 2/6] x86/sev: Initialize RMPOPT configuration MSRs
From: Borislav Petkov @ 2026-07-21  1:48 UTC (permalink / raw)
  To: Kalra, Ashish
  Cc: tglx, mingo, dave.hansen, x86, hpa, seanjc, peterz,
	thomas.lendacky, herbert, davem, ardb, pbonzini, aik,
	Michael.Roth, KPrateek.Nayak, Tycho.Andersen, Nathan.Fontenot,
	ackerleytng, jackyli, pgonda, rientjes, jacobhxu, xin,
	pawan.kumar.gupta, babu.moger, dyoung, nikunj, john.allen, darwi,
	linux-kernel, linux-crypto, kvm, linux-coco
In-Reply-To: <5168d3d3-c31c-4f80-be91-c964a5cee674@amd.com>

On Mon, Jul 20, 2026 at 05:38:05PM -0500, Kalra, Ashish wrote:
> Agreed on dropping the bool — I'll derive it in a local helper.
> 
> One issue though: rmp_segment_table != NULL isn't segmented-only. setup_contiguous_rmptable() also allocates rmp_segment_table
> (the contiguous RMP is stored as a single segment in the same table), so it's non-NULL for the contiguous case too.
> 
> To keep it segmented-only, I'll also need to gate on the segmented-RMP mode, something like: 
> 
>   static bool rmpopt_capable(void)
>   {
>         return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
>                cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
>                (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) &&
>                rmp_segment_table;
>   }
> 
> The CC_ATTR_HOST_SEV_SNP check also handles SNP being disabled at runtime, so snp_clear_rmpopt_capable() and its caller go away as well.

Ok, you can simply do:

	setup_clear_cpu_cap(X86_FEATURE_RMPOPT)

and clear our internal representation of RMPOPT support and make it a lot
simpler.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply

* Re: [PATCH v2 2/2] virt: tdx-guest: Allocate Quote buffer dynamically
From: Peter Fang @ 2026-07-21  6:49 UTC (permalink / raw)
  To: Dave Hansen
  Cc: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
	Kuppuswamy Sathyanarayanan, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, x86, H. Peter Anvin, linux-kernel, linux-coco,
	kvm, Xiaoyao Li, Binbin Wu
In-Reply-To: <51059852-9a10-4735-a81d-003b4b1963a6@intel.com>

On Mon, Jul 20, 2026 at 06:35:29AM -0700, Dave Hansen wrote:
> On 7/17/26 14:43, Peter Fang wrote:
> > From: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
> > 
> > The TDX attestation driver currently uses a fixed 128 KB Quote buffer
> > shared with the host VMM. This may be too small for Quotes using schemes
> > such as post-quantum cryptography (PQC), where larger certificate chains
> > can increase the Quote size significantly.
> > 
> > Allocate the Quote buffer based on the size reported by the TDX module
> > instead of always reserving a fixed-size buffer. This avoids wasting
> > memory on platforms that do not require larger Quotes. Older platforms
> > fall back to the default 128 KB buffer.
> > 
> > Because the Quote buffer must be physically contiguous, its size is
> > bound by the buddy allocator's maximum page order (4 MB), which should
> > be sufficient for current attestation needs.
> 
> This is all talking about post-quantum-crypto and all that fancy stuff.
> 
> Isn't the important part here that the old TDX module ABI had static
> quote sizes and now they're dynamic? Now, the reason it changed is all
> the fancy stuff.
> 
> But the ABI changed. Right?

Ah yes... I should call out that the size of
/sys/kernel/config/tsm/report/$name/outblob will no longer be fixed.
I'll update this. Thanks.

> 
> > -static void *alloc_quote_buf(void)
> > +static size_t get_quote_buf_size(void)
> >  {
> > -	size_t len = PAGE_ALIGN(GET_QUOTE_BUF_SIZE);
> > -	unsigned int count = len >> PAGE_SHIFT;
> > +	size_t buf_size = GET_QUOTE_DEFAULT_BUF_SIZE;
> > +	u32 quote_size;
> > +
> > +	quote_size = tdx_get_max_quote_size();
> > +
> > +	if (quote_size)
> > +		/* Reported size does not include GetQuote header */
> > +		buf_size = TDX_QUOTE_BUF_LEN(quote_size);
> > +
> > +	return PAGE_ALIGN(buf_size);
> > +}
> 
> This code is almost nonsensical on the surface.
> 
> It _really_ needs some commenting. Things like:
> 
> 	/* Start with the default quote buffer size: */
> 
> ...
> 
> 	/* Override the default when ... */
> 
> 
> You could even comment the function to say what it is trying to do overall.

Got it. I'll improve this pattern and add more comments.

> 
> > +static void *alloc_quote_buf(size_t *buflen)
> > +{
> > +	unsigned int count;
> > +	size_t len;
> >  	void *addr;
> >  
> > -	addr = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO);
> > +	len = get_quote_buf_size();
> > +
> > +	/*
> > +	 * This fails if the requested size exceeds the buddy allocator's
> > +	 * maximum order. Use __GFP_NOWARN since the size comes from the host
> > +	 * and should fail quietly rather than warn.
> > +	 */
> > +	addr = alloc_pages_exact(len, GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN);
> 
> Bad Sashiko. Bad.
> 
> The host may be untrusted, but it's also a critical part of the system.
> Are we sure we want to be completely quiet?
> 
> I used to see little dmesg warnings about TCP window shenanigans from
> random systems on the Internet. Maybe that's not how we do things today,
> but if a random dude on the Internet can spew one line to dmesg, is it
> that crazy that a bad VMM be able to spew a warning?

That makes sense... I actually argued with AI about this but it kept
saying this is kind of like DoSing the guest. But thinking about it
more, tainting the guest is probably the right thing to do... At least
the guest sees a big splat about why attestation is failing. I'll remove
the __GFP_NOWARN. Thanks.

> 
> >  	if (!addr)
> >  		return NULL;
> >  
> > +	count = len >> PAGE_SHIFT;
> > +
> >  	if (set_memory_decrypted((unsigned long)addr, count))
> >  		return NULL;
> >  
> > +	*buflen = len;
> > +
> >  	return addr;
> >  }
> 
> This feels weird to me.
> 
> If the upper-layer function needs to know the size, why not have it just
> call get_quote_buf_size()? Then there's no pass-by-address.

Got it. I'll fix this.

> 

[ ... ]

> 
> So, yeah, this patch isn't gigantic. But it's also fundamentally not
> doing a _nice_ refactoring the way we expect them to be done.
> 
> 1. Refactor old code to make it nice for adding features
> 2. Add the feature
> 
> If this was doing it the nice way, we would *actually* have something
> that's really close to s/GET_QUOTE_BUF_SIZE/quote_data_len/. But,
> instead, this chose to cram the mechanical changes and the new feature
> together.
> 
> Can we do it the right way, please? If for nothing else, for practice.

Yes I'll separate out the refactoring so that the dynamic buffer thing
is on its own. Thanks for the feedback.


^ permalink raw reply

* Re: [PATCH v8 01/23] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Leon Romanovsky @ 2026-07-21 11:54 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, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley,
	Jason Gunthorpe
In-Reply-To: <20260717180442.110954-2-aneesh.kumar@kernel.org>

On Fri, Jul 17, 2026 at 11:34:19PM +0530, Aneesh Kumar K.V (Arm) wrote:
> Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool
> helper") changed dma_direct_alloc_from_pool() to return the CPU address
> from dma_alloc_from_pool(). That fits dma_direct_alloc(), but
> dma_direct_alloc_pages() also uses the helper and expects a struct page *.
> 
> Fix this by making dma_direct_alloc_from_pool() return the struct page *
> again, and pass the CPU address back through an out-parameter for the
> dma_direct_alloc() caller.
> 
> Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper")
> Cc: stable@vger.kernel.org
> Tested-by: Michael Kelley <mhklinux@outlook.com>
> Tested-by: Mostafa Saleh <smostafa@google.com>
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
>  kernel/dma/direct.c | 18 ++++++++++--------
>  1 file changed, 10 insertions(+), 8 deletions(-)
> 
> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> index d8219efe3273..363d984d90e7 100644
> --- a/kernel/dma/direct.c
> +++ b/kernel/dma/direct.c
> @@ -164,22 +164,21 @@ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp)
>  	return !gfpflags_allow_blocking(gfp) && !is_swiotlb_for_alloc(dev);
>  }
>  
> -static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> -		dma_addr_t *dma_handle, gfp_t gfp)
> +static struct page *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> +		dma_addr_t *dma_handle, void **cpu_addr, gfp_t gfp)
>  {
>  	struct page *page;
>  	u64 phys_limit;
> -	void *ret;
>  
>  	if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_DMA_COHERENT_POOL)))
>  		return NULL;
>  
>  	gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
> -	page = dma_alloc_from_pool(dev, size, &ret, gfp, dma_coherent_ok);
> +	page = dma_alloc_from_pool(dev, size, cpu_addr, gfp, dma_coherent_ok);
>  	if (!page)
>  		return NULL;
>  	*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
> -	return ret;
> +	return page;
>  }
>  
>  static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
> @@ -247,8 +246,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>  	 * the atomic pools instead if we aren't allowed block.
>  	 */
>  	if ((remap || force_dma_unencrypted(dev)) &&
> -	    dma_direct_use_pool(dev, gfp))
> -		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
> +	    dma_direct_use_pool(dev, gfp)) {
> +		page = dma_direct_alloc_from_pool(dev, size, dma_handle,
> +						  &ret, gfp);
> +		return page ? ret : NULL;

Sorry for joining the discussion late, but the line above caught my
attention.

Why do we need both ret and page? We can derive cpu_addr from page and
vice versa. Do we really need the &ret parameter? Or, more generally, do
we really need "struct page *"?

static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
		struct gen_pool *pool, void **cpu_addr,
		bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
{
...
	*cpu_addr = (void *)addr;
	memset(*cpu_addr, 0, size);
	return pfn_to_page(__phys_to_pfn(phys));
}

Why 

> +	}
>  
>  	/* we always manually zero the memory once we are done */
>  	page = __dma_direct_alloc_pages(dev, size, gfp & ~__GFP_ZERO, true);
> @@ -357,7 +359,7 @@ struct page *dma_direct_alloc_pages(struct device *dev, size_t size,
>  	void *ret;
>  
>  	if (force_dma_unencrypted(dev) && dma_direct_use_pool(dev, gfp))
> -		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
> +		return dma_direct_alloc_from_pool(dev, size, dma_handle, &ret, gfp);
>  
>  	page = __dma_direct_alloc_pages(dev, size, gfp, false);
>  	if (!page)
> -- 
> 2.43.0
> 
> 

^ permalink raw reply

* Re: [PATCH v8 02/23] dma-pool: fix page leak in atomic_pool_expand() cleanup
From: Leon Romanovsky @ 2026-07-21 12:31 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, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, Jason Gunthorpe,
	Michael Kelley
In-Reply-To: <20260717180442.110954-3-aneesh.kumar@kernel.org>

On Fri, Jul 17, 2026 at 11:34:20PM +0530, Aneesh Kumar K.V (Arm) wrote:
> atomic_pool_expand() frees the allocated pages from the remove_mapping
> error path only when CONFIG_DMA_DIRECT_REMAP is enabled.
> 
> When CONFIG_DMA_DIRECT_REMAP is disabled, failures after page allocation,
> such as gen_pool_add_virt(), jump to remove_mapping and return without
> freeing the pages.
> 
> Move __free_pages(page, order) out of the CONFIG_DMA_DIRECT_REMAP block so
> that cleanup paths always release the allocation.
> 
> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> 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/pool.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
> index 2b2fbb709242..b0303efbc153 100644
> --- a/kernel/dma/pool.c
> +++ b/kernel/dma/pool.c
> @@ -81,6 +81,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
>  {
>  	unsigned int order;
>  	struct page *page = NULL;
> +	bool leak_pages = false;
>  	void *addr;
>  	int ret = -ENOMEM;
>  
> @@ -115,8 +116,10 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
>  	 */
>  	ret = set_memory_decrypted((unsigned long)page_to_virt(page),
>  				   1 << order);
> -	if (ret)
> +	if (ret) {
> +		leak_pages = true;
>  		goto remove_mapping;
> +	}
>  	ret = gen_pool_add_virt(pool, (unsigned long)addr, page_to_phys(page),
>  				pool_size, NUMA_NO_NODE);
>  	if (ret)
> @@ -130,14 +133,15 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
>  				   1 << order);
>  	if (WARN_ON_ONCE(ret)) {
>  		/* Decrypt succeeded but encrypt failed, purposely leak */
> -		goto out;
> +		leak_pages = true;

Instead of doing this dance with temporal variable, change "goto out" to
be "return true".

>  	}
>  remove_mapping:
>  #ifdef CONFIG_DMA_DIRECT_REMAP
>  	dma_common_free_remap(addr, pool_size);
>  free_page:

Remove free_page label, and change leftover of "goto free_page" to be
"goto out"

> -	__free_pages(page, order);
>  #endif
> +	if (!leak_pages)
> +		__free_pages(page, order);

Put these checks under out label and rely on page != NULL as a marker.
if (page)
 __free_pages(page, order);

>  out:
>  	return ret;
>  }
> -- 
> 2.43.0
> 
> 

^ permalink raw reply

* Re: [PATCH v8 00/23] dma-mapping: Track shared DMA state through direct, pool and swiotlb paths
From: Leon Romanovsky @ 2026-07-21 12:40 UTC (permalink / raw)
  To: Aneesh Kumar K.V (Arm), Marek Szyprowski
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, Robin Murphy,
	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 (CS GROUP), Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86
In-Reply-To: <20260717180442.110954-1-aneesh.kumar@kernel.org>

On Fri, Jul 17, 2026 at 11:34:18PM +0530, Aneesh Kumar K.V (Arm) wrote:
> This series tracks confidential-computing shared DMA state through the
> dma-direct, dma-pool, and swiotlb paths so that encrypted and decrypted
> DMA buffers are handled consistently.

<...>

> - makes dma_direct_map_phys() choose the DMA address encoding from
>   DMA_ATTR_CC_SHARED and fall back to swiotlb when a shared DMA request
>   cannot use the direct mapping, which lets arm64 and x86 CCA guests stop
>   relying on SWIOTLB_FORCE for DMA mappings

Why don't we continue the effort to remove "struct page" entirely
from the DMA API internals?

IMHO, everything not exposed to DMA API users should use
phys_addr_t, including the DMA address pool.

Thanks

^ permalink raw reply

* Re: [PATCH v2 2/2] virt: tdx-guest: Allocate Quote buffer dynamically
From: Dave Hansen @ 2026-07-21 13:48 UTC (permalink / raw)
  To: Peter Fang
  Cc: Dave Hansen, Kiryl Shutsemau, Rick Edgecombe,
	Kuppuswamy Sathyanarayanan, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, x86, H. Peter Anvin, linux-kernel, linux-coco,
	kvm, Xiaoyao Li, Binbin Wu
In-Reply-To: <20260721064907.GG3178326@pedri>

On 7/20/26 23:49, Peter Fang wrote:
...
>> This is all talking about post-quantum-crypto and all that fancy stuff.
>>
>> Isn't the important part here that the old TDX module ABI had static
>> quote sizes and now they're dynamic? Now, the reason it changed is all
>> the fancy stuff.
>>
>> But the ABI changed. Right?
> 
> Ah yes... I should call out that the size of
> /sys/kernel/config/tsm/report/$name/outblob will no longer be fixed.
> I'll update this. Thanks.

No. I mean the TDX Module ABI changed.

That's why we need new kernel patches.
>> The host may be untrusted, but it's also a critical part of the system.
>> Are we sure we want to be completely quiet?
>>
>> I used to see little dmesg warnings about TCP window shenanigans from
>> random systems on the Internet. Maybe that's not how we do things today,
>> but if a random dude on the Internet can spew one line to dmesg, is it
>> that crazy that a bad VMM be able to spew a warning?
> 
> That makes sense... I actually argued with AI about this but it kept
> saying this is kind of like DoSing the guest. But thinking about it
> more, tainting the guest is probably the right thing to do... At least
> the guest sees a big splat about why attestation is failing. I'll remove
> the __GFP_NOWARN. Thanks.

This does seem like the kind of high-level TDX policy that we all need
to be aligned on and probably document somewhere. The basic question is
whether a TDX guest should be quiet or verbose in the face of host
malfunction or malfeasance.

Kirill and Rick, what do you think?

^ permalink raw reply

* Re: [PATCH v8 01/23] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Aneesh Kumar K.V @ 2026-07-21 14:20 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley,
	Jason Gunthorpe
In-Reply-To: <20260721115456.GI110966@unreal>

Leon Romanovsky <leon@kernel.org> writes:

> On Fri, Jul 17, 2026 at 11:34:19PM +0530, Aneesh Kumar K.V (Arm) wrote:
>> Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool
>> helper") changed dma_direct_alloc_from_pool() to return the CPU address
>> from dma_alloc_from_pool(). That fits dma_direct_alloc(), but
>> dma_direct_alloc_pages() also uses the helper and expects a struct page *.
>> 
>> Fix this by making dma_direct_alloc_from_pool() return the struct page *
>> again, and pass the CPU address back through an out-parameter for the
>> dma_direct_alloc() caller.
>> 
>> Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper")
>> Cc: stable@vger.kernel.org
>> Tested-by: Michael Kelley <mhklinux@outlook.com>
>> Tested-by: Mostafa Saleh <smostafa@google.com>
>> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
>> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
>> ---
>>  kernel/dma/direct.c | 18 ++++++++++--------
>>  1 file changed, 10 insertions(+), 8 deletions(-)
>> 
>> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
>> index d8219efe3273..363d984d90e7 100644
>> --- a/kernel/dma/direct.c
>> +++ b/kernel/dma/direct.c
>> @@ -164,22 +164,21 @@ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp)
>>  	return !gfpflags_allow_blocking(gfp) && !is_swiotlb_for_alloc(dev);
>>  }
>>  
>> -static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,
>> -		dma_addr_t *dma_handle, gfp_t gfp)
>> +static struct page *dma_direct_alloc_from_pool(struct device *dev, size_t size,
>> +		dma_addr_t *dma_handle, void **cpu_addr, gfp_t gfp)
>>  {
>>  	struct page *page;
>>  	u64 phys_limit;
>> -	void *ret;
>>  
>>  	if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_DMA_COHERENT_POOL)))
>>  		return NULL;
>>  
>>  	gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
>> -	page = dma_alloc_from_pool(dev, size, &ret, gfp, dma_coherent_ok);
>> +	page = dma_alloc_from_pool(dev, size, cpu_addr, gfp, dma_coherent_ok);
>>  	if (!page)
>>  		return NULL;
>>  	*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
>> -	return ret;
>> +	return page;
>>  }
>>  
>>  static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
>> @@ -247,8 +246,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>>  	 * the atomic pools instead if we aren't allowed block.
>>  	 */
>>  	if ((remap || force_dma_unencrypted(dev)) &&
>> -	    dma_direct_use_pool(dev, gfp))
>> -		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
>> +	    dma_direct_use_pool(dev, gfp)) {
>> +		page = dma_direct_alloc_from_pool(dev, size, dma_handle,
>> +						  &ret, gfp);
>> +		return page ? ret : NULL;
>
> Sorry for joining the discussion late, but the line above caught my
> attention.
>
> Why do we need both ret and page? We can derive cpu_addr from page and
> vice versa. Do we really need the &ret parameter? Or, more generally, do
> we really need "struct page *"?
>
> static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
> 		struct gen_pool *pool, void **cpu_addr,
> 		bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
> {
> ...
> 	*cpu_addr = (void *)addr;
> 	memset(*cpu_addr, 0, size);
> 	return pfn_to_page(__phys_to_pfn(phys));
> }
>
> Why
>

With CONFIG_DMA_DIRECT_REMAP the cpu_addr can be different from
page_address.

-aneesh

^ permalink raw reply

* Re: [PATCH v10 2/6] x86/sev: Initialize RMPOPT configuration MSRs
From: Kalra, Ashish @ 2026-07-21 14:26 UTC (permalink / raw)
  To: Borislav Petkov
  Cc: tglx, mingo, dave.hansen, x86, hpa, seanjc, peterz,
	thomas.lendacky, herbert, davem, ardb, pbonzini, aik,
	Michael.Roth, KPrateek.Nayak, Tycho.Andersen, Nathan.Fontenot,
	ackerleytng, jackyli, pgonda, rientjes, jacobhxu, xin,
	pawan.kumar.gupta, babu.moger, dyoung, nikunj, john.allen, darwi,
	linux-kernel, linux-crypto, kvm, linux-coco
In-Reply-To: <20260721014841.GCal7P-f3ZBHQzR-0_@fat_crate.local>

Hello Boris,

On 7/20/2026 8:48 PM, Borislav Petkov wrote:
> On Mon, Jul 20, 2026 at 05:38:05PM -0500, Kalra, Ashish wrote:
>> Agreed on dropping the bool — I'll derive it in a local helper.
>>
>> One issue though: rmp_segment_table != NULL isn't segmented-only. setup_contiguous_rmptable() also allocates rmp_segment_table
>> (the contiguous RMP is stored as a single segment in the same table), so it's non-NULL for the contiguous case too.
>>
>> To keep it segmented-only, I'll also need to gate on the segmented-RMP mode, something like: 
>>
>>   static bool rmpopt_capable(void)
>>   {
>>         return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
>>                cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
>>                (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) &&
>>                rmp_segment_table;
>>   }
>>
>> The CC_ATTR_HOST_SEV_SNP check also handles SNP being disabled at runtime, so snp_clear_rmpopt_capable() and its caller go away as well.
> 
 Ok, you can simply do:
> 
> 	setup_clear_cpu_cap(X86_FEATURE_RMPOPT)
> 
> and clear our internal representation of RMPOPT support and make it a lot
> simpler.
> 

We did exactly that in v4, but had to drop it in v7 (flagged during Sashiko review) because it's unreliable here — we only
find out whether RMPOPT is usable after alternatives are patched — too late for setup_clear_cpu_cap() to take effect.

Segmented RMP (which RMPOPT requires) is only determined in setup_rmptable(), reached via:

  rootfs_initcall(pci_iommu_init)
    -> amd_iommu_init() 
	-> state_next() 
		-> iommu_snp_enable()
      			-> snp_rmptable_init() 
				-> setup_rmptable()

That's a rootfs_initcall, which runs after alternative_instructions(). By then static_cpu_has(X86_FEATURE_RMPOPT) is already
patched, so a setup_clear_cpu_cap() at that point doesn't take effect and cpu_feature_enabled(X86_FEATURE_RMPOPT) keeps returning true.

That's why v7 moved to a runtime check. In v11 (as i mentioned) this will be a small local helper,  it will also handles two things
the cap-clear can't:
  - a contiguous (non-segmented) RMP, where RMPOPT isn't usable even with X86_FEATURE_RMPOPT set.
  - SNP being disabled at runtime (CC_ATTR_HOST_SEV_SNP).

  static bool rmpopt_capable(void)
  {
        return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
               cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
               (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) &&
               rmp_segment_table;
  }

Thanks,
Ashish

^ permalink raw reply

* Re: [PATCH v8 01/23] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Leon Romanovsky @ 2026-07-21 14:29 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley,
	Jason Gunthorpe
In-Reply-To: <yq5atsps77c5.fsf@kernel.org>

On Tue, Jul 21, 2026 at 07:50:10PM +0530, Aneesh Kumar K.V wrote:
> Leon Romanovsky <leon@kernel.org> writes:
> 
> > On Fri, Jul 17, 2026 at 11:34:19PM +0530, Aneesh Kumar K.V (Arm) wrote:
> >> Commit 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool
> >> helper") changed dma_direct_alloc_from_pool() to return the CPU address
> >> from dma_alloc_from_pool(). That fits dma_direct_alloc(), but
> >> dma_direct_alloc_pages() also uses the helper and expects a struct page *.
> >> 
> >> Fix this by making dma_direct_alloc_from_pool() return the struct page *
> >> again, and pass the CPU address back through an out-parameter for the
> >> dma_direct_alloc() caller.
> >> 
> >> Fixes: 5b138c534fda ("dma-direct: factor out a dma_direct_alloc_from_pool helper")
> >> Cc: stable@vger.kernel.org
> >> Tested-by: Michael Kelley <mhklinux@outlook.com>
> >> Tested-by: Mostafa Saleh <smostafa@google.com>
> >> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> >> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> >> ---
> >>  kernel/dma/direct.c | 18 ++++++++++--------
> >>  1 file changed, 10 insertions(+), 8 deletions(-)
> >> 
> >> diff --git a/kernel/dma/direct.c b/kernel/dma/direct.c
> >> index d8219efe3273..363d984d90e7 100644
> >> --- a/kernel/dma/direct.c
> >> +++ b/kernel/dma/direct.c
> >> @@ -164,22 +164,21 @@ static bool dma_direct_use_pool(struct device *dev, gfp_t gfp)
> >>  	return !gfpflags_allow_blocking(gfp) && !is_swiotlb_for_alloc(dev);
> >>  }
> >>  
> >> -static void *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> >> -		dma_addr_t *dma_handle, gfp_t gfp)
> >> +static struct page *dma_direct_alloc_from_pool(struct device *dev, size_t size,
> >> +		dma_addr_t *dma_handle, void **cpu_addr, gfp_t gfp)
> >>  {
> >>  	struct page *page;
> >>  	u64 phys_limit;
> >> -	void *ret;
> >>  
> >>  	if (WARN_ON_ONCE(!IS_ENABLED(CONFIG_DMA_COHERENT_POOL)))
> >>  		return NULL;
> >>  
> >>  	gfp |= dma_direct_optimal_gfp_mask(dev, &phys_limit);
> >> -	page = dma_alloc_from_pool(dev, size, &ret, gfp, dma_coherent_ok);
> >> +	page = dma_alloc_from_pool(dev, size, cpu_addr, gfp, dma_coherent_ok);
> >>  	if (!page)
> >>  		return NULL;
> >>  	*dma_handle = phys_to_dma_direct(dev, page_to_phys(page));
> >> -	return ret;
> >> +	return page;
> >>  }
> >>  
> >>  static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
> >> @@ -247,8 +246,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
> >>  	 * the atomic pools instead if we aren't allowed block.
> >>  	 */
> >>  	if ((remap || force_dma_unencrypted(dev)) &&
> >> -	    dma_direct_use_pool(dev, gfp))
> >> -		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
> >> +	    dma_direct_use_pool(dev, gfp)) {
> >> +		page = dma_direct_alloc_from_pool(dev, size, dma_handle,
> >> +						  &ret, gfp);
> >> +		return page ? ret : NULL;
> >
> > Sorry for joining the discussion late, but the line above caught my
> > attention.
> >
> > Why do we need both ret and page? We can derive cpu_addr from page and
> > vice versa. Do we really need the &ret parameter? Or, more generally, do
> > we really need "struct page *"?
> >
> > static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
> > 		struct gen_pool *pool, void **cpu_addr,
> > 		bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
> > {
> > ...
> > 	*cpu_addr = (void *)addr;
> > 	memset(*cpu_addr, 0, size);
> > 	return pfn_to_page(__phys_to_pfn(phys));
> > }
> >
> > Why
> >
> 
> With CONFIG_DMA_DIRECT_REMAP the cpu_addr can be different from
> page_address.

Can you please point to the code there it can happen?
__dma_alloc_from_pool() has direct connection between physical address
and struct page.

Thanks

> 
> -aneesh
> 

^ permalink raw reply

* Re: [PATCH v8 02/23] dma-pool: fix page leak in atomic_pool_expand() cleanup
From: Aneesh Kumar K.V @ 2026-07-21 14:41 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, Jason Gunthorpe,
	Michael Kelley
In-Reply-To: <20260721123107.GJ110966@unreal>

Leon Romanovsky <leon@kernel.org> writes:

> On Fri, Jul 17, 2026 at 11:34:20PM +0530, Aneesh Kumar K.V (Arm) wrote:
>> atomic_pool_expand() frees the allocated pages from the remove_mapping
>> error path only when CONFIG_DMA_DIRECT_REMAP is enabled.
>> 
>> When CONFIG_DMA_DIRECT_REMAP is disabled, failures after page allocation,
>> such as gen_pool_add_virt(), jump to remove_mapping and return without
>> freeing the pages.
>> 
>> Move __free_pages(page, order) out of the CONFIG_DMA_DIRECT_REMAP block so
>> that cleanup paths always release the allocation.
>> 
>> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
>> 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/pool.c | 10 +++++++---
>>  1 file changed, 7 insertions(+), 3 deletions(-)
>> 
>> diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
>> index 2b2fbb709242..b0303efbc153 100644
>> --- a/kernel/dma/pool.c
>> +++ b/kernel/dma/pool.c
>> @@ -81,6 +81,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
>>  {
>>  	unsigned int order;
>>  	struct page *page = NULL;
>> +	bool leak_pages = false;
>>  	void *addr;
>>  	int ret = -ENOMEM;
>>  
>> @@ -115,8 +116,10 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
>>  	 */
>>  	ret = set_memory_decrypted((unsigned long)page_to_virt(page),
>>  				   1 << order);
>> -	if (ret)
>> +	if (ret) {
>> +		leak_pages = true;
>>  		goto remove_mapping;
>> +	}
>>  	ret = gen_pool_add_virt(pool, (unsigned long)addr, page_to_phys(page),
>>  				pool_size, NUMA_NO_NODE);
>>  	if (ret)
>> @@ -130,14 +133,15 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
>>  				   1 << order);
>>  	if (WARN_ON_ONCE(ret)) {
>>  		/* Decrypt succeeded but encrypt failed, purposely leak */
>> -		goto out;
>> +		leak_pages = true;
>
> Instead of doing this dance with temporal variable, change "goto out" to
> be "return true".
>


I didn't follow the return true part. A failure in
set_memory_encrypted() or set_memory_decrypted() requires the pages to
be leaked, so this is not the only call site that sets leak_pages =
true. There is a similar case a few lines above.


>
>>  	}
>>  remove_mapping:
>>  #ifdef CONFIG_DMA_DIRECT_REMAP
>>  	dma_common_free_remap(addr, pool_size);
>>  free_page:
>
> Remove free_page label, and change leftover of "goto free_page" to be
> "goto out"
>
>> -	__free_pages(page, order);
>>  #endif
>> +	if (!leak_pages)
>> +		__free_pages(page, order);
>
> Put these checks under out label and rely on page != NULL as a marker.
> if (page)
>  __free_pages(page, order);
>
>>  out:
>>  	return ret;
>>  }
>> -- 
>> 2.43.0
>> 
>> 

-aneesh

^ permalink raw reply

* Re: [PATCH v10 2/6] x86/sev: Initialize RMPOPT configuration MSRs
From: K Prateek Nayak @ 2026-07-21 14:57 UTC (permalink / raw)
  To: Kalra, Ashish, Borislav Petkov
  Cc: tglx, mingo, dave.hansen, x86, hpa, seanjc, peterz,
	thomas.lendacky, herbert, davem, ardb, pbonzini, aik,
	Michael.Roth, Tycho.Andersen, Nathan.Fontenot, ackerleytng,
	jackyli, pgonda, rientjes, jacobhxu, xin, pawan.kumar.gupta,
	babu.moger, dyoung, nikunj, john.allen, darwi, linux-kernel,
	linux-crypto, kvm, linux-coco
In-Reply-To: <9a183dfc-91fa-4a08-9168-8ea0e53f708c@amd.com>

Hello Ashish,

On 7/21/2026 7:56 PM, Kalra, Ashish wrote:
> That's why v7 moved to a runtime check. In v11 (as i mentioned) this will be a small local helper,  it will also handles two things
> the cap-clear can't:
>   - a contiguous (non-segmented) RMP, where RMPOPT isn't usable even with X86_FEATURE_RMPOPT set.
>   - SNP being disabled at runtime (CC_ATTR_HOST_SEV_SNP).
> 
>   static bool rmpopt_capable(void)
>   {
>         return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
>                cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&

CC_ATTR_HOST_SEV_SNP is set from bsp_determine_snp() ...

>                (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) &&

... and that already checks snp_probe_rmptable_info() ...

>                rmp_segment_table;

.. and if iommu_snp_enable() fails snp_rmptable_init(), we clear
CC_ATTR_HOST_SEV_SNP.

So, the way I see it, CC_ATTR_HOST_SEV_SNP being set means we have
already tried provisioning RMP table.

I'm assuming all platforms that have  X86_FEATURE_RMPOPT will all have
segmented RMP. If not, you can just clear X86_FEATURE_RMPOPT in
snp_rmptable_init() no?

We can never reach functions that need rmpopt_capable() without
first checking CC_ATTR_HOST_SEV_SNP.

-- 
Thanks and Regards,
Prateek


^ permalink raw reply

* Re: [PATCH v10 4/6] x86/sev: Add support to perform RMP optimizations asynchronously
From: K Prateek Nayak @ 2026-07-21 15:06 UTC (permalink / raw)
  To: Ashish Kalra, tglx, mingo, bp, dave.hansen, x86, hpa, seanjc,
	peterz, thomas.lendacky, herbert, davem, ardb
  Cc: pbonzini, aik, Michael.Roth, Tycho.Andersen, Nathan.Fontenot,
	ackerleytng, jackyli, pgonda, rientjes, jacobhxu, xin,
	pawan.kumar.gupta, babu.moger, dyoung, nikunj, john.allen, darwi,
	linux-kernel, linux-crypto, kvm, linux-coco
In-Reply-To: <ada64cdc976b98a70687b3a347bca0c25c89eb09.1782841284.git.ashish.kalra@amd.com>

Hello Ashish,

On 6/30/2026 11:41 PM, Ashish Kalra wrote:
> +	/*
> +	 * RMPOPT scans the RMP table, stores the result of the scan in the
> +	 * reserved processor memory. The RMP scan is the most expensive
> +	 * part. If a second RMPOPT occurs, it can skip the expensive scan
> +	 * if they can see a cached result in the reserved processor memory.
> +	 *
> +	 * Do RMPOPT on one CPU alone. Then, follow that up with RMPOPT
> +	 * on every other primary thread. Followers are "designed to"
> +	 * skip the scan if they see the "cached" scan results.
> +	 *
> +	 * Pin the worker to the current CPU for the leader loop so that
> +	 * this_cpu remains valid and the RMPOPT instruction executes on
> +	 * the correct CPU.  Use migrate_disable() rather than get_cpu() to
> +	 * prevent migration while still allowing preemption.
> +	 */
> +	migrate_disable();
> +	this_cpu = smp_processor_id();
> +
> +	cpumask_andnot(follower_mask, rmpopt_cpumask,
> +		       topology_sibling_cpumask(this_cpu));
> +
> +	for (pa = rmpopt_pa_start; pa < rmpopt_pa_end; pa += SZ_1G) {
> +		rmpopt(pa);
> +		cond_resched();
> +	}
> +	migrate_enable();
> +
> +	/*
> +	 * Followers: run RMPOPT on remaining cores.  CPUs cannot go offline
> +	 * while SNP is active, so the follower set stays valid across the
> +	 * scan and cpus_read_lock() is uncontended.
> +	 */
> +	scoped_guard(cpus_read_lock) {

We can only reach here after disabling hotplug. Do we still to hold the
cpus_read_lock?

> +		for (pa = rmpopt_pa_start; pa < rmpopt_pa_end; pa += SZ_1G) {
> +			on_each_cpu_mask(follower_mask, rmpopt_smp,
> +					 (void *)pa, true);
> +
> +			/* Give a chance for other threads to run */
> +			cond_resched();

Ever since commit 7dadeaa6e851 ("sched: Further restrict the preemption
modes"), one cannot select PREEMPT_VOLUNTARY on x86 and cond_resched()
is a nop with all the other preemption models (PREEMPT_NONE will not
preempt a kernel thread; PREEMPT_LAZY / PREEMPT / PREEMPT_RT all make
the kernel fully preemptible except for sections with
preempt_count != 0)

You can drop these cond_resched() calls in your respin.

> +		}
> +	}
> +
> +	free_cpumask_var(follower_mask);
> +}
> +

-- 
Thanks and Regards,
Prateek


^ permalink raw reply

* Re: [PATCH v8 01/23] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Aneesh Kumar K.V @ 2026-07-21 15:10 UTC (permalink / raw)
  To: Leon Romanovsky
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley,
	Jason Gunthorpe
In-Reply-To: <20260721142921.GN110966@unreal>

Leon Romanovsky <leon@kernel.org> writes:

> On Tue, Jul 21, 2026 at 07:50:10PM +0530, Aneesh Kumar K.V wrote:
>> Leon Romanovsky <leon@kernel.org> writes:
>> 
>> > On Fri, Jul 17, 2026 at 11:34:19PM +0530, Aneesh Kumar K.V (Arm) wrote:
....
>> >>  static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
>> >> @@ -247,8 +246,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
>> >>  	 * the atomic pools instead if we aren't allowed block.
>> >>  	 */
>> >>  	if ((remap || force_dma_unencrypted(dev)) &&
>> >> -	    dma_direct_use_pool(dev, gfp))
>> >> -		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
>> >> +	    dma_direct_use_pool(dev, gfp)) {
>> >> +		page = dma_direct_alloc_from_pool(dev, size, dma_handle,
>> >> +						  &ret, gfp);
>> >> +		return page ? ret : NULL;
>> >
>> > Sorry for joining the discussion late, but the line above caught my
>> > attention.
>> >
>> > Why do we need both ret and page? We can derive cpu_addr from page and
>> > vice versa. Do we really need the &ret parameter? Or, more generally, do
>> > we really need "struct page *"?
>> >
>> > static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
>> > 		struct gen_pool *pool, void **cpu_addr,
>> > 		bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
>> > {
>> > ...
>> > 	*cpu_addr = (void *)addr;
>> > 	memset(*cpu_addr, 0, size);
>> > 	return pfn_to_page(__phys_to_pfn(phys));
>> > }
>> >
>> > Why
>> >
>> 
>> With CONFIG_DMA_DIRECT_REMAP the cpu_addr can be different from
>> page_address.
>
> Can you please point to the code there it can happen?
> __dma_alloc_from_pool() has direct connection between physical address
> and struct page.
>

dma_direct_alloc -> 	remap = IS_ENABLED(CONFIG_DMA_DIRECT_REMAP);
	if ((remap && dma_direct_use_pool(dev, gfp)) {
		page = dma_direct_alloc_from_pool(dev, size,

..
__dma_alloc_from_pool -> 
	addr = gen_pool_alloc(pool, size);
	if (!addr)


We expand the pool as below..

atomic_pool_expand ->

#ifdef CONFIG_DMA_DIRECT_REMAP
	addr = dma_common_contiguous_remap(page, pool_size,
			pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
			__builtin_return_address(0));
	if (!addr)
		goto free_page;
#else
	addr = page_to_virt(page);
#endif


-aneesh

^ permalink raw reply

* Re: [PATCH v7 05/11] x86/virt/tdx: Handle multiple callers in tdx_pamt_get/put()
From: Nikolay Borisov @ 2026-07-21 15:32 UTC (permalink / raw)
  To: Rick Edgecombe, bp, dave.hansen, hpa, kas, kvm, linux-coco,
	linux-doc, linux-kernel, mingo, pbonzini, seanjc, tglx,
	vannapurve, x86, chao.gao, yan.y.zhao, kai.huang, tony.lindgren,
	binbin.wu
  Cc: Binbin Wu
In-Reply-To: <20260718014500.2231262-6-rick.p.edgecombe@intel.com>



On 7/18/26 04:44, Rick Edgecombe wrote:
> From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
> 
> tdx_pamt_get()/tdx_pamt_put() unconditionally add or remove Dynamic PAMT
> backing for the 2MB region covering the passed page. However, multiple
> callers can add or remove 4KB pages that fall within the same 2MB region
> and in that scenario only a single PAMT entry is required.
> 
> Make the helpers handle only adding/removing Dynamic PAMT backing when
> required, by refcounting each 2MB range. Gate the actual Dynamic PAMT add
> and remove on refcount transitions (0->1 and 1->0). Serialize the refcount
> check and SEAMCALL with a global spinlock so the read-decide-act sequence
> is atomic. This also avoids TDX module BUSY errors, as the Dynamic PAMT add
> and remove SEAMCALLs take internal TDX module locks for the 2MB ranges of
> the specified PFN and the PAMT page pair PFNs. So simultaneous attempts on
> the same 2MB ranges of the PFNs would otherwise encounter an error, which
> would not be handleable in the put case.
> 
> The lock is global and heavyweight. Use simple conditional logic to keep
> correctness obvious. This will be optimized in a later change.
> 
> The pamt_refcounts[] are atomic_t's. They do not strictly need to be
> because all access is protected by pamt_lock. The overhead of an atomic_t
> in this situation is minuscule compared to the global lock. Leave the
> atomic_t in place to enable future optimization with minimal churn.
> 
> AI was used under supervision to collect/apply feedback, split patches,
> review code and workshop logs.
> 
> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Co-developed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
> Reviewed-by: Chao Gao <chao.gao@intel.com>
> Reviewed-by: Yan Zhao <yan.y.zhao@intel.com>
> Reviewed-by: Tony Lindgren <tony.lindgren@linux.intel.com>


Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>

^ permalink raw reply

* Re: [PATCH v10 2/6] x86/sev: Initialize RMPOPT configuration MSRs
From: Borislav Petkov @ 2026-07-21 15:32 UTC (permalink / raw)
  To: Kalra, Ashish
  Cc: tglx, mingo, dave.hansen, x86, hpa, seanjc, peterz,
	thomas.lendacky, herbert, davem, ardb, pbonzini, aik,
	Michael.Roth, KPrateek.Nayak, Tycho.Andersen, Nathan.Fontenot,
	ackerleytng, jackyli, pgonda, rientjes, jacobhxu, xin,
	pawan.kumar.gupta, babu.moger, dyoung, nikunj, john.allen, darwi,
	linux-kernel, linux-crypto, kvm, linux-coco
In-Reply-To: <9a183dfc-91fa-4a08-9168-8ea0e53f708c@amd.com>

On Tue, Jul 21, 2026 at 09:26:48AM -0500, Kalra, Ashish wrote:
> That's why v7 moved to a runtime check. In v11 (as i mentioned) this will be a small local helper,  it will also handles two things
> the cap-clear can't:
>   - a contiguous (non-segmented) RMP, where RMPOPT isn't usable even with X86_FEATURE_RMPOPT set.

That's the point of clearing the flag - to mark it non-usable.

>   - SNP being disabled at runtime (CC_ATTR_HOST_SEV_SNP).

Same as RMPOPT being not usable follows from disabled SNP.

>   static bool rmpopt_capable(void)
>   {
>         return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
>                cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
>                (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) &&
>                rmp_segment_table;
>   }

But yes, this is a local helper so that's good enough.

We can always change it later if needed.

Thx.

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

^ permalink raw reply

* Re: [PATCH v8 01/23] dma-direct: return struct page from dma_direct_alloc_from_pool()
From: Leon Romanovsky @ 2026-07-21 15:33 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, stable, Michael Kelley,
	Jason Gunthorpe
In-Reply-To: <yq5ao6g0750v.fsf@kernel.org>

On Tue, Jul 21, 2026 at 08:40:08PM +0530, Aneesh Kumar K.V wrote:
> Leon Romanovsky <leon@kernel.org> writes:
> 
> > On Tue, Jul 21, 2026 at 07:50:10PM +0530, Aneesh Kumar K.V wrote:
> >> Leon Romanovsky <leon@kernel.org> writes:
> >> 
> >> > On Fri, Jul 17, 2026 at 11:34:19PM +0530, Aneesh Kumar K.V (Arm) wrote:
> ....
> >> >>  static void *dma_direct_alloc_no_mapping(struct device *dev, size_t size,
> >> >> @@ -247,8 +246,11 @@ void *dma_direct_alloc(struct device *dev, size_t size,
> >> >>  	 * the atomic pools instead if we aren't allowed block.
> >> >>  	 */
> >> >>  	if ((remap || force_dma_unencrypted(dev)) &&
> >> >> -	    dma_direct_use_pool(dev, gfp))
> >> >> -		return dma_direct_alloc_from_pool(dev, size, dma_handle, gfp);
> >> >> +	    dma_direct_use_pool(dev, gfp)) {
> >> >> +		page = dma_direct_alloc_from_pool(dev, size, dma_handle,
> >> >> +						  &ret, gfp);
> >> >> +		return page ? ret : NULL;
> >> >
> >> > Sorry for joining the discussion late, but the line above caught my
> >> > attention.
> >> >
> >> > Why do we need both ret and page? We can derive cpu_addr from page and
> >> > vice versa. Do we really need the &ret parameter? Or, more generally, do
> >> > we really need "struct page *"?
> >> >
> >> > static struct page *__dma_alloc_from_pool(struct device *dev, size_t size,
> >> > 		struct gen_pool *pool, void **cpu_addr,
> >> > 		bool (*phys_addr_ok)(struct device *, phys_addr_t, size_t))
> >> > {
> >> > ...
> >> > 	*cpu_addr = (void *)addr;
> >> > 	memset(*cpu_addr, 0, size);
> >> > 	return pfn_to_page(__phys_to_pfn(phys));
> >> > }
> >> >
> >> > Why
> >> >
> >> 
> >> With CONFIG_DMA_DIRECT_REMAP the cpu_addr can be different from
> >> page_address.
> >
> > Can you please point to the code there it can happen?
> > __dma_alloc_from_pool() has direct connection between physical address
> > and struct page.
> >
> 
> dma_direct_alloc -> 	remap = IS_ENABLED(CONFIG_DMA_DIRECT_REMAP);
> 	if ((remap && dma_direct_use_pool(dev, gfp)) {
> 		page = dma_direct_alloc_from_pool(dev, size,
> 
> ..
> __dma_alloc_from_pool -> 
> 	addr = gen_pool_alloc(pool, size);
> 	if (!addr)
> 
> 
> We expand the pool as below..
> 
> atomic_pool_expand ->
> 
> #ifdef CONFIG_DMA_DIRECT_REMAP
> 	addr = dma_common_contiguous_remap(page, pool_size,
> 			pgprot_decrypted(pgprot_dmacoherent(PAGE_KERNEL)),
> 			__builtin_return_address(0));
> 	if (!addr)
> 		goto free_page;
> #else
> 	addr = page_to_virt(page);
> #endif

Right, and nothing prevents you from adding a small DMA helper
that translates mapped/direct addresses back to struct page.

Something like, but probably void* needs to be phys_addr_t:

static inline struct page *dma_phys_to_page(void *addr)
{
#ifdef CONFIG_DMA_DIRECT_REMAP
	return vmalloc_to_page(addr);
#else
	return virt_to_page(addr);
#endif
}

Architecture code already does this throughout the tree.

Thanks


> 
> 
> -aneesh
> 

^ permalink raw reply

* Re: [PATCH v8 02/23] dma-pool: fix page leak in atomic_pool_expand() cleanup
From: Leon Romanovsky @ 2026-07-21 15:34 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: iommu, linux-arm-kernel, linux-kernel, linux-coco, 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 (CS GROUP),
	Alexander Gordeev, Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, x86, Jason Gunthorpe,
	Michael Kelley
In-Reply-To: <yq5aqzkw76ch.fsf@kernel.org>

On Tue, Jul 21, 2026 at 08:11:34PM +0530, Aneesh Kumar K.V wrote:
> Leon Romanovsky <leon@kernel.org> writes:
> 
> > On Fri, Jul 17, 2026 at 11:34:20PM +0530, Aneesh Kumar K.V (Arm) wrote:
> >> atomic_pool_expand() frees the allocated pages from the remove_mapping
> >> error path only when CONFIG_DMA_DIRECT_REMAP is enabled.
> >> 
> >> When CONFIG_DMA_DIRECT_REMAP is disabled, failures after page allocation,
> >> such as gen_pool_add_virt(), jump to remove_mapping and return without
> >> freeing the pages.
> >> 
> >> Move __free_pages(page, order) out of the CONFIG_DMA_DIRECT_REMAP block so
> >> that cleanup paths always release the allocation.
> >> 
> >> Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
> >> 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/pool.c | 10 +++++++---
> >>  1 file changed, 7 insertions(+), 3 deletions(-)
> >> 
> >> diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c
> >> index 2b2fbb709242..b0303efbc153 100644
> >> --- a/kernel/dma/pool.c
> >> +++ b/kernel/dma/pool.c
> >> @@ -81,6 +81,7 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
> >>  {
> >>  	unsigned int order;
> >>  	struct page *page = NULL;
> >> +	bool leak_pages = false;
> >>  	void *addr;
> >>  	int ret = -ENOMEM;
> >>  
> >> @@ -115,8 +116,10 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
> >>  	 */
> >>  	ret = set_memory_decrypted((unsigned long)page_to_virt(page),
> >>  				   1 << order);
> >> -	if (ret)
> >> +	if (ret) {
> >> +		leak_pages = true;
> >>  		goto remove_mapping;
> >> +	}
> >>  	ret = gen_pool_add_virt(pool, (unsigned long)addr, page_to_phys(page),
> >>  				pool_size, NUMA_NO_NODE);
> >>  	if (ret)
> >> @@ -130,14 +133,15 @@ static int atomic_pool_expand(struct gen_pool *pool, size_t pool_size,
> >>  				   1 << order);
> >>  	if (WARN_ON_ONCE(ret)) {
> >>  		/* Decrypt succeeded but encrypt failed, purposely leak */
> >> -		goto out;
> >> +		leak_pages = true;
> >
> > Instead of doing this dance with temporal variable, change "goto out" to
> > be "return true".
> >
> 
> 
> I didn't follow the return true part. A failure in
> set_memory_encrypted() or set_memory_decrypted() requires the pages to
> be leaked, so this is not the only call site that sets leak_pages =
> true. There is a similar case a few lines above.

Comment about "leaked" is enough. There is no need to introduce
convoluted flow just to check that page != NULL.

Thanks

> 
> 
> >
> >>  	}
> >>  remove_mapping:
> >>  #ifdef CONFIG_DMA_DIRECT_REMAP
> >>  	dma_common_free_remap(addr, pool_size);
> >>  free_page:
> >
> > Remove free_page label, and change leftover of "goto free_page" to be
> > "goto out"
> >
> >> -	__free_pages(page, order);
> >>  #endif
> >> +	if (!leak_pages)
> >> +		__free_pages(page, order);
> >
> > Put these checks under out label and rely on page != NULL as a marker.
> > if (page)
> >  __free_pages(page, order);
> >
> >>  out:
> >>  	return ret;
> >>  }
> >> -- 
> >> 2.43.0
> >> 
> >> 
> 
> -aneesh
> 

^ permalink raw reply

* SVSM Development Call July 22nd, 2026
From: Stefano Garzarella @ 2026-07-21 15:59 UTC (permalink / raw)
  To: coconut-svsm, linux-coco
In-Reply-To: <CAGxU2F6ko6Ojyu138cB7szTszoYkx1AEw5oK6EMMaUoi=m7+sw@mail.gmail.com>

Hi,

Here is the call for agenda items for this weeks SVSM development
call. Please send any agenda items you have in mind as a reply to this
email or raise them in the meeting.

We will use the LF Zoom instance. Details of the meeting can be found
in our governance repository at:

        https://github.com/coconut-svsm/governance

The link to the COCONUT-SVSM calendar is:

        https://zoom-lfx.platform.linuxfoundation.org/meetings/coconut-svsm?view=week

The meeting will be recorded and the recording eventually published.

Regards,
Stefano


^ permalink raw reply

* Re: [PATCH v2 2/2] virt: tdx-guest: Allocate Quote buffer dynamically
From: Edgecombe, Rick P @ 2026-07-21 16:43 UTC (permalink / raw)
  To: Hansen, Dave, Fang, Peter
  Cc: kvm@vger.kernel.org, bp@alien8.de, kas@kernel.org, Li, Xiaoyao,
	x86@kernel.org, sathyanarayanan.kuppuswamy@linux.intel.com,
	mingo@redhat.com, dave.hansen@linux.intel.com, tglx@kernel.org,
	linux-coco@lists.linux.dev, hpa@zytor.com,
	linux-kernel@vger.kernel.org, binbin.wu@linux.intel.com
In-Reply-To: <d88fe58e-5963-49a5-86a4-6a9779d06109@intel.com>

On Tue, 2026-07-21 at 06:48 -0700, Dave Hansen wrote:
> > > The host may be untrusted, but it's also a critical part of the system.
> > > Are we sure we want to be completely quiet?
> > > 
> > > I used to see little dmesg warnings about TCP window shenanigans from
> > > random systems on the Internet. Maybe that's not how we do things today,
> > > but if a random dude on the Internet can spew one line to dmesg, is it
> > > that crazy that a bad VMM be able to spew a warning?
> > 
> > That makes sense... I actually argued with AI about this but it kept
> > saying this is kind of like DoSing the guest.

A guest DOSing another guest is relevant, but the host DOSing the guest is not a
threat model we should or even can care about. If userspace or the kernel
decides to kill the guest, that is its prerogative. At most it's a functional
bug and not a security one.

But... doesn't this size come from the TDX module? In which case there is no
hope of defense from anything.

> >  But thinking about it
> > more, tainting the guest is probably the right thing to do... At least
> > the guest sees a big splat about why attestation is failing. I'll remove
> > the __GFP_NOWARN. Thanks.
> 
> This does seem like the kind of high-level TDX policy that we all need
> to be aligned on and probably document somewhere. The basic question is
> whether a TDX guest should be quiet or verbose in the face of host
> malfunction or malfeasance.
> 
> Kirill and Rick, what do you think?

We discussed something similar around the set_memory_en/decrypted() failures.
But that was around whether to panic or just warn. Not be silent. If the host is
mucking around, I think security conscious guests would want to know, and even
have the option to pass panic_on_warn. So yea I think we should assume the
default TDX user is security conscious. "Warn on untrusted host weird behavior"
seems like a good policy.

BUT, is this number coming from the untrusted host or the TDX module? I cant
find TDCS_QUOTE_MAX_SIZE in the docs. If it is coming from the TDX module then
we are not talking about security considerations at all. It's just a functional
"do you want to know if things are failing". Not sure why this one would be
special in that regard. If we think it will fail so often that we don't want a
warning, then we probably need another solution.

^ permalink raw reply

* Re: [PATCH v10 2/6] x86/sev: Initialize RMPOPT configuration MSRs
From: Kalra, Ashish @ 2026-07-21 20:46 UTC (permalink / raw)
  To: K Prateek Nayak, Borislav Petkov
  Cc: tglx, mingo, dave.hansen, x86, hpa, seanjc, peterz,
	thomas.lendacky, herbert, davem, ardb, pbonzini, aik,
	Michael.Roth, Tycho.Andersen, Nathan.Fontenot, ackerleytng,
	jackyli, pgonda, rientjes, jacobhxu, xin, pawan.kumar.gupta,
	babu.moger, dyoung, nikunj, john.allen, darwi, linux-kernel,
	linux-crypto, kvm, linux-coco
In-Reply-To: <2696f0a9-d2a3-41e8-91be-6f00a20d5f27@amd.com>

Hello Prateek,

On 7/21/2026 9:57 AM, K Prateek Nayak wrote:
> Hello Ashish,
> 
> On 7/21/2026 7:56 PM, Kalra, Ashish wrote:
>> That's why v7 moved to a runtime check. In v11 (as i mentioned) this will be a small local helper,  it will also handles two things
>> the cap-clear can't:
>>   - a contiguous (non-segmented) RMP, where RMPOPT isn't usable even with X86_FEATURE_RMPOPT set.
>>   - SNP being disabled at runtime (CC_ATTR_HOST_SEV_SNP).
>>
>>   static bool rmpopt_capable(void)
>>   {
>>         return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
>>                cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
> 
> CC_ATTR_HOST_SEV_SNP is set from bsp_determine_snp() ...
> 
>>                (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED) &&
> 
> ... and that already checks snp_probe_rmptable_info() ...
> 
>>                rmp_segment_table;
> 
> .. and if iommu_snp_enable() fails snp_rmptable_init(), we clear
> CC_ATTR_HOST_SEV_SNP.
> 
> So, the way I see it, CC_ATTR_HOST_SEV_SNP being set means we have
> already tried provisioning RMP table.

Agreed, and that makes rmp_segment_table redundant — iommu_snp_enable() clears CC_ATTR_HOST_SEV_SNP when
snp_rmptable_init() fails, so the attr being set already implies rmp_segment_table != NULL. I'll drop it.

The one I'd keep is (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED). It's a runtime config bit, not the CPUID feature:
setup_rmptable() allocates rmp_segment_table and keeps CC_ATTR_HOST_SEV_SNP set for both segmented and contiguous RMP, so
the MSR bit is the only thing that distinguishes them — and RMPOPT needs a segmented RMP.

Clearing X86_FEATURE_RMPOPT in snp_rmptable_init() won't work on its own as i mentioned in this reply earlier: it runs at
rootfs_initcall, after alternative_instructions(), so cpu_feature_enabled() keeps returning true off the already-patched
static_cpu_has().

So the helper becomes:

  static bool rmpopt_capable(void)
  {
        return cpu_feature_enabled(X86_FEATURE_RMPOPT) &&
               cc_platform_has(CC_ATTR_HOST_SEV_SNP) &&
               (rmp_cfg & MSR_AMD64_SEG_RMP_ENABLED);
  }

Thanks,
Ashish

> 
> I'm assuming all platforms that have  X86_FEATURE_RMPOPT will all have
> segmented RMP. If not, you can just clear X86_FEATURE_RMPOPT in
> snp_rmptable_init() no?
> 
> We can never reach functions that need rmpopt_capable() without
> first checking CC_ATTR_HOST_SEV_SNP.
> 

^ permalink raw reply

* Re: [PATCH v7 00/11] Dynamic PAMT
From: Sohil Mehta @ 2026-07-21 20:59 UTC (permalink / raw)
  To: Rick Edgecombe, bp, dave.hansen, hpa, kas, kvm, linux-coco,
	linux-doc, linux-kernel, mingo, nik.borisov, pbonzini, seanjc,
	tglx, vannapurve, x86, chao.gao, yan.y.zhao, kai.huang,
	tony.lindgren, binbin.wu
In-Reply-To: <20260718014500.2231262-1-rick.p.edgecombe@intel.com>

On 7/17/2026 6:44 PM, Rick Edgecombe wrote:

> Kiryl Shutsemau (9):
>   x86/virt/tdx: Allocate page bitmap for Dynamic PAMT
>   x86/virt/tdx: Add tdx_alloc/free_control_page() helpers
>   x86/virt/tdx: Allocate refcounts for Dynamic PAMT memory
>   x86/virt/tdx: Handle multiple callers in tdx_pamt_get/put()
>   KVM: TDX: Allocate PAMT memory for TD and vCPU control structures
>   KVM: TDX: Get/put PAMT pages when (un)mapping private memory
>   x86/virt/tdx: Enable Dynamic PAMT
>   Documentation/x86: Add documentation for TDX's Dynamic PAMT
>   x86/virt/tdx: Optimize tdx_pamt_get/put()
> 
> Rick Edgecombe (2):
>   x86/virt/tdx: Simplify PAMT layout calculation
>   x86/tdx: Add APIs to support Dynamic PAMT ops from KVM's fault path
> 
I primarily reviewed the commit logs and assessed the implementation.
The patches look good to me and are clean overall.

Acked-by: Sohil Mehta <sohil.mehta@intel.com>

^ permalink raw reply

* Re: [PATCH v5 08/10] arm64: realm: Move Realm memory encryption ops to RSI code
From: Will Deacon @ 2026-07-21 22:03 UTC (permalink / raw)
  To: Aneesh Kumar K.V (Arm)
  Cc: linux-coco, kvmarm, linux-arm-kernel, linux-kernel, iommu,
	Catalin Marinas, Jason Gunthorpe, Marc Zyngier, Marek Szyprowski,
	Robin Murphy, Steven Price, Suzuki K Poulose, Thomas Gleixner
In-Reply-To: <20260706060432.1375570-9-aneesh.kumar@kernel.org>

On Mon, Jul 06, 2026 at 11:34:30AM +0530, Aneesh Kumar K.V (Arm) wrote:
> Realm memory encryption callbacks are CCA-specific. Keep the Realm callback
> registration with the RSI initialization code instead of pageattr.c, which
> only needs to provide the low-level page-attribute transition helper.
> 
> Export __set_memory_enc_dec() within arm64 so the RSI code can wrap it with
> the Realm-specific encrypt/decrypt callbacks and warning policy.
> 
> No functional changes in this patch.
> 
> Signed-off-by: Aneesh Kumar K.V (Arm) <aneesh.kumar@kernel.org>
> ---
>  arch/arm64/include/asm/mem_encrypt.h |  3 +--
>  arch/arm64/kernel/rsi.c              | 34 +++++++++++++++++++++++++
>  arch/arm64/mm/pageattr.c             | 38 +---------------------------
>  3 files changed, 36 insertions(+), 39 deletions(-)
> 
> diff --git a/arch/arm64/include/asm/mem_encrypt.h b/arch/arm64/include/asm/mem_encrypt.h
> index 314b2b52025f..f6325f30e844 100644
> --- a/arch/arm64/include/asm/mem_encrypt.h
> +++ b/arch/arm64/include/asm/mem_encrypt.h
> @@ -15,8 +15,7 @@ int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops);
>  
>  int set_memory_encrypted(unsigned long addr, int numpages);
>  int set_memory_decrypted(unsigned long addr, int numpages);
> -
> -int realm_register_memory_enc_ops(void);
> +int __set_memory_enc_dec(unsigned long addr, int numpages, bool encrypt);
>  
>  static inline bool force_dma_unencrypted(struct device *dev)
>  {
> diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c
> index 1fb2abd79800..5c566700974c 100644
> --- a/arch/arm64/kernel/rsi.c
> +++ b/arch/arm64/kernel/rsi.c
> @@ -143,6 +143,40 @@ static int realm_ioremap_hook(phys_addr_t phys, size_t size, pgprot_t *prot)
>  	return 0;
>  }
>  
> +static int realm_set_memory_encrypted(unsigned long addr, int numpages)
> +{
> +	int ret = __set_memory_enc_dec(addr, numpages, true);
> +
> +	/*
> +	 * If the request to change state fails, then the only sensible cause
> +	 * of action for the caller is to leak the memory
> +	 */
> +	WARN(ret, "Failed to encrypt memory, %d pages will be leaked",
> +	     numpages);
> +
> +	return ret;
> +}
> +
> +static int realm_set_memory_decrypted(unsigned long addr, int numpages)
> +{
> +	int ret = __set_memory_enc_dec(addr, numpages, false);
> +
> +	WARN(ret, "Failed to decrypt memory, %d pages will be leaked",
> +	     numpages);
> +
> +	return ret;
> +}
> +
> +static const struct arm64_mem_crypt_ops realm_crypt_ops = {
> +	.encrypt = realm_set_memory_encrypted,
> +	.decrypt = realm_set_memory_decrypted,
> +};
> +
> +static int realm_register_memory_enc_ops(void)
> +{
> +	return arm64_mem_crypt_ops_register(&realm_crypt_ops);
> +}

It's good to move these out of pageattr.c but I still don't think any
of this stuff should be in arch/arm64. This is a firmware interface,
just like PSCI, so it should live in drivers/firmware/ along with all
the other Arm firmware interfaces (SDEI, FFA, SCMI, PSCI, SMCCC, ...).

Will

^ permalink raw reply

* [Invitation] bi-weekly guest_memfd upstream call on 2026-07-23
From: Ackerley Tng @ 2026-07-21 23:07 UTC (permalink / raw)
  To: linux-coco, linux-mm, kvm

Hi,

Our next guest_memfd upstream call is scheduled for Thursday, 2026-07-23
at 8:00 - 9:00am (GMT-07:00) Pacific Time - Vancouver.

We'll be using the following Google meet:
http://meet.google.com/wxp-wtju-jzw

We don't have any scheduled topics as of now, please add topics!

The meeting notes can be found at [1], where we also link recordings and
collect current guest_memfd upstream proposals. If you want a Google
calendar invitation that also covers all future meetings, just write
Ackerley or David a mail.

To put something to discuss onto the agenda, reply to this mail or add
them to the "Topics/questions for next meeting(s)" section in the
meeting notes as a comment.

[1] https://docs.google.com/document/d/1M6766BzdY1Lhk7LiR5IqVR8B8mG3cr-cxTxOrAosPOk/edit?usp=sharing

Ackerley

^ permalink raw reply

* Re: [PATCH 01/15] netlink: specs: Introduce multi-message blobs for SPDM
From: Jakub Kicinski @ 2026-07-22  1:20 UTC (permalink / raw)
  To: Dan Williams
  Cc: linux-coco, linux-pci, driver-core, ankita, Alistair Francis,
	Lukas Wunner, Donald Hunter
In-Reply-To: <20260705220819.2472765-2-djbw@kernel.org>

On Sun,  5 Jul 2026 15:08:05 -0700 Dan Williams wrote:
> The SPDM, Security Protocol and Data Model, underpins PCI device security
> and other use cases. It defines objects that allow for verification of
> device identity and configuration. These objects can be large in size 16MB.
> Netlink is otherwise suitable to define the operations, with optional
> parameters, and notifications for working with these objects. For example,
> operations like "regenerate evidence with nonce", "mark evidence
> validated", and "broadcast evidence / security state change events".
> 
> A netlink 'blob' is introduced as a way to teach YNL that one instance of a
> attribute may span multiple messages. It enables netlink to convey all the
> data needed for verification and manipulation of SPDM transported evidence.
> 
> The schema change to allows YNL to infer that an attribute may span
> multiple messages and interrogate its length to preallocate an
> appropriately sized receive buffer.
> 
> The design direction to extend the netlink schema for a "multi-message
> object receive" case was the result of this discussion [1].

.. continuing the tradition of creative abuse of Netlink.

I don't like this, sorry. You need to come up with something outside
of netlink or more netlink-y.

^ permalink raw reply


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