Linux Confidential Computing Development
 help / color / mirror / Atom feed
* Re: [PATCH 1/2] x86/virt/tdx: Retrieve TDX module version
From: Edgecombe, Rick P @ 2026-01-08 20:18 UTC (permalink / raw)
  To: kvm@vger.kernel.org, linux-coco@lists.linux.dev, Verma, Vishal L,
	linux-kernel@vger.kernel.org
  Cc: Gao, Chao, bp@alien8.de, Huang, Kai, kas@kernel.org,
	dave.hansen@linux.intel.com, mingo@redhat.com, Williams, Dan J,
	tglx@linutronix.de, hpa@zytor.com, x86@kernel.org
In-Reply-To: <20260107-tdx_print_module_version-v1-1-822baa56762d@intel.com>

On Wed, 2026-01-07 at 17:31 -0700, Vishal Verma wrote:
> From: Chao Gao <chao.gao@intel.com>
> 
> Each TDX module has several bits of metadata about which specific TDX
> module it is. 
> 


> The primary bit of info is the version, which has an x.y.z
> format, where x represents the major version, y the minor version, and z
> the update version.
> 

A bit of a run-on sentence.

>  Knowing the running TDX Module version is valuable
> for bug reporting and debugging. Note that the module does expose other
> pieces of version-related metadata, such as build number and date. Those
> aren't retrieved for now, that can be added if needed in the future.
> 
> Retrieve the TDX Module version using the existing metadata reading
> interface. Later changes will expose this information. The metadata
> reading interfaces have existed for quite some time, so this will work
> with older versions of the TDX module as well - i.e. this isn't a new
> interface.
> 
> As a side note, the global metadata reading code was originally set up
> to be auto-generated from a JSON definition [1]. However, later [2] this
> was found to be unsustainable, and the autogeneration approach was
> dropped in favor of just manually adding fields as needed (e.g. as in
> this patch).
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Cc: Kai Huang <kai.huang@intel.com>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Link: https://lore.kernel.org/kvm/CABgObfYXUxqQV_FoxKjC8U3t5DnyM45nz5DpTxYZv2x_uFK_Kw@mail.gmail.com/ # [1]
> Link: https://lore.kernel.org/all/1e7bcbad-eb26-44b7-97ca-88ab53467212@intel.com/ # [2]
> ---
>  arch/x86/include/asm/tdx_global_metadata.h  |  7 +++++++
>  arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 16 ++++++++++++++++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/asm/tdx_global_metadata.h
> index 060a2ad744bff..40689c8dc67eb 100644
> --- a/arch/x86/include/asm/tdx_global_metadata.h
> +++ b/arch/x86/include/asm/tdx_global_metadata.h
> @@ -5,6 +5,12 @@
>  
>  #include <linux/types.h>
>  
> +struct tdx_sys_info_version {
> +	u16 minor_version;
> +	u16 major_version;
> +	u16 update_version;
> +};
> +
>  struct tdx_sys_info_features {
>  	u64 tdx_features0;
>  };
> @@ -35,6 +41,7 @@ struct tdx_sys_info_td_conf {
>  };
>  
>  struct tdx_sys_info {
> +	struct tdx_sys_info_version version;
>  	struct tdx_sys_info_features features;
>  	struct tdx_sys_info_tdmr tdmr;
>  	struct tdx_sys_info_td_ctrl td_ctrl;
> diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
> index 13ad2663488b1..0454124803f36 100644
> --- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
> +++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
> @@ -7,6 +7,21 @@
>   * Include this file to other C file instead.
>   */
>  
> +static int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_version)
> +{
> +	int ret = 0;
> +	u64 val;
> +
> +	if (!ret && !(ret = read_sys_metadata_field(0x0800000100000003, &val)))
> +		sysinfo_version->minor_version = val;
> +	if (!ret && !(ret = read_sys_metadata_field(0x0800000100000004, &val)))
> +		sysinfo_version->major_version = val;
> +	if (!ret && !(ret = read_sys_metadata_field(0x0800000100000005, &val)))
> +		sysinfo_version->update_version = val;
> +
> +	return ret;
> +}
> +
>  static int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo_features)
>  {
>  	int ret = 0;
> @@ -89,6 +104,7 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
>  {
>  	int ret = 0;
>  
> +	ret = ret ?: get_tdx_sys_info_version(&sysinfo->version);
>  	ret = ret ?: get_tdx_sys_info_features(&sysinfo->features);
>  	ret = ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr);
>  	ret = ret ?: get_tdx_sys_info_td_ctrl(&sysinfo->td_ctrl);
> 

Code looks good to me.

Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>

^ permalink raw reply

* Re: [PATCH 2/2] x86/virt/tdx: Print TDX module version during init
From: Verma, Vishal L @ 2026-01-08 18:39 UTC (permalink / raw)
  To: kas@kernel.org
  Cc: Gao, Chao, Edgecombe, Rick P, dave.hansen@linux.intel.com,
	Huang, Kai, x86@kernel.org, bp@alien8.de,
	linux-kernel@vger.kernel.org, Williams, Dan J, tglx@linutronix.de,
	kvm@vger.kernel.org, linux-coco@lists.linux.dev, hpa@zytor.com,
	mingo@redhat.com
In-Reply-To: <orjok4cskwinwuuqkyovqu7tkfygdkiqlxc2sbdvi2jicpygi4@dgg76ojxkhak>

On Thu, 2026-01-08 at 10:50 +0000, Kiryl Shutsemau wrote:
> On Wed, Jan 07, 2026 at 05:31:29PM -0700, Vishal Verma wrote:
> > It is useful to print the TDX module version in dmesg logs. This allows
> > for a quick spot check for whether the correct/expected TDX module is
> > being loaded, and also creates a record for any future problems being
> > investigated. This was also requested in [1].
> > 
> > Include the version in the log messages during init, e.g.:
> > 
> >   virt/tdx: TDX module version: 1.5.24
> >   virt/tdx: 1034220 KB allocated for PAMT
> >   virt/tdx: module initialized
> > 
> > ..followed by remaining TDX initialization messages (or errors).
> > 
> > Print the version early in init_tdx_module(), right after the global
> > metadata is read, which makes it available even if there are subsequent
> > initialization failures.
> 
> One thing to note that if metadata read fails, we will not get there.
> 
> The daisy chaining we use for metadata read makes it fragile. Some
> metadata fields are version/feature dependant, like you can see in DPAMT
> case.
> 
> It can be useful to dump version information, even if get_tdx_sys_info()
> fails. Version info is likely to be valid on failure.

Good point, maybe something like this to print it as soon as it is
retrieved?

---3<---

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index fba00ddc11f1..5ce4ebe99774 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1084,11 +1084,6 @@ static int init_tdx_module(void)
        if (ret)
                return ret;
 
-       pr_info("Module version: %u.%u.%02u\n",
-               tdx_sysinfo.version.major_version,
-               tdx_sysinfo.version.minor_version,
-               tdx_sysinfo.version.update_version);
-
        /* Check whether the kernel can support this module */
        ret = check_features(&tdx_sysinfo);
        if (ret)
diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
index 0454124803f3..4c9917a9c2c3 100644
--- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
+++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
@@ -105,6 +105,12 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
        int ret = 0;
 
        ret = ret ?: get_tdx_sys_info_version(&sysinfo->version);
+
+       pr_info("Module version: %u.%u.%02u\n",
+               sysinfo->version.major_version,
+               sysinfo->version.minor_version,
+               sysinfo->version.update_version);
+
        ret = ret ?: get_tdx_sys_info_features(&sysinfo->features);
        ret = ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr);
        ret = ret ?: get_tdx_sys_info_td_ctrl(&sysinfo->td_ctrl);


^ permalink raw reply related

* Re: [PATCH v4 04/16] x86/virt/tdx: Allocate page bitmap for Dynamic PAMT
From: Edgecombe, Rick P @ 2026-01-08 16:52 UTC (permalink / raw)
  To: yilun.xu@linux.intel.com
  Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, Huang, Kai,
	Li, Xiaoyao, Hansen, Dave, Zhao, Yan Y, Wu, Binbin,
	kas@kernel.org, seanjc@google.com, mingo@redhat.com,
	pbonzini@redhat.com, tglx@linutronix.de, Yamahata, Isaku,
	linux-kernel@vger.kernel.org, kirill.shutemov@linux.intel.com,
	Annapurve, Vishal, Gao, Chao, bp@alien8.de, x86@kernel.org
In-Reply-To: <aV+o1VOTxt8hU4ou@yilunxu-OptiPlex-7050>

On Thu, 2026-01-08 at 20:53 +0800, Xu Yilun wrote:
> I actually don't understand why a RDALL seamcall could eliminate
> the check "if (some_optional_feature_exists) read_it;". IIUC, The
> check
> exists because kernel doesn't trust TDX Module so kernel wants to
> verify
> the correctness/consistency of the data, otherwise we could accept
> whatever TDX Module tells us, do the below for each field:
> 
>   static int read_sys_metadata_field(u64 field_id, u64 *data)
>   {
> 	...
> 	ret = seamcall(TDH_SYS_RD, &args);
> 	if (ret == TDX_SUCCESS) {
> 		*data = args.r8;
> 		return 0;
> 	}
> 
> 	/* The field doesn't exist */
> 	if (ret == TDX_METADATA_FIELD_ID_INCORRECT) {
> 		*data = 0;
> 		return 0;
> 	}
> 
> 	...
> 
> 	/* Real reading error */
> 	return -EFAULT;
>   }
> 
> The trustness doesn't change no matter how kernel retrieves these
> data,
> by a series of RD or a RDALL.

Having it be field specific behavior (like the diff I posted) means we
don't need to worry about TDX module bugs where some field read fails
and we don't catch it.

By RDALL, I mean a simpler way to bulk read the metadata. So for future
looking changes, let's think about what we need and not try to find yet
more clever ways to code around the current interface. The amount of
code and discussion on TDX metadata reading is just too high. Please go
back and look at the earlier threads if you haven't yet.

^ permalink raw reply

* Re: [PATCH v2 03/11] coco: guest: arm64: Add support for guest initiated TDI bind/unbind
From: Will Deacon @ 2026-01-08 15:32 UTC (permalink / raw)
  To: Aneesh Kumar K.V (Arm)
  Cc: linux-coco, kvmarm, linux-pci, linux-kernel, dan.j.williams, aik,
	lukas, Samuel Ortiz, Xu Yilun, Jason Gunthorpe, Suzuki K Poulose,
	Steven Price, Bjorn Helgaas, Jonathan Cameron, Catalin Marinas,
	Marc Zyngier, Oliver Upton
In-Reply-To: <20251117140007.122062-4-aneesh.kumar@kernel.org>

On Mon, Nov 17, 2025 at 07:29:59PM +0530, Aneesh Kumar K.V (Arm) wrote:
> Add RHI for VDEV_SET_TDI_STATE
> 
> Note: This is not part of RHI spec. This is a POC implementation
> and will be later converted to correct interface defined by RHI.

Then maybe send this as an RFC given that it doesn't sound like something
we should be merging?

Will

^ permalink raw reply

* Re: [PATCH v4 04/16] x86/virt/tdx: Allocate page bitmap for Dynamic PAMT
From: Xu Yilun @ 2026-01-08 12:53 UTC (permalink / raw)
  To: Edgecombe, Rick P
  Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, Huang, Kai,
	Li, Xiaoyao, Hansen, Dave, Zhao, Yan Y, Wu, Binbin,
	kas@kernel.org, seanjc@google.com, mingo@redhat.com,
	pbonzini@redhat.com, tglx@linutronix.de, Yamahata, Isaku,
	linux-kernel@vger.kernel.org, kirill.shutemov@linux.intel.com,
	Annapurve, Vishal, Gao, Chao, bp@alien8.de, x86@kernel.org
In-Reply-To: <44fb20f8cfaa732eb34c3f5d3a3ff0c22c713939.camel@intel.com>

On Wed, Jan 07, 2026 at 02:41:44PM +0000, Edgecombe, Rick P wrote:
> On Wed, 2026-01-07 at 14:01 +0800, Xu Yilun wrote:
> > > I do think this is a good area for cleanup, but let's not overhaul
> > > it
> > > just to get a small incremental benefit. If we need a new interface
> > > in
> > 
> > Agree. I definitely don't want a new TDX module interface for now.
> 
> No, I was suggesting to think about a new TDX module interface if that
> is what it takes to really simplify it. For example, something like a
> consistent TDH.SYS.RDALL. For TDX module changes to be available in the

I actually don't understand why a RDALL seamcall could eliminate
the check "if (some_optional_feature_exists) read_it;". IIUC, The check
exists because kernel doesn't trust TDX Module so kernel wants to verify
the correctness/consistency of the data, otherwise we could accept
whatever TDX Module tells us, do the below for each field:

  static int read_sys_metadata_field(u64 field_id, u64 *data)
  {
	...
	ret = seamcall(TDH_SYS_RD, &args);
	if (ret == TDX_SUCCESS) {
		*data = args.r8;
		return 0;
	}

	/* The field doesn't exist */
	if (ret == TDX_METADATA_FIELD_ID_INCORRECT) {
		*data = 0;
		return 0;
	}

	...

	/* Real reading error */
	return -EFAULT;
  }

The trustness doesn't change no matter how kernel retrieves these data,
by a series of RD or a RDALL.

Thanks,
Yilun

> future (for example at the time of the other optional metadata), we
> actually need to start the process now.

^ permalink raw reply

* Re: [PATCH] dma-direct: swiotlb: Skip encryption toggles for swiotlb allocations
From: Robin Murphy @ 2026-01-08 11:01 UTC (permalink / raw)
  To: Aneesh Kumar K.V (Arm), iommu, linux-kernel, linux-coco
  Cc: Marek Szyprowski, steven.price, Suzuki K Poulose
In-Reply-To: <20260102155448.2554240-1-aneesh.kumar@kernel.org>

On 2026-01-02 3:54 pm, Aneesh Kumar K.V (Arm) wrote:
> Swiotlb backing pages are already mapped decrypted via
> swiotlb_update_mem_attributes(), so dma-direct does not need to call
> set_memory_decrypted() during allocation or re-encrypt the memory on
> free.
> 
> Handle swiotlb-backed buffers explicitly: obtain the DMA address and
> zero the linear mapping for lowmem pages, and bypass the decrypt/encrypt
> transitions when allocating/freeing from the swiotlb pool (detected via
> swiotlb_find_pool()).

swiotlb_update_mem_attributes() only applies to the default SWIOTLB 
buffer, while the dma_direct_alloc_swiotlb() path is only for private 
restricted pools (because the whole point is that restricted DMA devices 
cannot use the regular allocator/default pools). There is no redundancy 
here AFAICS.

Thanks,
Robin.

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


^ permalink raw reply

* Re: [PATCH 2/2] x86/virt/tdx: Print TDX module version during init
From: Kiryl Shutsemau @ 2026-01-08 10:50 UTC (permalink / raw)
  To: Vishal Verma
  Cc: linux-kernel, linux-coco, kvm, x86, Chao Gao, Dan Williams,
	Kai Huang, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, H. Peter Anvin, Rick Edgecombe
In-Reply-To: <20260107-tdx_print_module_version-v1-2-822baa56762d@intel.com>

On Wed, Jan 07, 2026 at 05:31:29PM -0700, Vishal Verma wrote:
> It is useful to print the TDX module version in dmesg logs. This allows
> for a quick spot check for whether the correct/expected TDX module is
> being loaded, and also creates a record for any future problems being
> investigated. This was also requested in [1].
> 
> Include the version in the log messages during init, e.g.:
> 
>   virt/tdx: TDX module version: 1.5.24
>   virt/tdx: 1034220 KB allocated for PAMT
>   virt/tdx: module initialized
> 
> ..followed by remaining TDX initialization messages (or errors).
> 
> Print the version early in init_tdx_module(), right after the global
> metadata is read, which makes it available even if there are subsequent
> initialization failures.

One thing to note that if metadata read fails, we will not get there.

The daisy chaining we use for metadata read makes it fragile. Some
metadata fields are version/feature dependant, like you can see in DPAMT
case.

It can be useful to dump version information, even if get_tdx_sys_info()
fails. Version info is likely to be valid on failure.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov

^ permalink raw reply

* Re: [PATCH 1/2] x86/virt/tdx: Retrieve TDX module version
From: Kiryl Shutsemau @ 2026-01-08 10:41 UTC (permalink / raw)
  To: Vishal Verma
  Cc: linux-kernel, linux-coco, kvm, x86, Chao Gao, Dan Williams,
	Kai Huang, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, H. Peter Anvin, Rick Edgecombe
In-Reply-To: <20260107-tdx_print_module_version-v1-1-822baa56762d@intel.com>

On Wed, Jan 07, 2026 at 05:31:28PM -0700, Vishal Verma wrote:
> From: Chao Gao <chao.gao@intel.com>
> 
> Each TDX module has several bits of metadata about which specific TDX
> module it is. The primary bit of info is the version, which has an x.y.z
> format, where x represents the major version, y the minor version, and z
> the update version. Knowing the running TDX Module version is valuable
> for bug reporting and debugging. Note that the module does expose other
> pieces of version-related metadata, such as build number and date. Those
> aren't retrieved for now, that can be added if needed in the future.
> 
> Retrieve the TDX Module version using the existing metadata reading
> interface. Later changes will expose this information. The metadata
> reading interfaces have existed for quite some time, so this will work
> with older versions of the TDX module as well - i.e. this isn't a new
> interface.
> 
> As a side note, the global metadata reading code was originally set up
> to be auto-generated from a JSON definition [1]. However, later [2] this
> was found to be unsustainable, and the autogeneration approach was
> dropped in favor of just manually adding fields as needed (e.g. as in
> this patch).
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
> Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
> Cc: Kai Huang <kai.huang@intel.com>
> Cc: Dave Hansen <dave.hansen@linux.intel.com>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Link: https://lore.kernel.org/kvm/CABgObfYXUxqQV_FoxKjC8U3t5DnyM45nz5DpTxYZv2x_uFK_Kw@mail.gmail.com/ # [1]
> Link: https://lore.kernel.org/all/1e7bcbad-eb26-44b7-97ca-88ab53467212@intel.com/ # [2]
> ---
>  arch/x86/include/asm/tdx_global_metadata.h  |  7 +++++++
>  arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 16 ++++++++++++++++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/asm/tdx_global_metadata.h
> index 060a2ad744bff..40689c8dc67eb 100644
> --- a/arch/x86/include/asm/tdx_global_metadata.h
> +++ b/arch/x86/include/asm/tdx_global_metadata.h
> @@ -5,6 +5,12 @@
>  
>  #include <linux/types.h>
>  
> +struct tdx_sys_info_version {
> +	u16 minor_version;
> +	u16 major_version;
> +	u16 update_version;
> +};
> +
>  struct tdx_sys_info_features {
>  	u64 tdx_features0;
>  };
> @@ -35,6 +41,7 @@ struct tdx_sys_info_td_conf {
>  };
>  
>  struct tdx_sys_info {
> +	struct tdx_sys_info_version version;

Creates a 2 byte hole. Just enough to squeeze INTERNAL_VERSION there.
Just saying :P

But patch looks good to me:

Reviewed-by: Kiryl Shutsemau <kas@kernel.org>

-- 
  Kiryl Shutsemau / Kirill A. Shutemov

^ permalink raw reply

* Re: SVSM Development Call January 7th, 2026
From: Jörg Rödel @ 2026-01-08  9:21 UTC (permalink / raw)
  To: coconut-svsm, linux-coco
In-Reply-To: <7eiztvv2iuki3feczlj7wksll2hdh7buttz7k26llsger2qkwf@wfa2sidzim63>

PR with meeting minutes is now posted:

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

Regards,

	Joerg

^ permalink raw reply

* RE: [EXTERNAL] Re: "Paravisor" Feature Enumeration
From: Jon Lange @ 2026-01-08  6:53 UTC (permalink / raw)
  To: dan.j.williams@intel.com, Andrew Cooper, Dave Hansen
  Cc: Sean Christopherson, Paolo Bonzini, John Starks, Will Deacon,
	Mark Rutland, linux-coco@lists.linux.dev, LKML, Edgecombe, Rick P
In-Reply-To: <695ea905645a0_4b7a1008e@dwillia2-mobl4.notmuch>

Dan, thanks for taking the time to clarify what you meant by PV.  I couldn't tell whether you were talking about paravisor functionality or paravirtualization operations, and now I get what you mean.

You wrote:

> So, I was trying to get to the actual ops that need to be intercepted, and whether
> every operation that this paravisor wants to intercept already has an existing
> indirection or what new indirections need to be built. This probably becomes
> clearer when you have some time to build an RFC, but the array of operations to
> touch exceeds traditional paravirt hooks.
> So, for example, paravirt ops do handle MSR virtualization:

In the case of MSR - or anything else that's part of the core ISA - the paravisor handles this all transparently as part of its role as virtualization support - just like a hypervisor would do (again, that's part of the definition of paravisor mode).  I suspect the pv_ops structure you describe for MSR is designed to handle the abstractions around GHCB/GHCI for fully enlightened VMs, but in the case of a paravisor, the native RDMSR/WRMSR instructions work as expected so no paravirtualization is required.  In the paravisor scenario, this is true for every aspect of basic system execution.  Again, this is part of the core value of the paravisor: it just takes care of everything so the OS doesn't have to understand anything special about the confidential architecture.  To the extent that any pv_ops are required, they should just follow an existing virtualization path, because the paravisor is designed to mirror an established virtualization model.

> So my curiosity is whether there are other operations to capture that are
> buried deeper in the arch implementations that do not have abstractions
> today. Again, that is probably best addressed by an RFC implementation.

This is the big question, and I agree that we're not going to get very far until we start building real code.  In the example of attestation, I suspect that nothing special is required; the existing SNP and TDX platform services used by the OS should work transparently when running under a paravisor; SNP_GUEST_REQUEST over GHCB should behave as expected, and TDG.MR.REPORT will be intercepted and emulated by the L1, so no new convention should be required in either case.  The Arm CCA Planes architecture is not mature enough yet to be a firm basis for conjecture about how attestation report requests are managed, but I expect it to follow the same pattern as TDX and therefore should also work transparently.

The TDISP scenarios are much less clear, due in no small part to the fact that there is no code in the kernel yet to handle TDISP even for fully enlightened guests (as you are keenly aware).  As we design those interfaces for fully enlightened guests, it wouldn't be a bad idea to discuss how they would be handled in the paravisor case so we can minimize the need for pv_ops to handle the various configurations, but I don't want to predict how this unfolds until we actually have a real design for what TDISP negotiation will look like in at least one configuration.

-Jon

-----Original Message-----
From: dan.j.williams@intel.com <dan.j.williams@intel.com> 
Sent: Wednesday, January 7, 2026 10:42 AM
To: Jon Lange <jlange@microsoft.com>; dan.j.williams@intel.com; Andrew Cooper <andrew.cooper3@citrix.com>; Dave Hansen <dave.hansen@intel.com>
Cc: Sean Christopherson <seanjc@google.com>; Paolo Bonzini <pbonzini@redhat.com>; John Starks <John.Starks@microsoft.com>; Will Deacon <will@kernel.org>; Mark Rutland <mark.rutland@arm.com>; linux-coco@lists.linux.dev; LKML <linux-kernel@vger.kernel.org>; Edgecombe, Rick P <rick.p.edgecombe@intel.com>
Subject: RE: [EXTERNAL] Re: "Paravisor" Feature Enumeration

Jon Lange wrote:
> Dan W wrote:
> 
> > It sounds like the paravisor is going to hide confidential memory 
> > management details like page-acceptance, but it is going to 
> > advertise and intercept higher order operations like generate launch 
> > attestation report and TDISP paths like lock device, get device 
> > report, accept/run device.
> 
> I think that's roughly the right mental model.  The paravisor will 
> additionally hide confidential details like MSR virtualization, I/O 
> and MMIO handling, CPUID virtualization - all of the sorts of things 
> that would generate #VE/#VC exceptions in a fully enlightened guest so 
> that the guest doesn't have to worry about those, and the paravisor 
> can provide useful functionality (like device emulation or 
> hypervisor-type functionality) through those primitives.

Ah, anything that causes #VE/#VC helps, thanks.

> > So does this paravisor need low level intercepts via pv_ops and a 
> > confidential memory-management model independent of TDX/SNP etc? Or, 
> > does it only need the higher order common "services" like 
> > attestation and TDISP.
> 
> I'm not following your question - I don't understand what you're 
> envisioning when you describe confidential memory management 
> independent of TDX/SNP.  It is the case that the paravisor is 
> responsible for the confidentiality state of all memory, and therefore 
> it will have some implementation to fulfill this responsibility.  It's 
> natural for it to do so because its own operation has to integrate 
> with the state of memory.  Following my earlier analogy that the 
> paravisor acts like a nested hypervisor for a single (confidential) 
> guest, the paravisor itself will have to implement all of the services 
> necessary to satisfy the virtualization requirements of an 
> unenlightened guest, which is far more than the "common services" that 
> you mention.  Can you give some other examples of the sort of 
> distinction you're trying to highlight?

So, I was trying to get to the actual ops that need to be intercepted, and whether every operation that this paravisor wants to intercept already has an existing indirection or what new indirections need to be built. This probably becomes clearer when you have some time to build an RFC, but the array of operations to touch exceeds traditional paravirt hooks.

So, for example, paravirt ops do handle MSR virtualization:

struct pv_cpu_ops {
...
        u64 (*read_msr)(u32 msr);
        void (*write_msr)(u32 msr, u64 val); ...
};

Other operations are outside of paravirt hooks but do have generic abstractions, like these for encrypted memory:

struct x86_guest {
        int (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
        int (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
        bool (*enc_tlb_flush_required)(bool enc);
        bool (*enc_cache_flush_required)(void);
        void (*enc_kexec_begin)(void);
        void (*enc_kexec_finish)(void);
};

For attestation operations this effort would need to register its own tsm_report interface:

tsm_report_register(...)

...and for TDISP it would probably need to register its own TSM device:

struct_group_tagged(pci_tsm_devsec_ops, devsec_ops,
	struct pci_tsm *(*lock)(struct tsm_dev *tsm_dev,
				struct pci_dev *pdev);
	void (*unlock)(struct pci_tsm *tsm);
	int (*accept)(struct pci_dev *pdev);
);

So my curiosity is whether there are other operations to capture that are buried deeper in the arch implementations that do not have abstractions today. Again, that is probably best addressed by an RFC implementation.

^ permalink raw reply

* [PATCH 2/2] x86/virt/tdx: Print TDX module version during init
From: Vishal Verma @ 2026-01-08  0:31 UTC (permalink / raw)
  To: linux-kernel, linux-coco, kvm
  Cc: x86, Chao Gao, Dan Williams, Kai Huang, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin,
	Kiryl Shutsemau, Rick Edgecombe, Vishal Verma
In-Reply-To: <20260107-tdx_print_module_version-v1-0-822baa56762d@intel.com>

It is useful to print the TDX module version in dmesg logs. This allows
for a quick spot check for whether the correct/expected TDX module is
being loaded, and also creates a record for any future problems being
investigated. This was also requested in [1].

Include the version in the log messages during init, e.g.:

  virt/tdx: TDX module version: 1.5.24
  virt/tdx: 1034220 KB allocated for PAMT
  virt/tdx: module initialized

..followed by remaining TDX initialization messages (or errors).

Print the version early in init_tdx_module(), right after the global
metadata is read, which makes it available even if there are subsequent
initialization failures.

Based on a patch by Kai Huang <kai.huang@intel.com> [2]

Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Reviewed-by: Chao Gao <chao.gao@intel.com>
Cc: Chao Gao <chao.gao@intel.com>
Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
Cc: Kai Huang <kai.huang@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/all/CAGtprH8eXwi-TcH2+-Fo5YdbEwGmgLBh9ggcDvd6N=bsKEJ_WQ@mail.gmail.com/ # [1]
Link: https://lore.kernel.org/all/6b5553756f56a8e3222bfc36d0bdb3e5192137b7.1731318868.git.kai.huang@intel.com # [2]
---
 arch/x86/virt/vmx/tdx/tdx.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
index 5ce4ebe99774..fba00ddc11f1 100644
--- a/arch/x86/virt/vmx/tdx/tdx.c
+++ b/arch/x86/virt/vmx/tdx/tdx.c
@@ -1084,6 +1084,11 @@ static int init_tdx_module(void)
 	if (ret)
 		return ret;
 
+	pr_info("Module version: %u.%u.%02u\n",
+		tdx_sysinfo.version.major_version,
+		tdx_sysinfo.version.minor_version,
+		tdx_sysinfo.version.update_version);
+
 	/* Check whether the kernel can support this module */
 	ret = check_features(&tdx_sysinfo);
 	if (ret)

-- 
2.52.0


^ permalink raw reply related

* [PATCH 1/2] x86/virt/tdx: Retrieve TDX module version
From: Vishal Verma @ 2026-01-08  0:31 UTC (permalink / raw)
  To: linux-kernel, linux-coco, kvm
  Cc: x86, Chao Gao, Dan Williams, Kai Huang, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin,
	Kiryl Shutsemau, Rick Edgecombe, Vishal Verma
In-Reply-To: <20260107-tdx_print_module_version-v1-0-822baa56762d@intel.com>

From: Chao Gao <chao.gao@intel.com>

Each TDX module has several bits of metadata about which specific TDX
module it is. The primary bit of info is the version, which has an x.y.z
format, where x represents the major version, y the minor version, and z
the update version. Knowing the running TDX Module version is valuable
for bug reporting and debugging. Note that the module does expose other
pieces of version-related metadata, such as build number and date. Those
aren't retrieved for now, that can be added if needed in the future.

Retrieve the TDX Module version using the existing metadata reading
interface. Later changes will expose this information. The metadata
reading interfaces have existed for quite some time, so this will work
with older versions of the TDX module as well - i.e. this isn't a new
interface.

As a side note, the global metadata reading code was originally set up
to be auto-generated from a JSON definition [1]. However, later [2] this
was found to be unsustainable, and the autogeneration approach was
dropped in favor of just manually adding fields as needed (e.g. as in
this patch).

Signed-off-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Cc: Rick Edgecombe <rick.p.edgecombe@intel.com>
Cc: Kai Huang <kai.huang@intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Link: https://lore.kernel.org/kvm/CABgObfYXUxqQV_FoxKjC8U3t5DnyM45nz5DpTxYZv2x_uFK_Kw@mail.gmail.com/ # [1]
Link: https://lore.kernel.org/all/1e7bcbad-eb26-44b7-97ca-88ab53467212@intel.com/ # [2]
---
 arch/x86/include/asm/tdx_global_metadata.h  |  7 +++++++
 arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 16 ++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/arch/x86/include/asm/tdx_global_metadata.h b/arch/x86/include/asm/tdx_global_metadata.h
index 060a2ad744bff..40689c8dc67eb 100644
--- a/arch/x86/include/asm/tdx_global_metadata.h
+++ b/arch/x86/include/asm/tdx_global_metadata.h
@@ -5,6 +5,12 @@
 
 #include <linux/types.h>
 
+struct tdx_sys_info_version {
+	u16 minor_version;
+	u16 major_version;
+	u16 update_version;
+};
+
 struct tdx_sys_info_features {
 	u64 tdx_features0;
 };
@@ -35,6 +41,7 @@ struct tdx_sys_info_td_conf {
 };
 
 struct tdx_sys_info {
+	struct tdx_sys_info_version version;
 	struct tdx_sys_info_features features;
 	struct tdx_sys_info_tdmr tdmr;
 	struct tdx_sys_info_td_ctrl td_ctrl;
diff --git a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
index 13ad2663488b1..0454124803f36 100644
--- a/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
+++ b/arch/x86/virt/vmx/tdx/tdx_global_metadata.c
@@ -7,6 +7,21 @@
  * Include this file to other C file instead.
  */
 
+static int get_tdx_sys_info_version(struct tdx_sys_info_version *sysinfo_version)
+{
+	int ret = 0;
+	u64 val;
+
+	if (!ret && !(ret = read_sys_metadata_field(0x0800000100000003, &val)))
+		sysinfo_version->minor_version = val;
+	if (!ret && !(ret = read_sys_metadata_field(0x0800000100000004, &val)))
+		sysinfo_version->major_version = val;
+	if (!ret && !(ret = read_sys_metadata_field(0x0800000100000005, &val)))
+		sysinfo_version->update_version = val;
+
+	return ret;
+}
+
 static int get_tdx_sys_info_features(struct tdx_sys_info_features *sysinfo_features)
 {
 	int ret = 0;
@@ -89,6 +104,7 @@ static int get_tdx_sys_info(struct tdx_sys_info *sysinfo)
 {
 	int ret = 0;
 
+	ret = ret ?: get_tdx_sys_info_version(&sysinfo->version);
 	ret = ret ?: get_tdx_sys_info_features(&sysinfo->features);
 	ret = ret ?: get_tdx_sys_info_tdmr(&sysinfo->tdmr);
 	ret = ret ?: get_tdx_sys_info_td_ctrl(&sysinfo->td_ctrl);

-- 
2.52.0


^ permalink raw reply related

* [PATCH 0/2] x86/virt/tdx: Print TDX module version to dmesg
From: Vishal Verma @ 2026-01-08  0:31 UTC (permalink / raw)
  To: linux-kernel, linux-coco, kvm
  Cc: x86, Chao Gao, Dan Williams, Kai Huang, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, Dave Hansen, H. Peter Anvin,
	Kiryl Shutsemau, Rick Edgecombe, Vishal Verma

=== Problem & Solution ===

Currently, there is neither an ABI, nor any other way to determine from
the host system, what version of the TDX module is running. A sysfs ABI
for this has been proposed in [1], but it may need additional discussion.

Many/most TDX developers already carry patches like this in their
development branches. It can be tricky to know which TDX module is
actually loaded on a system, and so this functionality has been needed
regularly for development and processing bug reports. Hence, it is
prudent to break out the patches to retrieve and print the TDX module
version, as those parts are very straightforward, and get some level of
debugability and traceability for TDX host systems.

=== Dependencies ===

None. This is based on v6.19-rc4, and applies cleanly to tip.git.

=== Patch details ===

Patch 1 is a prerequisite that adds the infrastructure to retrieve the
TDX module version from its global metadata. This was originally posted in [2].

Patch 2 is based on a patch from Kai Huang [3], and prints the version to
dmesg during init.

=== Testing ===

This has passed the usual suite of tests, including successful 0day
builds, KVM Unit tests, KVM selftests, a TD creation smoke test, and
selected KVM tests from the Avocado test suite.

[1]: https://lore.kernel.org/all/20260105074350.98564-1-chao.gao@intel.com/
[2]: https://lore.kernel.org/all/20260105074350.98564-2-chao.gao@intel.com/
[3]: https://lore.kernel.org/all/57eaa1b17429315f8b5207774307f3c1dd40cf37.1730118186.git.kai.huang@intel.com/

Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
---
Chao Gao (1):
      x86/virt/tdx: Retrieve TDX module version

Vishal Verma (1):
      x86/virt/tdx: Print TDX module version during init

 arch/x86/include/asm/tdx_global_metadata.h  |  7 +++++++
 arch/x86/virt/vmx/tdx/tdx.c                 |  5 +++++
 arch/x86/virt/vmx/tdx/tdx_global_metadata.c | 16 ++++++++++++++++
 3 files changed, 28 insertions(+)
---
base-commit: 9ace4753a5202b02191d54e9fdf7f9e3d02b85eb
change-id: 20260107-tdx_print_module_version-e4ca7edc2022

Best regards,
--  
Vishal Verma <vishal.l.verma@intel.com>


^ permalink raw reply

* Re: [PATCH v2 0/3] Expose TDX Module version
From: Dave Hansen @ 2026-01-07 22:26 UTC (permalink / raw)
  To: dan.j.williams, Kiryl Shutsemau
  Cc: Chao Gao, kvm, linux-coco, linux-kernel, x86, vishal.l.verma,
	kai.huang, yilun.xu, vannapurve, Borislav Petkov, Dave Hansen,
	H. Peter Anvin, Ingo Molnar, Rick Edgecombe, Thomas Gleixner
In-Reply-To: <695ed1604db38_4b7a10028@dwillia2-mobl4.notmuch>

On 1/7/26 13:34, dan.j.williams@intel.com wrote:
> For sake of argument, I assume you have no fundamental objection to
> module version information in sysfs in general? I.e. is the question
> more on the where and how for TDX sysfs?

For reference, and so the next poster can write an excellent and focused
changelog wherever this goes, the context I was yearning for in the
changelog was:

1. AMD has a PCI device for the PSP for SEV which provides an existing
   place to hang their equivalent metadata. TDX has no PCI device.
2. ARM CCA will likely have a faux device (although it isn't obvious if
   they have a need to export version information there)
3. The TDX faux device will drive TDX module updates. The version number
   is obviously deeply important to entities doing updates.

So, no, I don't have a fundamental objection to having TDX module
version information in sysfs. But, in the context of this series, I
don't see any incremental value for doing it in addition to dmesg _now_.
If the module updater userspace needs it, then I'd rather defer the
sysfs export (and faux device creation) until the time that there's an
actual concrete user.

^ permalink raw reply

* [Invitation] bi-weekly guest_memfd upstream call on 2026-01-08
From: David Hildenbrand (Red Hat) @ 2026-01-07 22:01 UTC (permalink / raw)
  To: linux-coco@lists.linux.dev, linux-mm@kvack.org, KVM

Hi,

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

Ackerley will lead this meeting as I am on PTO (and apparently yet 
writing this mail :) ). I might still join, though.

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

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

In this meeting, we'll cover:

(1) Updates from LPC
(2) Private-only guest_memfd THP for testing purposes (continuation from
     previous discussions)

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

-- 
Cheers

David




^ permalink raw reply

* Re: [Invitation] bi-weekly guest_memfd upstream call on 2025-12-04
From: David Hildenbrand (Red Hat) @ 2026-01-07 21:52 UTC (permalink / raw)
  To: dan.j.williams, linux-coco@lists.linux.dev, linux-mm@kvack.org,
	KVM
  Cc: Ackerley Tng
In-Reply-To: <695ec54cf5c3_875d1009d@dwillia2-mobl4.notmuch>

On 1/7/26 21:42, dan.j.williams@intel.com wrote:
> David Hildenbrand (Red Hat) wrote:
> [..]
>> This might be the last meeting this year: I will be traveling for LPC on
>> December 11 and December 18. Then, Christmas is already around the
>> corner and we'll skip the one on December 25. So we'll probably have our
>> next meeting then on January 8.
> 
> Hi David,

Hi Dan!

> 
> Great seeing you at LPC! 

Absolutely :)

> Can I grab some time on the agenda to
> brainstorm the next level of detail on the topic I briefly ran by you in
> the hallway track? I.e. is there a path to decouple dependencies and
> land some of the low level huge page support upstream while the
> guest_memfd reworks for in place conversion and hugetlbfs backing
> continue to mature?

Yes, Ackerley already added that to the meeting agenda :)

> 
> As you said this at a minimum needs to be crippled / not production
> worthy to maintain focus and momentum on the guest_memfd rework
> completion. The observation that shifted my thinking is that, given the
> timelines and remaining work, there are solid steps that the low level
> implementations can be landing and maturing in advance of that
> integration. All net progress for upstream.

Right, I think we're good as long as we don't start splitting folios on 
partial truncation. That is: only allow truncation in THP granularity.

I might not be around tomorrow and Ackerley will likely lead the 
meeting. I'll send out a reminder mail now that I realize I haven't ...

-- 
Cheers

David

^ permalink raw reply

* Re: [PATCH v2 0/3] Expose TDX Module version
From: dan.j.williams @ 2026-01-07 21:34 UTC (permalink / raw)
  To: Dave Hansen, Kiryl Shutsemau
  Cc: Chao Gao, kvm, linux-coco, linux-kernel, x86, vishal.l.verma,
	kai.huang, dan.j.williams, yilun.xu, vannapurve, Borislav Petkov,
	Dave Hansen, H. Peter Anvin, Ingo Molnar, Rick Edgecombe,
	Thomas Gleixner
In-Reply-To: <7cbac499-6145-4b83-873c-c2d283f9cb79@intel.com>

Dave Hansen wrote:
[..]
> Since there's a dearth of discussion of this topic in the changelog or
> cover letter, my working assumption is that Chao did not consider any of
> this before posting.

Unfortunately that is incorrect, harsh, but somewhat forgivable because
features like TDX module update and the PCI device security stuff
stretch the boundaries of what tip.git historically needed to worry
about.

For example, the equivalent on the SNP side goes through
drivers/crypto/ccp/ which sometimes Boris takes changes through tip.git,
but many other commits, for features like "update device firmware" and
"PCI device security", go through crypto.git and now tsm.git. Case in
point, nobody in tip.git land had cause to even glance at commits like:

    2e424c33d8e7 crypto: ccp - Add support for displaying PSP firmware versions

I do not know where your specific objection lies so I am going to start
from the beginning summarizing all the discussions had around this to
date, some off list, some on list [1]. Chao has been involved in those
from the beginning and threw a fair share of consideration logs into the
fire.

The main problem for TDX with respect to the considered features of:

- sysfs to display some module metadata
- sysfs to mediate module update
- device + driver to coordinate PCI device security 

Is that TDX does not come with a device enumeration. It has no ACPI
description, it only has CPUID. Note, that at least puts TDX in a more
comfortable position than ARM which is also struggling with the "where
do we hang a useful device abstraction for this software pseudo
hypervisor thingy that controls confidential computing".

For sake of argument, I assume you have no fundamental objection to
module version information in sysfs in general? I.e. is the question
more on the where and how for TDX sysfs?

Note that back in March of last year there was this nak from me on the
proposal for something like a custom crafted /sys/hypervisor hierarchy
[2]. I still hold the same position today that all these archs are to
have widely different ways to enumerate their capabilities.  Anything
implementation specific should hang off an implementation specific
device. Everything else that is cross-arch should create a shared class
device. We now have that "shared class device" upstream via
tsm_register() [3].

For TDX the question is what is the best path to create a device
abstraction for a technology that does not come with a PCI device nor a
firmware enumerated platform device. The faux device infrastructure was
purpose built for cases like this. Now, faux device arrived in February
after I had sent out my original "tdx_subsys" proposal in January [1].
While I found the /sys/devices/faux path prefix somewhat unsavory
compared to /sys/devices/virtual, the implementation does exactly what
is needed and avoids the abuses of /sys/devices/platform that would
usually result from cases like this.

It turns out ARM is strongly recommended to go the faux device route as
well [4], so if you have other ideas here you have some work ahead to
undo some standing consensus.

As for which patch set should introduce this new device, I am in favor
of following Chao's lead here. Land the least controversial of all
possible TDX module metadata to publish in sysfs, a version string.
This simple infrastructure unblocks the path for the module update and
PCI device security features. Those add more attributes, a fw_upload
instance, and an idiomatic driver model for the tail of TDX features
that are more suitable for driver enabling than core-x86 enabling.

Yes, you were not directly copied on any of the references I have below,
yes you are free to have an opinion on proposals you are not copied.
However, going forward I would like to negotiate some working model
similar to the tip.git relationship to drivers/crypto/ccp/, and work on
how to avoid surprises like this in the future.

[1]: Earliest on list concept of needing device infrastructure for TDX
features: http://lore.kernel.org/170660662589.224441.11503798303914595072.stgit@dwillia2-xfh.jf.intel.com
[2]: http://lore.kernel.org/67d4bee77313a_12e31294c7@dwillia2-xfh.jf.intel.com.notmuch
[3]: http://lore.kernel.org/20251031212902.2256310-2-dan.j.williams@intel.com
[4]: http://lore.kernel.org/2025073035-bulginess-rematch-b92e@gregkh

^ permalink raw reply

* Re: [Invitation] bi-weekly guest_memfd upstream call on 2025-12-04
From: dan.j.williams @ 2026-01-07 20:42 UTC (permalink / raw)
  To: David Hildenbrand (Red Hat), linux-coco@lists.linux.dev,
	linux-mm@kvack.org, KVM
In-Reply-To: <66c32ad4-a59a-425e-8a00-bcfb918e7559@kernel.org>

David Hildenbrand (Red Hat) wrote:
[..]
> This might be the last meeting this year: I will be traveling for LPC on 
> December 11 and December 18. Then, Christmas is already around the 
> corner and we'll skip the one on December 25. So we'll probably have our 
> next meeting then on January 8.

Hi David,

Great seeing you at LPC! Can I grab some time on the agenda to
brainstorm the next level of detail on the topic I briefly ran by you in
the hallway track? I.e. is there a path to decouple dependencies and
land some of the low level huge page support upstream while the
guest_memfd reworks for in place conversion and hugetlbfs backing
continue to mature?

As you said this at a minimum needs to be crippled / not production
worthy to maintain focus and momentum on the guest_memfd rework
completion. The observation that shifted my thinking is that, given the
timelines and remaining work, there are solid steps that the low level
implementations can be landing and maturing in advance of that
integration. All net progress for upstream.

^ permalink raw reply

* RE: [EXTERNAL] Re: "Paravisor" Feature Enumeration
From: dan.j.williams @ 2026-01-07 18:42 UTC (permalink / raw)
  To: Jon Lange, dan.j.williams@intel.com, Andrew Cooper, Dave Hansen
  Cc: Sean Christopherson, Paolo Bonzini, John Starks, Will Deacon,
	Mark Rutland, linux-coco@lists.linux.dev, LKML, Edgecombe, Rick P
In-Reply-To: <CH8PR21MB5222DB4477497784FC170791CA84A@CH8PR21MB5222.namprd21.prod.outlook.com>

Jon Lange wrote:
> Dan W wrote:
> 
> > It sounds like the paravisor is going to hide confidential memory
> > management details like page-acceptance, but it is going to advertise
> > and intercept higher order operations like generate launch attestation
> > report and TDISP paths like lock device, get device report, accept/run
> > device.
> 
> I think that's roughly the right mental model.  The paravisor will
> additionally hide confidential details like MSR virtualization, I/O
> and MMIO handling, CPUID virtualization - all of the sorts of things
> that would generate #VE/#VC exceptions in a fully enlightened guest so
> that the guest doesn't have to worry about those, and the paravisor
> can provide useful functionality (like device emulation or
> hypervisor-type functionality) through those primitives.

Ah, anything that causes #VE/#VC helps, thanks.

> > So does this paravisor need low level intercepts via pv_ops and a
> > confidential memory-management model independent of TDX/SNP etc? Or,
> > does it only need the higher order common "services" like attestation
> > and TDISP.
> 
> I'm not following your question - I don't understand what you're
> envisioning when you describe confidential memory management
> independent of TDX/SNP.  It is the case that the paravisor is
> responsible for the confidentiality state of all memory, and therefore
> it will have some implementation to fulfill this responsibility.  It's
> natural for it to do so because its own operation has to integrate
> with the state of memory.  Following my earlier analogy that the
> paravisor acts like a nested hypervisor for a single (confidential)
> guest, the paravisor itself will have to implement all of the services
> necessary to satisfy the virtualization requirements of an
> unenlightened guest, which is far more than the "common services" that
> you mention.  Can you give some other examples of the sort of
> distinction you're trying to highlight?

So, I was trying to get to the actual ops that need to be intercepted,
and whether every operation that this paravisor wants to intercept
already has an existing indirection or what new indirections need to be
built. This probably becomes clearer when you have some time to build an
RFC, but the array of operations to touch exceeds traditional paravirt
hooks.

So, for example, paravirt ops do handle MSR virtualization:

struct pv_cpu_ops {
...
        u64 (*read_msr)(u32 msr);
        void (*write_msr)(u32 msr, u64 val);
...
};

Other operations are outside of paravirt hooks but do have generic
abstractions, like these for encrypted memory:

struct x86_guest {
        int (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc);
        int (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc);
        bool (*enc_tlb_flush_required)(bool enc);
        bool (*enc_cache_flush_required)(void);
        void (*enc_kexec_begin)(void);
        void (*enc_kexec_finish)(void);
};

For attestation operations this effort would need to register its own
tsm_report interface:

tsm_report_register(...)

...and for TDISP it would probably need to register its own TSM device:

struct_group_tagged(pci_tsm_devsec_ops, devsec_ops,
	struct pci_tsm *(*lock)(struct tsm_dev *tsm_dev,
				struct pci_dev *pdev);
	void (*unlock)(struct pci_tsm *tsm);
	int (*accept)(struct pci_dev *pdev);
);

So my curiosity is whether there are other operations to capture that
are buried deeper in the arch implementations that do not have
abstractions today. Again, that is probably best addressed by an RFC
implementation.

^ permalink raw reply

* Re: [PATCH v4 04/16] x86/virt/tdx: Allocate page bitmap for Dynamic PAMT
From: Edgecombe, Rick P @ 2026-01-07 14:41 UTC (permalink / raw)
  To: yilun.xu@linux.intel.com
  Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, Huang, Kai,
	Li, Xiaoyao, Hansen, Dave, Zhao, Yan Y, Wu, Binbin,
	kas@kernel.org, seanjc@google.com, mingo@redhat.com,
	pbonzini@redhat.com, tglx@linutronix.de, Yamahata, Isaku,
	linux-kernel@vger.kernel.org, kirill.shutemov@linux.intel.com,
	Annapurve, Vishal, Gao, Chao, bp@alien8.de, x86@kernel.org
In-Reply-To: <aV32uDSqEDOgYp6L@yilunxu-OptiPlex-7050>

On Wed, 2026-01-07 at 14:01 +0800, Xu Yilun wrote:
> > I do think this is a good area for cleanup, but let's not overhaul
> > it
> > just to get a small incremental benefit. If we need a new interface
> > in
> 
> Agree. I definitely don't want a new TDX module interface for now.

No, I was suggesting to think about a new TDX module interface if that
is what it takes to really simplify it. For example, something like a
consistent TDH.SYS.RDALL. For TDX module changes to be available in the
future (for example at the time of the other optional metadata), we
actually need to start the process now.

^ permalink raw reply

* Re: [EXTERNAL] Re: "Paravisor" Feature Enumeration
From: Kiryl Shutsemau @ 2026-01-07 12:06 UTC (permalink / raw)
  To: Andrew Cooper
  Cc: Jon Lange, Dave Hansen, Williams, Dan J, Sean Christopherson,
	Paolo Bonzini, John Starks, Will Deacon, Mark Rutland,
	linux-coco@lists.linux.dev, LKML, Edgecombe, Rick P
In-Reply-To: <43ae1b15-c911-4ecd-aaaa-15bc23ec6192@citrix.com>

On Tue, Jan 06, 2026 at 10:39:08PM +0000, Andrew Cooper wrote:
> On 06/01/2026 2:12 am, Jon Lange wrote:
> > Andrew wrote:
> >
> >> Are we saying that, inside an opaque blob that a customer provides to a CSP to run we might have:
> >> * a paravisor and an unaware OS, or
> >> * svsm and a fully-aware OS, or
> >> * something in-between these two.
> >> and we're looking a way to describe which piece of the interior stack owns which capability/service?
> >> I think the discussion would benefit greatly from having a couple of concrete examples of data this wants to hold,
> >> and how it is to be used at different levels of the interior software stack.
> > Here are two examples.  In both examples, the OS is running behind a paravisor but I wouldn't term it an "unaware OS".  Rather, the paravisor is present because of the set of services it provides, and it is running in paravisor mode (not SVSM mode) because the implementation benefits from taking full management responsibility for the confidential trust boundary (e.g. determination of when/how to validate/accept pages).  In such a configuration, where the paravisor has management responsibility for the confidential trust boundary, all of the enlightenments in the guest OS for managing confidentiality state must be suppressed.  The straightforward way to do this is for the paravisor to suppress the confidential VM enumeration information visible to the guest OS (the "SNP available" CPUID bit, or the "TDX active" bit, for example).
> >
> > Note that this occurs out of necessity because we can't have the paravisor and the guest OS fighting over who has the right/responsibility to execute PVALIDATE, or TDG.MEM.PAGE.ACCEPT, or whatever.  The kernel today only has two concepts of its execution mode: either it is a confidential VM, in which case it takes full responsibility, or it is not a confidential VM, in which case it ignores the responsibility.  When a paravisor (not SVSM) is active, we have to operate in the second mode because the first mode would provoke precisely the conflict we're trying to avoid. 
> >
> > First example: a confidential VM running under a paravisor wants to obtain an attestation report for itself to pass to a third party to vouch for the fact that it is a confidential VM.  Assume in this example that the relying party is aware of the paravisor and the paravisor's measurements, so the evidence provided in such an attestation report can successfully be verified as authentic.  In order for this to be possible, the kernel has to know that it's running in a confidential VM in a mode where attestation reports are available but where the responsibility for confidential memory state management is suppressed.  This is a third state beyond the two states described above.  This isn't just a userspace problem because access to the attestation service is mediated by a kernel-mode driver that needs to know how to configure itself (such configuration today is based on CPUID and not on ACPI).
> >
> > Second example: a confidential VM running under a paravisor determines that one of the devices available to it is a TDISP device that requires the OS - not the paravisor - to perform the operations required to configure the device, to obtain and verify its attestation information, and to consent to activating the device in the TDISP RUN state.  In order for the OS to be able to execute that sequence, the device has to know that it is running as a confidential VM so it knows that TDISP configuration may be necessary.
> 
> Thankyou - that is helpful.
> 
> So overall, we're wanting the paravisor to be able to express "You're in
> a confidential VM, but you're not in charge" to the OS.
> 
> Hiding the SNP / TDX bit is of course necessary.  They have well defined
> meanings which the OS cannot use when it's not in charge.

Hiding "TDX bit" is not necessary for TDX guest. Linux TDX guest kernel
can run both as L1 and L2 guest. Paravisor in L1 can redirect all
necessary operation to itself and it is transparent for L2.

It might be more relevant for the guest OSes which cannot be run as TDX
guest natively.

-- 
  Kiryl Shutsemau / Kirill A. Shutemov

^ permalink raw reply

* Re: [PATCH v4 04/16] x86/virt/tdx: Allocate page bitmap for Dynamic PAMT
From: Xu Yilun @ 2026-01-07  6:01 UTC (permalink / raw)
  To: Edgecombe, Rick P
  Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev, Huang, Kai,
	Li, Xiaoyao, Hansen, Dave, Zhao, Yan Y, Wu, Binbin,
	kas@kernel.org, seanjc@google.com, mingo@redhat.com,
	pbonzini@redhat.com, tglx@linutronix.de, Yamahata, Isaku,
	linux-kernel@vger.kernel.org, kirill.shutemov@linux.intel.com,
	Annapurve, Vishal, Gao, Chao, bp@alien8.de, x86@kernel.org
In-Reply-To: <94b619208022ee29812d871eeacab4f979e51d85.camel@intel.com>

On Tue, Jan 06, 2026 at 05:00:48PM +0000, Edgecombe, Rick P wrote:
> On Tue, 2026-01-06 at 12:01 +0800, Xu Yilun wrote:
> > Yes the extra indentation is unconventional, but everything here is,
> > and we know we will eventually change them all. So I more prefer
> > simple changes based on:
> > 
> >   if (!ret && !(ret = read_sys_metadata_field(0xABCDEF, &val)))
> > 
> > rather than neat but more LOC (when both are easy to read).
> 
> This whole code style was optimized to be verifiable, not for LOC. Kai
> originally had several macro based solution that had a bunch of code
> reuse before this style got settled on as part of the code gen. It

Yeah, I know the code style in this block is the result of several
rounds discussion, refined but not intend for human read. So I suggest
we only keep the existing steorotypes:

  if (!ret && !(ret = read_sys_metadata_field(0xABCDEF, &val)))
	sysinfo_xxx->xxxxx = val;
and

  ret = ret ?: get_tdx_sys_info_xxx(&sysinfo->xxx);

isolate them, don't create other varients/hybrids of them such as:

  if (!ret && !(ret = get_tdx_sys_info_dpamt_bits(sysinfo_tdmr, &val)))

when we need other logics, to avoid extensive review effort.


That's why I'm more fond of my version, it embraces the steorotype with
a nature "if" for extra logic:

  if (tdx_support_dynamic_pamt(&tdx_sysinfo))
	if (!ret && !(ret = read_sys_metadata_field(0x9100000100000013, &val)))
		sysinfo_tdmr->pamt_page_bitmap_entry_bits = val;

But anyway, if anyone is really uncomfortable with the indentation,
ignore my version.

[...]

> > Anyway, this is trivial concern. I have more optional fields to add
> > and will follow the final decision.
> 
> This is the kind of thing that shouldn't need a clever solution. There
> *should* be a way to more simply copy structured data from the TDX
> module.
> 
> I do think this is a good area for cleanup, but let's not overhaul it
> just to get a small incremental benefit. If we need a new interface in

Agree. I definitely don't want a new TDX module interface for now.

> the TDX module, let's explore it and actually get to something simple.

^ permalink raw reply

* RE: [EXTERNAL] Re: "Paravisor" Feature Enumeration
From: Jon Lange @ 2026-01-07  2:48 UTC (permalink / raw)
  To: dan.j.williams@intel.com, Andrew Cooper, Dave Hansen
  Cc: Sean Christopherson, Paolo Bonzini, John Starks, Will Deacon,
	Mark Rutland, linux-coco@lists.linux.dev, LKML, Edgecombe, Rick P
In-Reply-To: <695dbdbb37d41_4b7a1003@dwillia2-mobl4.notmuch>

Dan W wrote:

> It sounds like the paravisor is going to hide confidential memory
> management details like page-acceptance, but it is going to advertise
> and intercept higher order operations like generate launch attestation
> report and TDISP paths like lock device, get device report, accept/run
> device.

I think that's roughly the right mental model.  The paravisor will additionally hide confidential details like MSR virtualization, I/O and MMIO handling, CPUID virtualization - all of the sorts of things that would generate #VE/#VC exceptions in a fully enlightened guest so that the guest doesn't have to worry about those, and the paravisor can provide useful functionality (like device emulation or hypervisor-type functionality) through those primitives.

> So does this paravisor need low level intercepts via pv_ops and a
> confidential memory-management model independent of TDX/SNP etc? Or,
> does it only need the higher order common "services" like attestation
> and TDISP.

I'm not following your question - I don't understand what you're envisioning when you describe confidential memory management independent of TDX/SNP.  It is the case that the paravisor is responsible for the confidentiality state of all memory, and therefore it will have some implementation to fulfill this responsibility.  It's natural for it to do so because its own operation has to integrate with the state of memory.  Following my earlier analogy that the paravisor acts like a nested hypervisor for a single (confidential) guest, the paravisor itself will have to implement all of the services necessary to satisfy the virtualization requirements of an unenlightened guest, which is far more than the "common services" that you mention.  Can you give some other examples of the sort of distinction you're trying to highlight?

-Jon

-----Original Message-----
From: dan.j.williams@intel.com <dan.j.williams@intel.com> 
Sent: Tuesday, January 6, 2026 5:58 PM
To: Jon Lange <jlange@microsoft.com>; Andrew Cooper <andrew.cooper3@citrix.com>; Dave Hansen <dave.hansen@intel.com>
Cc: Williams, Dan J <dan.j.williams@intel.com>; Sean Christopherson <seanjc@google.com>; Paolo Bonzini <pbonzini@redhat.com>; John Starks <John.Starks@microsoft.com>; Will Deacon <will@kernel.org>; Mark Rutland <mark.rutland@arm.com>; linux-coco@lists.linux.dev; LKML <linux-kernel@vger.kernel.org>; Edgecombe, Rick P <rick.p.edgecombe@intel.com>
Subject: RE: [EXTERNAL] Re: "Paravisor" Feature Enumeration

Jon Lange wrote:
[..]
> > Do you foresee a need to pass anything other than "here's a handful of
> > services that are available to you"?
> 
> Assuming we move past the question of "are we in paravisor mode",
> something that is less clear to me is how components like the
> attestation driver know how to consume the confidential services that
> exist.  A fully enlightened OS that knows that it is in charge also
> knows that it has direct access to all of the platform services that
> support confidentiality (whether it's specific SNP ABI calls, or TDG.*
> TDCALL leaves, or GHCB/GHCI interaction, or whatever).  But when
> running behind a paravisor, some of that access might be restricted,
> and it might not be possible for the existing drivers to work without
> modification.  Since none of these paravisor support services have
> been built yet, it's hard for me to predict what kinds of differences
> need to exist in these drivers between paravisor mode and fully
> enlightened mode - it might turn out to be none at all.  I suspect
> that we're going to have to just try to build something and see where
> the problems lie in practice, and that will information how much
> additional information might need to flow (which might go beyond
> "these services are available" to "here's how you access them").  I
> don't think it's too productive to conjecture any specifics now until
> we have code to point to, but this is a potential problem worth
> acknowledging.

Where I get lost in this discussion is in the transition between wanting
to intercept operations like "private page acceptance" vs operations
like "guest OS is asking for an attestation report".

It sounds like the paravisor is going to hide confidential memory
management details like page-acceptance, but it is going to advertise
and intercept higher order operations like generate launch attestation
report and TDISP paths like lock device, get device report, accept/run
device.

So does this paravisor need low level intercepts via pv_ops and a
confidential memory-management model independent of TDX/SNP etc? Or,
does it only need the higher order common "services" like attestation
and TDISP.

^ permalink raw reply

* RE: [EXTERNAL] Re: "Paravisor" Feature Enumeration
From: dan.j.williams @ 2026-01-07  1:58 UTC (permalink / raw)
  To: Jon Lange, Andrew Cooper, Dave Hansen
  Cc: Williams, Dan J, Sean Christopherson, Paolo Bonzini, John Starks,
	Will Deacon, Mark Rutland, linux-coco@lists.linux.dev, LKML,
	Edgecombe, Rick P
In-Reply-To: <CH8PR21MB5222D4771880715FC8104835CA87A@CH8PR21MB5222.namprd21.prod.outlook.com>

Jon Lange wrote:
[..]
> > Do you foresee a need to pass anything other than "here's a handful of
> > services that are available to you"?
> 
> Assuming we move past the question of "are we in paravisor mode",
> something that is less clear to me is how components like the
> attestation driver know how to consume the confidential services that
> exist.  A fully enlightened OS that knows that it is in charge also
> knows that it has direct access to all of the platform services that
> support confidentiality (whether it's specific SNP ABI calls, or TDG.*
> TDCALL leaves, or GHCB/GHCI interaction, or whatever).  But when
> running behind a paravisor, some of that access might be restricted,
> and it might not be possible for the existing drivers to work without
> modification.  Since none of these paravisor support services have
> been built yet, it's hard for me to predict what kinds of differences
> need to exist in these drivers between paravisor mode and fully
> enlightened mode - it might turn out to be none at all.  I suspect
> that we're going to have to just try to build something and see where
> the problems lie in practice, and that will information how much
> additional information might need to flow (which might go beyond
> "these services are available" to "here's how you access them").  I
> don't think it's too productive to conjecture any specifics now until
> we have code to point to, but this is a potential problem worth
> acknowledging.

Where I get lost in this discussion is in the transition between wanting
to intercept operations like "private page acceptance" vs operations
like "guest OS is asking for an attestation report".

It sounds like the paravisor is going to hide confidential memory
management details like page-acceptance, but it is going to advertise
and intercept higher order operations like generate launch attestation
report and TDISP paths like lock device, get device report, accept/run
device.

So does this paravisor need low level intercepts via pv_ops and a
confidential memory-management model independent of TDX/SNP etc? Or,
does it only need the higher order common "services" like attestation
and TDISP.

^ permalink raw reply

* Re: [PATCH v2 0/3] Expose TDX Module version
From: dan.j.williams @ 2026-01-07  0:36 UTC (permalink / raw)
  To: Chao Gao, Kiryl Shutsemau
  Cc: kvm, linux-coco, linux-kernel, x86, vishal.l.verma, kai.huang,
	dan.j.williams, yilun.xu, vannapurve, Borislav Petkov,
	Dave Hansen, H. Peter Anvin, Ingo Molnar, Rick Edgecombe,
	Thomas Gleixner
In-Reply-To: <aVywHbHlcRw2tM/X@intel.com>

Chao Gao wrote:
[..]
> And in my opinion, exposing version information to guests is also unnecessary
> since the module version can already be read from the host with this series.
> In debugging scenarios, I'm not sure why the TDX module would be so special
> that guests should know its version but not other host information, such as
> host kernel version, microcode version, etc. None of these are exposed to guest
> kernel (not to mention guest userspace).

Agree, and note that the guest already has full launch attestation
details available via the common
Documentation/ABI/testing/configfs-tsm-report transport.

I assume the primary need for version information is debug, but if you
are debugging a guest problem might as well get the entire launch
attestation with the version of "all the things" included.

^ 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