Linux Confidential Computing Development
 help / color / mirror / Atom feed
* [PATCH v3 0/2] SEV-SNP Unaccepted Memory Hotplug
From: Pratik R. Sampat @ 2026-01-28 20:41 UTC (permalink / raw)
  To: linux-mm, linux-coco, x86, linux-kernel
  Cc: tglx, mingo, bp, dave.hansen, kas, ardb, akpm, david, osalvador,
	thomas.lendacky, michael.roth, prsampat

Guest memory hot-plug/remove via the QEMU monitor is used by virtual
machines to dynamically scale the memory capacity of a system with
virtually zero downtime to the guest. For confidential VMs, memory has
to be first accepted before it can be used. Add support to accept
memory that has been hot-added and revert back it's state for
hypervisors to be able to use the pages during hot-remove.

Usage (for SNP guests)
----------------------
Step1: Spawn a QEMU SNP guest with the additional parameter of slots and
maximum possible memory, along with the initial memory as below:
"-m X,slots=Y,maxmem=Z".

Step2: Once the guest is booted, launch the qemu monitor and hotplug
the memory as follows:
(qemu) object_add memory-backend-memfd,id=mem1,size=1G
(qemu) device_add pc-dimm,id=dimm1,memdev=mem1

Memory is accepted up-front when added to the guest.

If using auto-onlining by either:
    a) echo online > /sys/devices/system/memory/auto_online_blocks, OR
    b) enable CONFIG_MHP_DEFAULT_ONLINE_TYPE_* while compiling kernel
Memory should show up automatically.

Otherwise, memory can also be onlined by echoing 1 to the newly added
blocks in: /sys/devices/system/memory/memoryXX/online

Step3: memory can be hot-removed using the qemu monitor using:
(qemu) device_remove dimm1
(qemu) object_remove mem1

Tip: Enable the kvm_convert_memory event in QEMU to observe memory
conversions between private and shared during hotplug/remove.

The series is based on
        git.kernel.org/pub/scm/virt/kvm/kvm.git next

Comments and feedback appreciated!

Changelog Patch v2..v3:
-----------------------
https://lore.kernel.org/all/20260112202300.43546-1-prsampat@amd.com/
1. Account for cold-plugged memory at boot and introduce proper handling
   of the unaccepted bitmap during both hotplug and remove. (Kiryl)
2. #include<asm/unaccepted_memory.h> within memory_hotplug caused build
   failures on non-x86 archs (Andrew). Instead of introducing
   #if-deffery to have arch agnostic fall throughs, create hotplug
   specific helper functions since we now also need to take care of
   managing the bitmaps due to 1. as well.

Changelog RFC..Patch v2:
------------------------
https://lore.kernel.org/all/20251125175753.1428857-1-prsampat@amd.com/
Based on feedback from the RFC, reworked the series to accept memory
upfront on hotplug. This is done for two reasons:
1. Avoids modifying the unaccepted bitmap. Extending the bitmap would
   require either:
   * Dynamically allocating the bitmap, which would need changes to EFI
     struct definitions, or
   * Pre-allocating a larger bitmap to accommodate hotpluggable memory.
     This poses challenges since e820 is parsed before SRAT, which
     contains the actual memory ranges information.
2. There are currently no known use-cases that would benefit from lazy
   acceptance of hotplugged ranges which warrants this additional
   complexity.

Pratik R. Sampat (2):
  mm/memory_hotplug: Add support to accept memory during hot-add
  x86/sev: Add support to unaccept memory after hot-remove

 arch/x86/coco/sev/core.c                 | 13 +++++
 arch/x86/include/asm/sev.h               |  2 +
 arch/x86/include/asm/unaccepted_memory.h |  9 +++
 drivers/firmware/efi/unaccepted_memory.c | 74 ++++++++++++++++++++++++
 include/linux/mm.h                       | 14 +++++
 mm/memory_hotplug.c                      |  4 ++
 6 files changed, 116 insertions(+)

-- 
2.52.0


^ permalink raw reply

* Re: [PATCH 1/2] KVM: SEV: IBPB-on-Entry guest support
From: Borislav Petkov @ 2026-01-28 19:23 UTC (permalink / raw)
  To: Kim Phillips
  Cc: linux-kernel, kvm, linux-coco, x86, Sean Christopherson,
	Paolo Bonzini, K Prateek Nayak, Nikunj A Dadhania, Tom Lendacky,
	Michael Roth, Naveen Rao, David Kaplan, stable
In-Reply-To: <20260126224205.1442196-2-kim.phillips@amd.com>

On Mon, Jan 26, 2026 at 04:42:04PM -0600, Kim Phillips wrote:
> The SEV-SNP IBPB-on-Entry feature does not require a guest-side
> implementation. The feature was added in Zen5 h/w, after the first
> SNP Zen implementation, and thus was not accounted for when the
> initial set of SNP features were added to the kernel.
> 
> In its abundant precaution, commit 8c29f0165405 ("x86/sev: Add SEV-SNP
> guest feature negotiation support") included SEV_STATUS' IBPB-on-Entry
> bit as a reserved bit, thereby masking guests from using the feature.
> 
> Unmask the bit, to allow guests to take advantage of the feature on
> hypervisor kernel versions that support it: Amend the SEV_STATUS MSR
> SNP_RESERVED_MASK to exclude bit 23 (IbpbOnEntry).

Do not explain what the patch does.

> Fixes: 8c29f0165405 ("x86/sev: Add SEV-SNP guest feature negotiation support")
> Cc: Nikunj A Dadhania <nikunj@amd.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> CC: Borislav Petkov (AMD) <bp@alien8.de>
> CC: Michael Roth <michael.roth@amd.com>
> Cc: stable@kernel.org

I guess...

> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 4d3566bb1a93..9016a6b00bc7 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -735,7 +735,10 @@
>  #define MSR_AMD64_SNP_SMT_PROT		BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
>  #define MSR_AMD64_SNP_SECURE_AVIC_BIT	18
>  #define MSR_AMD64_SNP_SECURE_AVIC	BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
> -#define MSR_AMD64_SNP_RESV_BIT		19
> +#define MSR_AMD64_SNP_RESERVED_BITS19_22 GENMASK_ULL(22, 19)
> +#define MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT	23
> +#define MSR_AMD64_SNP_IBPB_ON_ENTRY	BIT_ULL(MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT)

Why isn't this part of SNP_FEATURES_PRESENT?

If this feature doesn't require guest-side support, then it is trivially
present, no?

> +#define MSR_AMD64_SNP_RESV_BIT		24
>  #define MSR_AMD64_SNP_RESERVED_MASK	GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
>  #define MSR_AMD64_SAVIC_CONTROL		0xc0010138
>  #define MSR_AMD64_SAVIC_EN_BIT		0
> -- 

I guess this is a fix of sorts and I could take it in now once all review
comments have been addressed...

-- 
Regards/Gruss,
    Boris.

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

^ permalink raw reply

* Re: [PATCH 2/2] KVM: SEV: Add support for IBPB-on-Entry
From: Tom Lendacky @ 2026-01-28 19:08 UTC (permalink / raw)
  To: Kim Phillips, linux-kernel, kvm, linux-coco, x86
  Cc: Sean Christopherson, Paolo Bonzini, K Prateek Nayak,
	Nikunj A Dadhania, Michael Roth, Borislav Petkov, Borislav Petkov,
	Naveen Rao, David Kaplan
In-Reply-To: <20260126224205.1442196-3-kim.phillips@amd.com>

On 1/26/26 16:42, Kim Phillips wrote:
> AMD EPYC 5th generation and above processors support IBPB-on-Entry
> for SNP guests.  By invoking an Indirect Branch Prediction Barrier
> (IBPB) on VMRUN, old indirect branch predictions are prevented
> from influencing indirect branches within the guest.
> 
> SNP guests may choose to enable IBPB-on-Entry by setting
> SEV_FEATURES bit 21 (IbpbOnEntry).
> 
> Host support for IBPB on Entry is indicated by CPUID
> Fn8000_001F[IbpbOnEntry], bit 31.
> 
> If supported, indicate support for IBPB on Entry in
> sev_supported_vmsa_features bit 23 (IbpbOnEntry).
> 
> For more info, refer to page 615, Section 15.36.17 "Side-Channel
> Protection", AMD64 Architecture Programmer's Manual Volume 2: System
> Programming Part 2, Pub. 24593 Rev. 3.42 - March 2024 (see Link).
> 
> Link: https://bugzilla.kernel.org/attachment.cgi?id=306250
> Signed-off-by: Kim Phillips <kim.phillips@amd.com>

Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>

> ---
>  arch/x86/include/asm/cpufeatures.h | 1 +
>  arch/x86/include/asm/svm.h         | 1 +
>  arch/x86/kvm/svm/sev.c             | 9 ++++++++-
>  3 files changed, 10 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
> index c01fdde465de..3ce5dff36f78 100644
> --- a/arch/x86/include/asm/cpufeatures.h
> +++ b/arch/x86/include/asm/cpufeatures.h
> @@ -459,6 +459,7 @@
>  #define X86_FEATURE_ALLOWED_SEV_FEATURES (19*32+27) /* Allowed SEV Features */
>  #define X86_FEATURE_SVSM		(19*32+28) /* "svsm" SVSM present */
>  #define X86_FEATURE_HV_INUSE_WR_ALLOWED	(19*32+30) /* Allow Write to in-use hypervisor-owned pages */
> +#define X86_FEATURE_IBPB_ON_ENTRY	(19*32+31) /* SEV-SNP IBPB on VM Entry */
>  
>  /* AMD-defined Extended Feature 2 EAX, CPUID level 0x80000021 (EAX), word 20 */
>  #define X86_FEATURE_NO_NESTED_DATA_BP	(20*32+ 0) /* No Nested Data Breakpoints */
> diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
> index edde36097ddc..eebc65ec948f 100644
> --- a/arch/x86/include/asm/svm.h
> +++ b/arch/x86/include/asm/svm.h
> @@ -306,6 +306,7 @@ static_assert((X2AVIC_4K_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AV
>  #define SVM_SEV_FEAT_ALTERNATE_INJECTION		BIT(4)
>  #define SVM_SEV_FEAT_DEBUG_SWAP				BIT(5)
>  #define SVM_SEV_FEAT_SECURE_TSC				BIT(9)
> +#define SVM_SEV_FEAT_IBPB_ON_ENTRY			BIT(21)
>  
>  #define VMCB_ALLOWED_SEV_FEATURES_VALID			BIT_ULL(63)
>  
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index ea515cf41168..8a6d25db0c00 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -3165,8 +3165,15 @@ void __init sev_hardware_setup(void)
>  	    cpu_feature_enabled(X86_FEATURE_NO_NESTED_DATA_BP))
>  		sev_supported_vmsa_features |= SVM_SEV_FEAT_DEBUG_SWAP;
>  
> -	if (sev_snp_enabled && tsc_khz && cpu_feature_enabled(X86_FEATURE_SNP_SECURE_TSC))
> +	if (!sev_snp_enabled)
> +		return;
> +	/* the following feature bit checks are SNP specific */
> +
> +	if (tsc_khz && cpu_feature_enabled(X86_FEATURE_SNP_SECURE_TSC))
>  		sev_supported_vmsa_features |= SVM_SEV_FEAT_SECURE_TSC;
> +
> +	if (cpu_feature_enabled(X86_FEATURE_IBPB_ON_ENTRY))
> +		sev_supported_vmsa_features |= SVM_SEV_FEAT_IBPB_ON_ENTRY;
>  }
>  
>  void sev_hardware_unsetup(void)


^ permalink raw reply

* Re: [PATCH 1/2] KVM: SEV: IBPB-on-Entry guest support
From: Tom Lendacky @ 2026-01-28 19:02 UTC (permalink / raw)
  To: Kim Phillips, linux-kernel, kvm, linux-coco, x86
  Cc: Sean Christopherson, Paolo Bonzini, K Prateek Nayak,
	Nikunj A Dadhania, Michael Roth, Borislav Petkov, Borislav Petkov,
	Naveen Rao, David Kaplan, stable
In-Reply-To: <20260126224205.1442196-2-kim.phillips@amd.com>

On 1/26/26 16:42, Kim Phillips wrote:
> The SEV-SNP IBPB-on-Entry feature does not require a guest-side
> implementation. The feature was added in Zen5 h/w, after the first
> SNP Zen implementation, and thus was not accounted for when the
> initial set of SNP features were added to the kernel.
> 
> In its abundant precaution, commit 8c29f0165405 ("x86/sev: Add SEV-SNP
> guest feature negotiation support") included SEV_STATUS' IBPB-on-Entry
> bit as a reserved bit, thereby masking guests from using the feature.
> 
> Unmask the bit, to allow guests to take advantage of the feature on
> hypervisor kernel versions that support it: Amend the SEV_STATUS MSR
> SNP_RESERVED_MASK to exclude bit 23 (IbpbOnEntry).
> 
> Fixes: 8c29f0165405 ("x86/sev: Add SEV-SNP guest feature negotiation support")
> Cc: Nikunj A Dadhania <nikunj@amd.com>
> Cc: Tom Lendacky <thomas.lendacky@amd.com>
> CC: Borislav Petkov (AMD) <bp@alien8.de>
> CC: Michael Roth <michael.roth@amd.com>
> Cc: stable@kernel.org
> Signed-off-by: Kim Phillips <kim.phillips@amd.com>

With the change to the subject line...

Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com>

> ---
>  arch/x86/boot/compressed/sev.c   | 1 +
>  arch/x86/coco/sev/core.c         | 1 +
>  arch/x86/include/asm/msr-index.h | 5 ++++-
>  3 files changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
> index c8c1464b3a56..2b639703b8dd 100644
> --- a/arch/x86/boot/compressed/sev.c
> +++ b/arch/x86/boot/compressed/sev.c
> @@ -188,6 +188,7 @@ bool sev_es_check_ghcb_fault(unsigned long address)
>  				 MSR_AMD64_SNP_RESERVED_BIT13 |		\
>  				 MSR_AMD64_SNP_RESERVED_BIT15 |		\
>  				 MSR_AMD64_SNP_SECURE_AVIC |		\
> +				 MSR_AMD64_SNP_RESERVED_BITS19_22 |	\
>  				 MSR_AMD64_SNP_RESERVED_MASK)
>  
>  #ifdef CONFIG_AMD_SECURE_AVIC
> diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
> index 9ae3b11754e6..13f608117411 100644
> --- a/arch/x86/coco/sev/core.c
> +++ b/arch/x86/coco/sev/core.c
> @@ -122,6 +122,7 @@ static const char * const sev_status_feat_names[] = {
>  	[MSR_AMD64_SNP_VMSA_REG_PROT_BIT]	= "VMSARegProt",
>  	[MSR_AMD64_SNP_SMT_PROT_BIT]		= "SMTProt",
>  	[MSR_AMD64_SNP_SECURE_AVIC_BIT]		= "SecureAVIC",
> +	[MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT]	= "IBPBOnEntry",
>  };
>  
>  /*
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 4d3566bb1a93..9016a6b00bc7 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -735,7 +735,10 @@
>  #define MSR_AMD64_SNP_SMT_PROT		BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
>  #define MSR_AMD64_SNP_SECURE_AVIC_BIT	18
>  #define MSR_AMD64_SNP_SECURE_AVIC	BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
> -#define MSR_AMD64_SNP_RESV_BIT		19
> +#define MSR_AMD64_SNP_RESERVED_BITS19_22 GENMASK_ULL(22, 19)
> +#define MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT	23
> +#define MSR_AMD64_SNP_IBPB_ON_ENTRY	BIT_ULL(MSR_AMD64_SNP_IBPB_ON_ENTRY_BIT)
> +#define MSR_AMD64_SNP_RESV_BIT		24
>  #define MSR_AMD64_SNP_RESERVED_MASK	GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
>  #define MSR_AMD64_SAVIC_CONTROL		0xc0010138
>  #define MSR_AMD64_SAVIC_EN_BIT		0


^ permalink raw reply

* Re: [PATCH v3 00/26] Runtime TDX Module update support
From: Sagi Shahar @ 2026-01-28 17:52 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Borislav Petkov, H. Peter Anvin,
	Ingo Molnar, Paolo Bonzini, Thomas Gleixner
In-Reply-To: <20260123145645.90444-1-chao.gao@intel.com>

On Fri, Jan 23, 2026 at 9:00 AM Chao Gao <chao.gao@intel.com> wrote:
>
> Hi Reviewers,
>
> With this posting, I'm hoping to collect more Reviewed-by or Acked-by tags.
> Dave, since this version is still light on acks, it might not be ready for
> your review.
>
> Changelog:
> v2->v3:
>  - Make this series self-contained and independently runnable, testable and
>    reviewable by
>
>    * Including dependent patches such as TDX Module version exposure and TDX
>      faux device creation

I see "x86/virt/tdx: Retrieve TDX module version" and "x86/virt/tdx:
Print TDX module version during init" in the github link but I don't
see them as part of this series. Were they posted/accepted as part of
a different series?

Trying to build this series without them fails since
tdx_sysinfo.version is undefined.

>
>    * Removing dependency on Sean's VMXON cleanups for now, the tdx-host device
>      simply checks that the TDX module is initialized, regardless of when or
>      who performed the initialization.
>
>      Note: If the KVM module is unloaded, all services exposed by the tdx-host
>      device will fail. This shouldn't be a big issue since proper errors will
>      be returned to userspace, similar to other failure cases.
>
>  - Handle updates during update-sensitive times and documented expectations for
>    TDX Module updates
>  - Rework how updates are aborted when errors occur midway
>  - Map Linux error codes to firmware upload error codes
>  - Preserve bit 63 in P-SEAMLDR SEAMCALL leaf numbers and display them in hex
>  - Do not fail the entire tdx-host device when update features encounter errors
>  - Drop superfluous is_visible() function for P-SEAMLDR sysfs nodes
>  - Add support for sigstruct sizes up to 16KB
>  - Move CONFIG_INTEL_TDX_MODULE_UPDATE kconfig entry under TDX_HOST_SERVICES
>  - Various cleanups and changelog improvements for clarity and consistency
>  - Collect review tags from ZhenZhong and Jonathan
>  - v2: https://lore.kernel.org/linux-coco/20251001025442.427697-1-chao.gao@intel.com/
>
> This series adds support for runtime TDX Module updates that preserve
> running TDX guests. It is also available at:
>
>   https://github.com/gaochaointel/linux-dev/commits/tdx-module-updates-v3/
>
> == Background ==
>
> Intel TDX isolates Trusted Domains (TDs), or confidential guests, from the
> host. A key component of Intel TDX is the TDX Module, which enforces
> security policies to protect the memory and CPU states of TDs from the
> host. However, the TDX Module is software that require updates.
>
> == Problems ==
>
> Currently, the TDX Module is loaded by the BIOS at boot time, and the only
> way to update it is through a reboot, which results in significant system
> downtime. Users expect the TDX Module to be updatable at runtime without
> disrupting TDX guests.
>
> == Solution ==
>
> On TDX platforms, P-SEAMLDR[1] is a component within the protected SEAM
> range. It is loaded by the BIOS and provides the host with functions to
> install a TDX Module at runtime.
>
> Implement a TDX Module update facility via the fw_upload mechanism. Given
> that there is variability in which module update to load based on features,
> fix levels, and potentially reloading the same version for error recovery
> scenarios, the explicit userspace chosen payload flexibility of fw_upload
> is attractive.
>
> This design allows the kernel to accept a bitstream instead of loading a
> named file from the filesystem, as the module selection and policy
> enforcement for TDX Modules are quite complex (see more in patch 8). By
> doing so, much of this complexity is shifted out of the kernel. The kernel
> need to expose information, such as the TDX Module version, to userspace.
> Userspace must understand the TDX Module versioning scheme and update
> policy to select the appropriate TDX Module (see "TDX Module Versioning"
> below).
>
> In the unlikely event the update fails, for example userspace picks an
> incompatible update image, or the image is otherwise corrupted, all TDs
> will experience SEAMCALL failures and be killed. The recovery of TD
> operation from that event requires a reboot.
>
> Given there is no mechanism to quiesce SEAMCALLs, the TDs themselves must
> pause execution over an update. The most straightforward way to meet the
> 'pause TDs while update executes' constraint is to run the update in
> stop_machine() context. All other evaluated solutions export more
> complexity to KVM, or exports more fragility to userspace.
>
> == How to test this series ==
>
> First, load kvm-intel.ko and tdx-host.ko if they haven't been loaded:
>
>  # modprobe -r kvm_intel
>  # modprobe kvm_intel tdx=1
>  # modprobe tdx-host
>
> Then, use the userspace tool below to select the appropriate TDX module and
> install it via the interfaces exposed by this series:
>
>  # git clone https://github.com/intel/tdx-module-binaries
>  # cd tdx-module-binaries
>  # python version_select_and_load.py --update
>
> == Other information relevant to Runtime TDX Module updates ==
>
> === TDX Module versioning ===
>
> Each TDX Module is assigned a version number x.y.z, where x represents the
> "major" version, y the "minor" version, and z the "update" version.
>
> Runtime TDX Module updates are restricted to Z-stream releases.
>
> Note that Z-stream releases do not necessarily guarantee compatibility. A
> new release may not be compatible with all previous versions. To address this,
> Intel provides a separate file containing compatibility information, which
> specifies the minimum module version required for a particular update. This
> information is referenced by the tool to determine if two modules are
> compatible.
>
> === TCB Stability ===
>
> Updates change the TCB as viewed by attestation reports. In TDX there is
> a distinction between launch-time version and current version where
> runtime TDX Module updates cause that latter version number to change,
> subject to Z-stream constraints.
>
> The concern that a malicious host may attack confidential VMs by loading
> insecure updates was addressed by Alex in [3]. Similarly, the scenario
> where some "theoretical paranoid tenant" in the cloud wants to audit
> updates and stop trusting the host after updates until audit completion
> was also addressed in [4]. Users not in the cloud control the host machine
> and can manage updates themselves, so they don't have these concerns.
>
> See more about the implications of current TCB version changes in
> attestation as summarized by Dave in [5].
>
> === TDX Module Distribution Model ===
>
> At a high level, Intel publishes all TDX Modules on the github [2], along
> with a mapping_file.json which documents the compatibility information
> about each TDX Module and a userspace tool to install the TDX Module. OS
> vendors can package these modules and distribute them. Administrators
> install the package and use the tool to select the appropriate TDX Module
> and install it via the interfaces exposed by this series.
>
> [1]: https://cdrdv2.intel.com/v1/dl/getContent/733584
> [2]: https://github.com/intel/tdx-module-binaries
> [3]: https://lore.kernel.org/all/665c5ae0-4b7c-4852-8995-255adf7b3a2f@amazon.com/
> [4]: https://lore.kernel.org/all/5d1da767-491b-4077-b472-2cc3d73246d6@amazon.com/
> [5]: https://lore.kernel.org/all/94d6047e-3b7c-4bc1-819c-85c16ff85abf@intel.com/
>
> Chao Gao (25):
>   x86/virt/tdx: Print SEAMCALL leaf numbers in decimal
>   x86/virt/tdx: Use %# prefix for hex values in SEAMCALL error messages
>   coco/tdx-host: Introduce a "tdx_host" device
>   coco/tdx-host: Expose TDX Module version
>   x86/virt/tdx: Prepare to support P-SEAMLDR SEAMCALLs
>   x86/virt/seamldr: Introduce a wrapper for P-SEAMLDR SEAMCALLs
>   x86/virt/seamldr: Retrieve P-SEAMLDR information
>   coco/tdx-host: Expose P-SEAMLDR information via sysfs
>   coco/tdx-host: Implement FW_UPLOAD sysfs ABI for TDX Module updates
>   x86/virt/seamldr: Block TDX Module updates if any CPU is offline
>   x86/virt/seamldr: Verify availability of slots for TDX Module updates
>   x86/virt/seamldr: Allocate and populate a module update request
>   x86/virt/seamldr: Introduce skeleton for TDX Module updates
>   x86/virt/seamldr: Abort updates if errors occurred midway
>   x86/virt/seamldr: Shut down the current TDX module
>   x86/virt/tdx: Reset software states after TDX module shutdown
>   x86/virt/seamldr: Log TDX Module update failures
>   x86/virt/seamldr: Install a new TDX Module
>   x86/virt/seamldr: Do TDX per-CPU initialization after updates
>   x86/virt/tdx: Establish contexts for the new TDX Module
>   x86/virt/tdx: Update tdx_sysinfo and check features post-update
>   x86/virt/tdx: Enable TDX Module runtime updates
>   x86/virt/seamldr: Extend sigstruct to 16KB
>   x86/virt/tdx: Avoid updates during update-sensitive operations
>   coco/tdx-host: Set and document TDX Module update expectations
>
> Kai Huang (1):
>   x86/virt/tdx: Move low level SEAMCALL helpers out of <asm/tdx.h>
>
>  .../ABI/testing/sysfs-devices-faux-tdx-host   |  76 ++++
>  arch/x86/include/asm/seamldr.h                |  29 ++
>  arch/x86/include/asm/tdx.h                    |  66 +--
>  arch/x86/include/asm/tdx_global_metadata.h    |   5 +
>  arch/x86/kvm/vmx/tdx_errno.h                  |   2 -
>  arch/x86/virt/vmx/tdx/Makefile                |   1 +
>  arch/x86/virt/vmx/tdx/seamcall.h              | 125 ++++++
>  arch/x86/virt/vmx/tdx/seamldr.c               | 398 ++++++++++++++++++
>  arch/x86/virt/vmx/tdx/tdx.c                   | 153 ++++---
>  arch/x86/virt/vmx/tdx/tdx.h                   |  11 +-
>  arch/x86/virt/vmx/tdx/tdx_global_metadata.c   |  13 +
>  drivers/virt/coco/Kconfig                     |   2 +
>  drivers/virt/coco/Makefile                    |   1 +
>  drivers/virt/coco/tdx-host/Kconfig            |  22 +
>  drivers/virt/coco/tdx-host/Makefile           |   1 +
>  drivers/virt/coco/tdx-host/tdx-host.c         | 260 ++++++++++++
>  16 files changed, 1064 insertions(+), 101 deletions(-)
>  create mode 100644 Documentation/ABI/testing/sysfs-devices-faux-tdx-host
>  create mode 100644 arch/x86/include/asm/seamldr.h
>  create mode 100644 arch/x86/virt/vmx/tdx/seamcall.h
>  create mode 100644 arch/x86/virt/vmx/tdx/seamldr.c
>  create mode 100644 drivers/virt/coco/tdx-host/Kconfig
>  create mode 100644 drivers/virt/coco/tdx-host/Makefile
>  create mode 100644 drivers/virt/coco/tdx-host/tdx-host.c
>
> --
> 2.47.3
>
>

^ permalink raw reply

* Re: [PATCH v3 05/26] coco/tdx-host: Expose TDX Module version
From: Dave Hansen @ 2026-01-28 17:01 UTC (permalink / raw)
  To: Chao Gao, linux-coco, linux-kernel, kvm, x86
  Cc: reinette.chatre, ira.weiny, kai.huang, dan.j.williams, yilun.xu,
	sagis, vannapurve, paulmck, nik.borisov, zhenzhong.duan, seanjc,
	rick.p.edgecombe, kas, dave.hansen, vishal.l.verma
In-Reply-To: <20260123145645.90444-6-chao.gao@intel.com>

On 1/23/26 06:55, Chao Gao wrote:
...
> This approach follows the pattern used by microcode updates and
> other CoCo implementations:
> 
> 1. AMD has a PCI device for the PSP for SEV which provides an
> existing place to hang their equivalent metadata.
> 
> 2. ARM CCA will likely have a faux device (although it isn't obvious
> if they have a need to export version information there) [1]
> 
> 3. Microcode revisions are exposed as CPU device attributes

I kinda disagree with the idea that this follows existing patterns. It
uses a *NEW* pattern.

AMD doesn't use a faux device because they *HAVE* a PCI device in their
architecture. TDX doesn't have a PCI device in its hardware architecture.

ARM CCA doesn't exist in the tree.

CPU microcode doesn't use a faux device. For good reason. The microcode
version is *actually* per-cpu. It can differ between CPU cores. The TDX
module version is not per-cpu. There's one and only one global module.
This is the reason that we need a global, unique device for TDX.

I'm not saying that being new is a bad thing. But let's not pretend this
is following any kind of existing pattern. Let's explain *why* it needs
to be different.


^ permalink raw reply

* Re: [PATCH v1 01/14] x86/realmode: remove I/O port paravirtualization
From: Borislav Petkov @ 2026-01-28 17:01 UTC (permalink / raw)
  To: H. Peter Anvin
  Cc: Thomas Gleixner, Ingo Molnar, Dave Hansen, Uros Bizjak,
	Petr Mladek, Andrew Morton, Kees Cook, Peter Zijlstra (Intel),
	Nathan Chancellor, Kiryl Shutsemau, Rick Edgecombe, linux-kernel,
	linux-coco, x86
In-Reply-To: <20260120195407.1163051-2-hpa@zytor.com>

On Tue, Jan 20, 2026 at 11:53:53AM -0800, H. Peter Anvin wrote:
> In commit:
> 
> eb4ea1ae8f45 x86/boot: Port I/O: Allow to hook up alternative helpers

We do this format for referencing commits:

  eb4ea1ae8f45 ("x86/boot: Port I/O: Allow to hook up alternative helpers")

> ... paravirtualization hooks were added to (some!) of the port I/O
> functions. However, they were only ever used in the 32/64-bit
> "compressed" directory, and never made any sense in the real-mode
> code, which is notoriously size sensitive.
> 
> Without these hooks, <asm/shared/io.h> is usable directly, so mode

s/mode/move/

Otherwise, LGTM.

-- 
Regards/Gruss,
    Boris.

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

^ permalink raw reply

* Re: [PATCH v3 04/26] coco/tdx-host: Introduce a "tdx_host" device
From: Dave Hansen @ 2026-01-28 16:53 UTC (permalink / raw)
  To: Tony Lindgren, Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Jonathan Cameron, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin
In-Reply-To: <aXc5Y_VAuGQWsWZX@tlindgre-MOBL1>

On 1/26/26 01:52, Tony Lindgren wrote:
> On Fri, Jan 23, 2026 at 06:55:12AM -0800, Chao Gao wrote:
>> --- /dev/null
>> +++ b/drivers/virt/coco/tdx-host/tdx-host.c
>> @@ -0,0 +1,43 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * TDX host user interface driver
>> + *
>> + * Copyright (C) 2025 Intel Corporation
>> + */
> Just a nit, the year has changed so could be updated.

Folks, please stop this.

You can ask an patch author *if* this should be updated. But if they're
just last year's work, then the year needs to stay 2025. This isn't some
mechanical thing that you flip over when the year changes. You change it
when you meaningfully change the work.

^ permalink raw reply

* Re: [PATCH v3 03/26] x86/virt/tdx: Move low level SEAMCALL helpers out of <asm/tdx.h>
From: Dave Hansen @ 2026-01-28 16:37 UTC (permalink / raw)
  To: Chao Gao, linux-coco, linux-kernel, kvm, x86
  Cc: reinette.chatre, ira.weiny, kai.huang, dan.j.williams, yilun.xu,
	sagis, vannapurve, paulmck, nik.borisov, zhenzhong.duan, seanjc,
	rick.p.edgecombe, kas, dave.hansen, vishal.l.verma,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-4-chao.gao@intel.com>

On 1/23/26 06:55, Chao Gao wrote:
> +++ b/arch/x86/virt/vmx/tdx/seamcall.h

Moving the code to a local header is a good thing. The more private
these things are, the better.

I _do_ like when I see these things have a label in the filename like:

	internal.h

or even:

	seamcall_internal.h

That really catches your eye. It would also be ideal to have a small
blurb at the top of the file to say what its scope is, just to explain
what folks should be adding to it or not.

If you get a chance to add those, all the better. But either way:

Acked-by: Dave Hansen <dave.hansen@linux.intel.com>

^ permalink raw reply

* Re: [PATCH v3 03/26] x86/virt/tdx: Move low level SEAMCALL helpers out of <asm/tdx.h>
From: Dave Hansen @ 2026-01-28 16:31 UTC (permalink / raw)
  To: Chao Gao, Binbin Wu
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin
In-Reply-To: <aXoEQP0jyXgR6ohs@intel.com>

On 1/28/26 04:42, Chao Gao wrote:
>>> diff --git a/arch/x86/virt/vmx/tdx/seamcall.h b/arch/x86/virt/vmx/tdx/seamcall.h
>>> new file mode 100644
>>> index 000000000000..0912e03fabfe
>>> --- /dev/null
>>> +++ b/arch/x86/virt/vmx/tdx/seamcall.h
>>> @@ -0,0 +1,99 @@
>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>> +/* Copyright (C) 2025 Intel Corporation */
>> Should this be updated to 2026?
> Yes. And I may drop the copyright notice if it is not necessary.

No.

The copyright is to document the timing of a creative action. Moving
code is not a creative action.

If you want to remove it, do it in another patch. If you move code, just
_move_ _the_ _code_. You can _maybe_ clean up whitespace if you want to
along the way. But that's it. Don't muck with it unless you have a
reason. A *good* reason.

^ permalink raw reply

* Re: [PATCH v3 01/26] x86/virt/tdx: Print SEAMCALL leaf numbers in decimal
From: Dave Hansen @ 2026-01-28 16:26 UTC (permalink / raw)
  To: Chao Gao, linux-coco, linux-kernel, kvm, x86
  Cc: reinette.chatre, ira.weiny, kai.huang, dan.j.williams, yilun.xu,
	sagis, vannapurve, paulmck, nik.borisov, zhenzhong.duan, seanjc,
	rick.p.edgecombe, kas, dave.hansen, vishal.l.verma,
	Kirill A. Shutemov, Farrah Chen, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-2-chao.gao@intel.com>

On 1/23/26 06:55, Chao Gao wrote:
> Both TDX spec and kernel defines SEAMCALL leaf numbers as decimal. Printing
> them in hex makes no sense. Correct it.

This patch has zero to do with "Runtime TDX Module update support". Why
is it in this series?

^ permalink raw reply

* Re: [PATCH v3 02/26] x86/virt/tdx: Use %# prefix for hex values in SEAMCALL error messages
From: Dave Hansen @ 2026-01-28 15:18 UTC (permalink / raw)
  To: Chao Gao, linux-coco, linux-kernel, kvm, x86
  Cc: reinette.chatre, ira.weiny, kai.huang, dan.j.williams, yilun.xu,
	sagis, vannapurve, paulmck, nik.borisov, zhenzhong.duan, seanjc,
	rick.p.edgecombe, kas, dave.hansen, vishal.l.verma,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-3-chao.gao@intel.com>

On 1/23/26 06:55, Chao Gao wrote:
> "%#" format specifier automatically adds the "0x" prefix and has one less
> character than "0x%".

IMNHO, this is needless bikeshedding about existing code. It's only
function is going to be to distract reviewers from the parts of the set
that actually need review.

If this matters (it doesn't), send it as a separate patch, please.

^ permalink raw reply

* Re: [PATCH v3 03/26] x86/virt/tdx: Move low level SEAMCALL helpers out of <asm/tdx.h>
From: Chao Gao @ 2026-01-28 12:42 UTC (permalink / raw)
  To: Binbin Wu
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin
In-Reply-To: <f8329aaf-7074-4bcc-b05b-b50a639cc970@linux.intel.com>

On Wed, Jan 28, 2026 at 09:37:05AM +0800, Binbin Wu wrote:
>
>
>On 1/23/2026 10:55 PM, Chao Gao wrote:
>> From: Kai Huang <kai.huang@intel.com>
>> 
>> TDX host core code implements three seamcall*() helpers to make SEAMCALL
>> to the TDX module.  Currently, they are implemented in <asm/tdx.h> and
>> are exposed to other kernel code which includes <asm/tdx.h>.
>> 
>> However, other than the TDX host core, seamcall*() are not expected to
>> be used by other kernel code directly.  For instance, for all SEAMCALLs
>> that are used by KVM, the TDX host core exports a wrapper function for
>> each of them.
>> 
>> Move seamcall*() and related code out of <asm/tdx.h> and make them only
>> visible to TDX host core.
>> 
>> Since TDX host core tdx.c is already very heavy, don't put low level
>> seamcall*() code there but to a new dedicated "seamcall.h".  Also,
>> currently tdx.c has seamcall_prerr*() helpers which additionally print
>> error message when calling seamcall*() fails.  Move them to "seamcall.h"
>> as well.  In such way all low level SEAMCALL helpers are in a dedicated
>> place, which is much more readable.
>> 
>> Signed-off-by: Kai Huang <kai.huang@intel.com>
>> Signed-off-by: Chao Gao <chao.gao@intel.com>
>> Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>
>
>Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
>
>One question below.
>
>[...]
>
>> diff --git a/arch/x86/virt/vmx/tdx/seamcall.h b/arch/x86/virt/vmx/tdx/seamcall.h
>> new file mode 100644
>> index 000000000000..0912e03fabfe
>> --- /dev/null
>> +++ b/arch/x86/virt/vmx/tdx/seamcall.h
>> @@ -0,0 +1,99 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/* Copyright (C) 2025 Intel Corporation */
>
>Should this be updated to 2026?

Yes. And I may drop the copyright notice if it is not necessary.

According to [1][2], it seems to be optional or even discouraged.

[1]: https://lwn.net/Articles/912355/
[2]: https://www.linuxfoundation.org/blog/blog/copyright-notices-in-open-source-software-projects

^ permalink raw reply

* Re: [PATCH v3 02/26] x86/virt/tdx: Use %# prefix for hex values in SEAMCALL error messages
From: Chao Gao @ 2026-01-28 12:16 UTC (permalink / raw)
  To: Binbin Wu
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin
In-Reply-To: <35fa8047-7506-4a78-b493-732160c3d25c@linux.intel.com>

On Wed, Jan 28, 2026 at 09:34:03AM +0800, Binbin Wu wrote:
>
>
>On 1/23/2026 10:55 PM, Chao Gao wrote:
>> "%#" format specifier automatically adds the "0x" prefix and has one less
>> character than "0x%".
>> 
>> For conciseness, replace "0x%" with "%#" when printing hexadecimal values
>> in SEAMCALL error messages.
>> 
>> Suggested-by: Dan Williams <dan.j.williams@intel.com>
>> Signed-off-by: Chao Gao <chao.gao@intel.com>
>
>Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
>
>> ---
>> "0x%" is also used to print TDMR ranges. I didn't convert them to reduce
>> code churn, but if they should be converted for consistency, I'm happy
>> to do that.
>
>Generally, is there any preference for coding in Linux kernel about
>"0x%" VS. "%#"? Or developers just make their own choices?

There seems to be no clear guidance on "0x%x" vs. "%#x".

If anyone has strong objections to this change, I can definitely drop it. I
included this patch because Dan suggested it during his review, though I'm not
sure how strongly he feels about it.

I searched lore and found the example below where "%#x" is preferred in another
subsystem:

https://lore.kernel.org/all/20251202231352.GF1712166@ZenIV/

^ permalink raw reply

* Re: [PATCH v3 13/26] x86/virt/seamldr: Allocate and populate a module update request
From: Chao Gao @ 2026-01-28 11:28 UTC (permalink / raw)
  To: Huang, Kai
  Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev,
	linux-kernel@vger.kernel.org, x86@kernel.org,
	dave.hansen@linux.intel.com, kas@kernel.org, seanjc@google.com,
	Chatre, Reinette, Weiny, Ira, tglx@linutronix.de, Verma, Vishal L,
	nik.borisov@suse.com, mingo@redhat.com, hpa@zytor.com,
	sagis@google.com, Chen, Farrah, Duan, Zhenzhong,
	Edgecombe, Rick P, paulmck@kernel.org, Annapurve, Vishal,
	yilun.xu@linux.intel.com, Williams, Dan J, bp@alien8.de
In-Reply-To: <fc3e72ec4443afd79ccade31e9e0036e645e567b.camel@intel.com>

On Tue, Jan 27, 2026 at 11:21:06AM +0800, Huang, Kai wrote:
>
>> +/*
>> + * Allocate and populate a seamldr_params.
>> + * Note that both @module and @sig should be vmalloc'd memory.
>> + */
>> +static struct seamldr_params *alloc_seamldr_params(const void *module, unsigned int module_size,
>> +						   const void *sig, unsigned int sig_size)
>> +{
>> +	struct seamldr_params *params;
>> +	const u8 *ptr;
>> +	int i;
>> +
>> +	BUILD_BUG_ON(sizeof(struct seamldr_params) != SZ_4K);
>> +	if (module_size > SEAMLDR_MAX_NR_MODULE_4KB_PAGES * SZ_4K)
>> +		return ERR_PTR(-EINVAL);
>> +
>> +	if (!IS_ALIGNED(module_size, SZ_4K) || sig_size != SZ_4K ||
>> +	    !IS_ALIGNED((unsigned long)module, SZ_4K) ||
>> +	    !IS_ALIGNED((unsigned long)sig, SZ_4K))
>> +		return ERR_PTR(-EINVAL);
>> +
>
>Based on the the blob format link below, we have 
>
>struct tdx_blob
>{
>	...
>	_u64 sigstruct[256]; // 2KB sigstruct,intel_tdx_module.so.sigstruct
>	_u64 reserved2[256]; // Reserved space
>	...
>}
>
>So it's clear SIGSTRUCT is just 2KB and the second half 2KB is "reserved
>space".
>
>Why is the "reserved space" treated as part of SIGSTRUCT here? 

Good question. Because the space is reserved for sigstruct expansion.

The __current__ SEAMLDR ABI accepts one 4KB page, but all __existing__
sigstructs are only 2KB. so, tdx_blob currently defines a 2KB sigstruct field
followed by 2KB of reserved space. We anticipate that sigstructs will
eventually exceed 4KB, so we added reserved3[N*512] to accommodate future
growth.

You're right. The current tdx_blob definition doesn't clearly indicate that
reserved2/3 are actually part of the sigstruct.

Does this revised tdx_blob definition make that clearer and better align with
this patch? The idea is to make tdx_blob generic enough to clearly represent:
a 4KB header, followed by 4KB-aligned sigstruct, followed by the TDX Module
binary. Current SEAMLDR ABI details or current sigstruct sizes are irrelevant.

struct tdx_blob
{
        _u16 version;              // Version number
        _u16 checksum;             // Checksum of the entire blob should be zero
        _u32 offset_of_module;     // Offset of the module binary intel_tdx_module.bin in bytes
        _u8  signature[8];         // Must be "TDX-BLOB"
        _u32 length;               // The length in bytes of the entire blob
        _u32 reserved0;            // Reserved space
        _u64 reserved1[509];       // Reserved space
        _u64 sigstruct[512 + N*512]; // sigstruct, 4KB aligned

	^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        _u8  module[];             // intel_tdx_module.bin, 4KB aligned, to the end of the file
}


>
>> +
>> +/*
>> + * Intel TDX Module blob. Its format is defined at:
>> + * https://github.com/intel/tdx-module-binaries/blob/main/blob_structure.txt
>> + */
>> +struct tdx_blob {
>> +	u16	version;
>> +	u16	checksum;
>> +	u32	offset_of_module;
>> +	u8	signature[8];
>> +	u32	len;
>> +	u32	resv1;
>> +	u64	resv2[509];
>
>Nit:  Perhaps s/resv/rsvd ?
>

Sure. Will do.

>"#grep rsvd arch/x86 -Rn" gave me a bunch of results but "#grep resv" gave
>me much less (and part of the results were 'resvd' and 'resv_xx' instead of
>plain 'resv').
>  
>> +	u8	data[];
>> +} __packed;
>
>For this structure, I need to click the link and open it in a browser to
>understand where is the sigstruct and module, and ...
>
>> +static struct seamldr_params *init_seamldr_params(const u8 *data, u32 size)
>> +{
>> +	const struct tdx_blob *blob = (const void *)data;
>> +	int module_size, sig_size;
>> +	const void *sig, *module;
>> +
>> +	if (blob->version != 0x100) {
>> +		pr_err("unsupported blob version: %x\n", blob->version);
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	if (blob->resv1 || memchr_inv(blob->resv2, 0, sizeof(blob->resv2))) {
>> +		pr_err("non-zero reserved fields\n");
>> +		return ERR_PTR(-EINVAL);
>> +	}
>> +
>> +	/* Split the given blob into a sigstruct and a module */
>> +	sig		= blob->data;
>> +	sig_size	= blob->offset_of_module - sizeof(struct tdx_blob);
>> +	module		= data + blob->offset_of_module;
>> +	module_size	= size - blob->offset_of_module;
>> +
>
>... to see whether this code makes sense.
>
>I understand the
>
>	...
>	u64	rsvd[N*512];
>	u8	module[];
>
>is painful to be declared explicitly in 'struct tdx_blob' because IIUC we
>cannot put two flexible array members at the end of the structure.

Yes.

>
>But I think if we add 'sigstruct' to the 'struct tdx_blob', e.g.,
>
>struct tdx_blob {
>	u16	version;
>	...
>	u64	rsvd2[509];
>	u64	sigstruct[256];
>	u64	rsvd3[256];
>	u64	data;
>} __packed;
>
>.. we can just use
>
>	sig		= blob->sigstruct;
>	sig_size	= 2K (or 4K I don't quite follow);
>
>which is clearer to read IMHO?

The problem is hard-coding the sigstruct size to 2KB/4KB. This will soon no
longer hold.

But
	sig		= blob->data;
	sig_size	= blob->offset_of_module - sizeof(struct tdx_blob);

doesn't make that assumption, making it more future-proof.

>
>> +	return alloc_seamldr_params(module, module_size, sig, sig_size);
>> +}
>> +
>
>
>

^ permalink raw reply

* Re: [PATCH v3 08/26] x86/virt/seamldr: Retrieve P-SEAMLDR information
From: Binbin Wu @ 2026-01-28  6:50 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Farrah Chen, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-9-chao.gao@intel.com>



On 1/23/2026 10:55 PM, Chao Gao wrote:
> P-SEAMLDR returns its information e.g., version and supported features, in
> response to the SEAMLDR.INFO SEAMCALL.
> 
> This information is useful for userspace. For example, the admin can decide
> which TDX module versions are compatible with the P-SEAMLDR according to
> the P-SEAMLDR version.
> 
> Add and export seamldr_get_info() which retrieves P-SEAMLDR information by
> invoking SEAMLDR.INFO SEAMCALL in preparation for exposing P-SEAMLDR
> version and other necessary information to userspace.
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Tested-by: Farrah Chen <farrah.chen@intel.com>

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>

One nit below.

[...]

> diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c
> index b99d73f7bb08..6a83ae405fac 100644
> --- a/arch/x86/virt/vmx/tdx/seamldr.c
> +++ b/arch/x86/virt/vmx/tdx/seamldr.c
> @@ -9,9 +9,16 @@
>  #include <linux/irqflags.h>
>  #include <linux/types.h>
>  
> +#include <asm/seamldr.h>
> +
>  #include "seamcall.h"
>  
> -static __maybe_unused int seamldr_call(u64 fn, struct tdx_module_args *args)
> +/* P-SEAMLDR SEAMCALL leaf function */
> +#define P_SEAMLDR_INFO			0x8000000000000000
> +
> +static struct seamldr_info seamldr_info __aligned(256);
> +
> +static inline int seamldr_call(u64 fn, struct tdx_module_args *args)

No need to tag the local function with inline.

>  {
>  	unsigned long flags;
>  	u64 vmcs;
> @@ -54,3 +61,11 @@ static __maybe_unused int seamldr_call(u64 fn, struct tdx_module_args *args)
>  	WARN_ONCE(1, "Failed to save/restore the current VMCS");
>  	return -EIO;
>  }


^ permalink raw reply

* Re: [PATCH v3 07/26] x86/virt/seamldr: Introduce a wrapper for P-SEAMLDR SEAMCALLs
From: Binbin Wu @ 2026-01-28  6:38 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Farrah Chen, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-8-chao.gao@intel.com>



On 1/23/2026 10:55 PM, Chao Gao wrote:
> Software needs to talk with P-SEAMLDR via P-SEAMLDR SEAMCALLs. So, add a
> wrapper for P-SEAMLDR SEAMCALLs.
> 
> Save and restore the current VMCS using VMPTRST and VMPTRLD instructions
> to avoid breaking KVM. Doing so is because P-SEAMLDR SEAMCALLs would
> invalidate the current VMCS as documented in Intel® Trust Domain CPU
> Architectural Extensions (May 2021 edition) Chapter 2.3 [1]:
> 
>   SEAMRET from the P-SEAMLDR clears the current VMCS structure pointed
>   to by the current-VMCS pointer. A VMM that invokes the P-SEAMLDR using
>   SEAMCALL must reload the current-VMCS, if required, using the VMPTRLD
>   instruction.
> 
> Disable interrupts to prevent KVM code from interfering with P-SEAMLDR
> SEAMCALLs. For example, if a vCPU is scheduled before the current VMCS is
> restored, it may encounter an invalid current VMCS, causing its VMX
> instruction to fail. Additionally, if KVM sends IPIs to invalidate a
> current VMCS and the invalidation occurs right after the current VMCS is
> saved, that VMCS will be reloaded after P-SEAMLDR SEAMCALLs, leading to
> unexpected behavior.
> 
> NMIs are not a problem, as the only scenario where instructions relying on
> the current-VMCS are used is during guest PMI handling in KVM. This occurs
> immediately after VM exits with IRQ and NMI disabled, ensuring no
> interference with P-SEAMLDR SEAMCALLs.
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Tested-by: Farrah Chen <farrah.chen@intel.com>
> Link: https://cdrdv2.intel.com/v1/dl/getContent/733582 # [1]

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>

Two nits below.

> ---
> v2:
>  - don't create a new, inferior framework to save/restore VMCS
>  - use human-friendly language, just "current VMCS" rather than
>    SDM term "current-VMCS pointer"
>  - don't mix guard() with goto
> ---
>  arch/x86/virt/vmx/tdx/Makefile     |  1 +
>  arch/x86/virt/vmx/tdx/seamldr.c    | 56 ++++++++++++++++++++++++++++++
>  drivers/virt/coco/tdx-host/Kconfig | 10 ++++++
>  3 files changed, 67 insertions(+)
>  create mode 100644 arch/x86/virt/vmx/tdx/seamldr.c
> 
> diff --git a/arch/x86/virt/vmx/tdx/Makefile b/arch/x86/virt/vmx/tdx/Makefile
> index 90da47eb85ee..26aea3531c36 100644
> --- a/arch/x86/virt/vmx/tdx/Makefile
> +++ b/arch/x86/virt/vmx/tdx/Makefile
> @@ -1,2 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0-only
>  obj-y += seamcall.o tdx.o
> +obj-$(CONFIG_INTEL_TDX_MODULE_UPDATE) += seamldr.o
> diff --git a/arch/x86/virt/vmx/tdx/seamldr.c b/arch/x86/virt/vmx/tdx/seamldr.c
> new file mode 100644
> index 000000000000..b99d73f7bb08
> --- /dev/null
> +++ b/arch/x86/virt/vmx/tdx/seamldr.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright(c) 2025 Intel Corporation.

Update to 2026?

> + *
> + * Intel TDX module runtime update
> + */
> +#define pr_fmt(fmt)	"seamldr: " fmt
> +
> +#include <linux/irqflags.h>
> +#include <linux/types.h>
> +
> +#include "seamcall.h"
> +
> +static __maybe_unused int seamldr_call(u64 fn, struct tdx_module_args *args)
> +{
> +	unsigned long flags;
> +	u64 vmcs;
> +	int ret;
> +
> +	if (!is_seamldr_call(fn))
> +		return -EINVAL;
> +
> +	/*
> +	 * SEAMRET from P-SEAMLDR invalidates the current VMCS.  Save/restore
> +	 * the VMCS across P-SEAMLDR SEAMCALLs to avoid clobbering KVM state.
> +	 * Disable interrupts as KVM is allowed to do VMREAD/VMWRITE in IRQ
> +	 * context (but not NMI context).
> +	 */
> +	local_irq_save(flags);
> +
> +	asm goto("1: vmptrst %0\n\t"
> +		 _ASM_EXTABLE(1b, %l[error])
> +		 : "=m" (vmcs) : : "cc" : error);
> +
> +	ret = seamldr_prerr(fn, args);
> +
> +	/*
> +	 * Restore the current VMCS pointer.  VMPTSTR "returns" all ones if the

s/VMPTSTR/VMPTRST 


^ permalink raw reply

* Re: [PATCH v3 06/26] x86/virt/tdx: Prepare to support P-SEAMLDR SEAMCALLs
From: Binbin Wu @ 2026-01-28  5:58 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Farrah Chen, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-7-chao.gao@intel.com>



On 1/23/2026 10:55 PM, Chao Gao wrote:
> P-SEAMLDR is another component alongside the TDX module within the
> protected SEAM range. P-SEAMLDR can update the TDX module at runtime.
> Software can talk with P-SEAMLDR via SEAMCALLs with the bit 63 of RAX
> (leaf number) set to 1 (a.k.a P-SEAMLDR SEAMCALLs).
> 
> P-SEAMLDR SEAMCALLs differ from SEAMCALLs of the TDX module in terms of
> error codes and the handling of the current VMCS.
> 
> In preparation for adding support for P-SEAMLDR SEAMCALLs, do the two
> following changes to SEAMCALL low-level helpers:
> 
> 1) Tweak sc_retry() to retry on "lack of entropy" errors reported by
>    P-SEAMLDR because it uses a different error code.
> 
> 2) Add seamldr_err() to log error messages on P-SEAMLDR SEAMCALL failures.
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Tested-by: Farrah Chen <farrah.chen@intel.com>

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>

^ permalink raw reply

* Re: [PATCH v3 13/26] x86/virt/seamldr: Allocate and populate a module update request
From: Huang, Kai @ 2026-01-28  4:03 UTC (permalink / raw)
  To: kvm@vger.kernel.org, linux-coco@lists.linux.dev,
	linux-kernel@vger.kernel.org, Gao, Chao, x86@kernel.org
  Cc: dave.hansen@linux.intel.com, kas@kernel.org, seanjc@google.com,
	Chatre, Reinette, Weiny, Ira, tglx@linutronix.de, Verma, Vishal L,
	nik.borisov@suse.com, mingo@redhat.com, hpa@zytor.com,
	sagis@google.com, Chen, Farrah, Duan, Zhenzhong,
	Edgecombe, Rick P, paulmck@kernel.org, Annapurve, Vishal,
	yilun.xu@linux.intel.com, Williams, Dan J, bp@alien8.de
In-Reply-To: <20260123145645.90444-14-chao.gao@intel.com>


> +/*
> + * Allocate and populate a seamldr_params.
> + * Note that both @module and @sig should be vmalloc'd memory.

Nit:

How about actually using is_vmalloc_addr() to check in the code rather than
documenting in the comment?

I see you have already checked the overall 'data' buffer is vmalloc()'ed in
seamldr_install_module() so the 'module' and 'sig' (part of 'data') must be
too.  But since is_vmalloc_addr() is cheap so I think it's also fine to do
the check here.  We can also WARN() so it can be used to catch bug.

> + */
> +static struct seamldr_params *alloc_seamldr_params(const void *module, unsigned int module_size,
> +						   const void *sig, unsigned int sig_size)
> +{
> 

[...]

> +	ptr = module;
> +	for (i = 0; i < params->num_module_pages; i++) {
> +		params->mod_pages_pa_list[i] = (vmalloc_to_pfn(ptr) << PAGE_SHIFT) +
> +					       ((unsigned long)ptr & ~PAGE_MASK);
> +		ptr += SZ_4K;
> +	}
> +
> +	return params;
> +}
> 

[...]

> +/*
> + * Verify that the checksum of the entire blob is zero. The checksum is
> + * calculated by summing up all 16-bit words, with carry bits dropped.
> + */
> +static bool verify_checksum(const struct tdx_blob *blob)
> +{
> +	u32 size = blob->len;
> +	u16 checksum = 0;
> +	const u16 *p;
> +	int i;
> +
> +	/* Handle the last byte if the size is odd */
> +	if (size % 2) {
> +		checksum += *((const u8 *)blob + size - 1);
> +		size--;
> +	}
> +
> +	p = (const u16 *)blob;
> +	for (i = 0; i < size; i += 2) {
> +		checksum += *p;
> +		p++;
> +	}
> +
> +	return !checksum;
> +}
> +
> +static struct seamldr_params *init_seamldr_params(const u8 *data, u32 size)
> +{
> 

[...]

> +	if (!verify_checksum(blob)) {
> +		pr_err("invalid checksum\n");
> +		return ERR_PTR(-EINVAL);
> +	}
> +
> +	return alloc_seamldr_params(module, module_size, sig, sig_size);
> +}

It's weird that we have do verify checksum manually, because hardware
normally catches that.

I suppose this is because we want to catch as many errors as possible before
actually asking P-SEAMLDR to do module update, since in order to do which we
have to shutdown the existing module first and there's no returning point
once we reach that?

If so a comment would be helpful.

Also, it's also weird that you have to write code for checksum on your own.
I guess the kernel should already have some library code for that.

I checked and it _seems_ the code in lib/checksum.c could be used?

I am not expert though, but I think we should use kernel lib code when we
can.


^ permalink raw reply

* Re: [PATCH v3 05/26] coco/tdx-host: Expose TDX Module version
From: Binbin Wu @ 2026-01-28  3:48 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma
In-Reply-To: <20260123145645.90444-6-chao.gao@intel.com>



On 1/23/2026 10:55 PM, Chao Gao wrote:
> For TDX Module updates, userspace needs to select compatible update
> versions based on the current module version. This design delegates
> module selection complexity to userspace because TDX Module update
> policies are complex and version series are platform-specific.
> 
> For example, the 1.5.x series is for certain platform generations, while
> the 2.0.x series is intended for others. And TDX Module 1.5.x may be
> updated to 1.5.y but not to 1.5.y+1.
> 
> Expose the TDX Module version to userspace via sysfs to aid module
> selection. Since the TDX faux device will drive module updates, expose
> the version as its attribute.
> 
> This approach follows the pattern used by microcode updates and other
> CoCo implementations:
> 
> 1. AMD has a PCI device for the PSP for SEV which provides an existing
>    place to hang their equivalent metadata.
> 
> 2. ARM CCA will likely have a faux device (although it isn't obvious if
>    they have a need to export version information there) [1]
> 
> 3. Microcode revisions are exposed as CPU device attributes
> 
> One bonus of exposing TDX Module version via sysfs is: TDX Module
> version information remains available even after dmesg logs are cleared.
> 
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Link: https://lore.kernel.org/all/2025073035-bulginess-rematch-b92e@gregkh/ # [1]

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>


^ permalink raw reply

* Re: [PATCH v3 10/26] coco/tdx-host: Implement FW_UPLOAD sysfs ABI for TDX Module updates
From: Huang, Kai @ 2026-01-28  3:30 UTC (permalink / raw)
  To: kvm@vger.kernel.org, linux-coco@lists.linux.dev,
	linux-kernel@vger.kernel.org, Gao, Chao, x86@kernel.org
  Cc: dave.hansen@linux.intel.com, kas@kernel.org, seanjc@google.com,
	Chatre, Reinette, Weiny, Ira, tglx@linutronix.de, Verma, Vishal L,
	nik.borisov@suse.com, mingo@redhat.com, hpa@zytor.com,
	sagis@google.com, Chen, Farrah, Duan, Zhenzhong,
	Edgecombe, Rick P, paulmck@kernel.org, Annapurve, Vishal,
	yilun.xu@linux.intel.com, Williams, Dan J, bp@alien8.de
In-Reply-To: <20260123145645.90444-11-chao.gao@intel.com>


> 2. TDX Module Updates complete synchronously within .write(), meaning
>    .poll_complete() is only called after successful updates and therefore
>    always returns success

Nit:

Why "updates" instead of "update"?  Is there multiple updates possible
within .write()?

[...]

> 
>  
> +struct tdx_fw_upload_status {
> +	bool cancel_request;
> +};
> +
> +struct fw_upload *tdx_fwl;

Can 'tdx_fwl' be static?

[...]

> 
> +static void seamldr_init(struct device *dev)
> +{
> +	const struct tdx_sys_info *tdx_sysinfo = tdx_get_sysinfo();
> +	int ret;
> +
> +	if (WARN_ON_ONCE(!tdx_sysinfo))
> +		return;
> +
> +	if (!IS_ENABLED(CONFIG_INTEL_TDX_MODULE_UPDATE))
> +		return;
> +
> +	if (!tdx_supports_runtime_update(tdx_sysinfo))
> +		pr_info("Current TDX Module cannot be updated. Consider BIOS updates\n");

What's the point of continuing if runtime update is not supported?

> +
> +	tdx_fwl = firmware_upload_register(THIS_MODULE, dev, "seamldr_upload",
> +					   &tdx_fw_ops, &tdx_fw_upload_status);
> +	ret = PTR_ERR_OR_ZERO(tdx_fwl);
> +	if (ret)
> +		pr_err("failed to register module uploader %d\n", ret);
> +}
> +
> +static void seamldr_deinit(void)
> +{
> +	if (tdx_fwl)
> +		firmware_upload_unregister(tdx_fwl);
> +}
> +
> +static int tdx_host_probe(struct faux_device *fdev)
> +{
> +	seamldr_init(&fdev->dev);

IMHO you need a comment to explain why seamldr_init() doesn't return error
and tdx_host_probe() already returns success?

> +	return 0;
> +}
> +
> +static void tdx_host_remove(struct faux_device *fdev)
> +{
> +	seamldr_deinit();
> +}
> +
> +static struct faux_device_ops tdx_host_ops = {
> +	.probe		= tdx_host_probe,
> +	.remove		= tdx_host_remove,
> +};
> +
>  static struct faux_device *fdev;
>  
>  static int __init tdx_host_init(void)
> @@ -107,7 +229,7 @@ static int __init tdx_host_init(void)
>  	if (!x86_match_cpu(tdx_host_ids) || !tdx_get_sysinfo())
>  		return -ENODEV;
>  
> -	fdev = faux_device_create_with_groups(KBUILD_MODNAME, NULL, NULL, tdx_host_groups);
> +	fdev = faux_device_create_with_groups(KBUILD_MODNAME, NULL, &tdx_host_ops, tdx_host_groups);
>  	if (!fdev)
>  		return -ENODEV;
>  

^ permalink raw reply

* Re: [PATCH v3 04/26] coco/tdx-host: Introduce a "tdx_host" device
From: Binbin Wu @ 2026-01-28  3:24 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Jonathan Cameron, Thomas Gleixner,
	Ingo Molnar, Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-5-chao.gao@intel.com>



On 1/23/2026 10:55 PM, Chao Gao wrote:
[...]
> diff --git a/drivers/virt/coco/Kconfig b/drivers/virt/coco/Kconfig
> index df1cfaf26c65..f7691f64fbe3 100644
> --- a/drivers/virt/coco/Kconfig
> +++ b/drivers/virt/coco/Kconfig
> @@ -17,5 +17,7 @@ source "drivers/virt/coco/arm-cca-guest/Kconfig"
>  source "drivers/virt/coco/guest/Kconfig"
>  endif
>  
> +source "drivers/virt/coco/tdx-host/Kconfig"
> +
>  config TSM
>  	bool
> diff --git a/drivers/virt/coco/Makefile b/drivers/virt/coco/Makefile
> index cb52021912b3..b323b0ae4f82 100644
> --- a/drivers/virt/coco/Makefile
> +++ b/drivers/virt/coco/Makefile
> @@ -6,6 +6,7 @@ obj-$(CONFIG_EFI_SECRET)	+= efi_secret/
>  obj-$(CONFIG_ARM_PKVM_GUEST)	+= pkvm-guest/
>  obj-$(CONFIG_SEV_GUEST)		+= sev-guest/
>  obj-$(CONFIG_INTEL_TDX_GUEST)	+= tdx-guest/
> +obj-$(CONFIG_INTEL_TDX_HOST)	+= tdx-host/

IIUC, the folder name "tdx-host" here stands for TDX host services?
Should it use CONFIG_TDX_HOST_SERVICES here?

>  obj-$(CONFIG_ARM_CCA_GUEST)	+= arm-cca-guest/
>  obj-$(CONFIG_TSM) 		+= tsm-core.o
>  obj-$(CONFIG_TSM_GUEST)		+= guest/
> diff --git a/drivers/virt/coco/tdx-host/Kconfig b/drivers/virt/coco/tdx-host/Kconfig
> new file mode 100644
> index 000000000000..e58bad148a35
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-host/Kconfig
> @@ -0,0 +1,10 @@
> +config TDX_HOST_SERVICES
> +	tristate "TDX Host Services Driver"
> +	depends on INTEL_TDX_HOST
> +	default m
> +	help
> +	  Enable access to TDX host services like module update and
> +	  extensions (e.g. TDX Connect).
> +
> +	  Say y or m if enabling support for confidential virtual machine
> +	  support (CONFIG_INTEL_TDX_HOST). The module is called tdx_host.ko
> diff --git a/drivers/virt/coco/tdx-host/Makefile b/drivers/virt/coco/tdx-host/Makefile
> new file mode 100644
> index 000000000000..e61e749a8dff
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-host/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_TDX_HOST_SERVICES) += tdx-host.o
> diff --git a/drivers/virt/coco/tdx-host/tdx-host.c b/drivers/virt/coco/tdx-host/tdx-host.c
> new file mode 100644
> index 000000000000..c77885392b09
> --- /dev/null
> +++ b/drivers/virt/coco/tdx-host/tdx-host.c
> @@ -0,0 +1,43 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TDX host user interface driver
> + *
> + * Copyright (C) 2025 Intel Corporation

Nit:
Update the year to 2026?



^ permalink raw reply

* Re: [PATCH v3 09/26] coco/tdx-host: Expose P-SEAMLDR information via sysfs
From: Huang, Kai @ 2026-01-28  3:07 UTC (permalink / raw)
  To: kvm@vger.kernel.org, linux-coco@lists.linux.dev,
	linux-kernel@vger.kernel.org, Gao, Chao, x86@kernel.org
  Cc: Edgecombe, Rick P, seanjc@google.com, Duan, Zhenzhong,
	yilun.xu@linux.intel.com, sagis@google.com, Chatre, Reinette,
	kas@kernel.org, Williams, Dan J, paulmck@kernel.org, Weiny, Ira,
	Annapurve, Vishal, nik.borisov@suse.com,
	dave.hansen@linux.intel.com, Verma, Vishal L, Chen, Farrah
In-Reply-To: <20260123145645.90444-10-chao.gao@intel.com>

On Fri, 2026-01-23 at 06:55 -0800, Chao Gao wrote:
> -ATTRIBUTE_GROUPS(tdx_host);
> +
> +struct attribute_group tdx_host_group = {
> +	.attrs = tdx_host_attrs,
> +};
> +

This 'tdx_host_group' can be static?

^ permalink raw reply

* Re: [PATCH v3 03/26] x86/virt/tdx: Move low level SEAMCALL helpers out of <asm/tdx.h>
From: Binbin Wu @ 2026-01-28  1:37 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-4-chao.gao@intel.com>



On 1/23/2026 10:55 PM, Chao Gao wrote:
> From: Kai Huang <kai.huang@intel.com>
> 
> TDX host core code implements three seamcall*() helpers to make SEAMCALL
> to the TDX module.  Currently, they are implemented in <asm/tdx.h> and
> are exposed to other kernel code which includes <asm/tdx.h>.
> 
> However, other than the TDX host core, seamcall*() are not expected to
> be used by other kernel code directly.  For instance, for all SEAMCALLs
> that are used by KVM, the TDX host core exports a wrapper function for
> each of them.
> 
> Move seamcall*() and related code out of <asm/tdx.h> and make them only
> visible to TDX host core.
> 
> Since TDX host core tdx.c is already very heavy, don't put low level
> seamcall*() code there but to a new dedicated "seamcall.h".  Also,
> currently tdx.c has seamcall_prerr*() helpers which additionally print
> error message when calling seamcall*() fails.  Move them to "seamcall.h"
> as well.  In such way all low level SEAMCALL helpers are in a dedicated
> place, which is much more readable.
> 
> Signed-off-by: Kai Huang <kai.huang@intel.com>
> Signed-off-by: Chao Gao <chao.gao@intel.com>
> Reviewed-by: Zhenzhong Duan <zhenzhong.duan@intel.com>

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>

One question below.

[...]

> diff --git a/arch/x86/virt/vmx/tdx/seamcall.h b/arch/x86/virt/vmx/tdx/seamcall.h
> new file mode 100644
> index 000000000000..0912e03fabfe
> --- /dev/null
> +++ b/arch/x86/virt/vmx/tdx/seamcall.h
> @@ -0,0 +1,99 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/* Copyright (C) 2025 Intel Corporation */

Should this be updated to 2026?



^ permalink raw reply

* Re: [PATCH v3 02/26] x86/virt/tdx: Use %# prefix for hex values in SEAMCALL error messages
From: Binbin Wu @ 2026-01-28  1:34 UTC (permalink / raw)
  To: Chao Gao
  Cc: linux-coco, linux-kernel, kvm, x86, reinette.chatre, ira.weiny,
	kai.huang, dan.j.williams, yilun.xu, sagis, vannapurve, paulmck,
	nik.borisov, zhenzhong.duan, seanjc, rick.p.edgecombe, kas,
	dave.hansen, vishal.l.verma, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, H. Peter Anvin
In-Reply-To: <20260123145645.90444-3-chao.gao@intel.com>



On 1/23/2026 10:55 PM, Chao Gao wrote:
> "%#" format specifier automatically adds the "0x" prefix and has one less
> character than "0x%".
> 
> For conciseness, replace "0x%" with "%#" when printing hexadecimal values
> in SEAMCALL error messages.
> 
> Suggested-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Chao Gao <chao.gao@intel.com>

Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>

> ---
> "0x%" is also used to print TDMR ranges. I didn't convert them to reduce
> code churn, but if they should be converted for consistency, I'm happy
> to do that.

Generally, is there any preference for coding in Linux kernel about
"0x%" VS. "%#"? Or developers just make their own choices?


> 
> v2: new
> ---
>  arch/x86/virt/vmx/tdx/tdx.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/x86/virt/vmx/tdx/tdx.c b/arch/x86/virt/vmx/tdx/tdx.c
> index dbc7cb08ca53..2218bb42af40 100644
> --- a/arch/x86/virt/vmx/tdx/tdx.c
> +++ b/arch/x86/virt/vmx/tdx/tdx.c
> @@ -63,16 +63,16 @@ typedef void (*sc_err_func_t)(u64 fn, u64 err, struct tdx_module_args *args);
>  
>  static inline void seamcall_err(u64 fn, u64 err, struct tdx_module_args *args)
>  {
> -	pr_err("SEAMCALL (%llu) failed: 0x%016llx\n", fn, err);
> +	pr_err("SEAMCALL (%llu) failed: %#016llx\n", fn, err);
>  }
>  
>  static inline void seamcall_err_ret(u64 fn, u64 err,
>  				    struct tdx_module_args *args)
>  {
>  	seamcall_err(fn, err, args);
> -	pr_err("RCX 0x%016llx RDX 0x%016llx R08 0x%016llx\n",
> +	pr_err("RCX %#016llx RDX %#016llx R08 %#016llx\n",
>  			args->rcx, args->rdx, args->r8);
> -	pr_err("R09 0x%016llx R10 0x%016llx R11 0x%016llx\n",
> +	pr_err("R09 %#016llx R10 %#016llx R11 %#016llx\n",
>  			args->r9, args->r10, args->r11);
>  }
>  


^ 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