Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: "Edgecombe, Rick P" <rick.p.edgecombe@intel.com>
To: "kvm@vger.kernel.org" <kvm@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"binbin.wu@linux.intel.com" <binbin.wu@linux.intel.com>
Cc: "Gao, Chao" <chao.gao@intel.com>,
	"seanjc@google.com" <seanjc@google.com>,
	"dave.hansen@linux.intel.com" <dave.hansen@linux.intel.com>,
	"kas@kernel.org" <kas@kernel.org>,
	"Li, Xiaoyao" <xiaoyao.li@intel.com>,
	"pbonzini@redhat.com" <pbonzini@redhat.com>,
	"andrew.cooper3@citrix.com" <andrew.cooper3@citrix.com>,
	"nik.borisov@suse.com" <nik.borisov@suse.com>
Subject: Re: [PATCH v3 0/4] KVM: TDX: Validate directly configurable CPUID bits
Date: Thu, 27 Aug 2026 19:33:07 +0000	[thread overview]
Message-ID: <e2f8f7976ac6a54e0bbda0e65ed9990940d9fef3.camel@intel.com> (raw)
In-Reply-To: <20260827031837.2863609-1-binbin.wu@linux.intel.com>

On Thu, 2026-08-27 at 11:18 +0800, Binbin Wu wrote:
> Hi,
> 
> The purpose of this patch series is to prevent userspace from enabling
> host state clobbering features that KVM does not support for TDX.  A host
> state clobbering feature exposed on a new TDX module/platform can corrupt
> host state if KVM does not explicitly save and restore the related MSR(s)
> across host/guest transitions.  If such a feature is blindly exposed to
> and used by a TD, the host will behave unexpectedly.
> 
> Except for a few fixed-1 bits required for basic TDX support, host state
> clobbering features are either directly configurable or gated by TD
> ATTRIBUTES/XFAM.  So an allowlist covering only the directly configurable
> CPUID bits, plus the corresponding filtering and validation, is sufficient
> to serve the purpose while keeping the code footprint small.
> 
> Open question for Sean/Paolo
> ============================
> This revision comes long after Sean confirmed the overall direction on
> RFC v2 [1], due to internal discussions about a potential backward
> compatibility issue: a CPUID field can change virtualization type to
> directly configurable.  The TDX module can maintain backward
> compatibility in most cases; the problematic case is a single bit that
> was effectively "1" and non-configurable becoming directly configurable.
> The only scenario we can envision for that is an x86 feature deprecation.
> 
> In that case the TDX module has to decide how to handle deprecation,
> especially with respect to TD migration compatibility.  That
> pre-existing VMs with the deprecated feature enabled cannot migrate from
> an old platform to a new one is a problem shared by TDX and VMX, but the
> TDX module additionally has to decide:
> - Whether to allow TDs newly created on old platforms to migrate to new
>   platforms.
> - Whether to allow TDs created on new platforms to migrate to old
>   platforms.
> 
> There are two options:
> 1. Do not offer the VMM the ability to configure the bit, i.e. simply
>    report it as zero on platforms that no longer support the feature.
>    This disallows both migration cases above.
> 2. Make the bit directly configurable so the VMM can clear it even on
>    platforms that still support the feature, allowing both migration
>    cases above.  However, since the bit is not in KVM's allowlist,
>    userspace would no longer be able to enable it on old platforms after
>    a TDX module update.
> 
> Adding all supported CPUID bits to the allowlist, regardless of their
> virtualization type in the TDX module, would avoid the compatibility
> issue for option 2, at the cost of a significantly larger series.

I think we could only do this if no new fixed-1 bits are added. If they were,
then a future fixes-1 bit could be added then deprecated. An old kernel would
not know about it.

But we will not see new fixed-1 bits?

> 
> Given that x86 feature deprecation is expected to be very rare, and that
> Intel will discuss such cases with the community beforehand, does the
> approach taken by this series look acceptable?
> 

In the event a feature bit is turned configurable to support creating TDs that
can be migrated to new platforms without the feature, then the desired value for
the bit on the old platform will be 0. Which is what it would end up being set
as, if the bit was not in the KVM side allow list. So everything will work as
desired for that use?

But a user on the old platform that didn't care about migration and was using
the feature, would suddenly lose it after TDX module upgrade that turned the bit
configurable

But it isn't a kernel bug, so I'd think to punt on this and let TDX module
figure out a solution if/when the time comes. Probably various opt-in knobs to
allow for working around it. If they are not worried, we don't need to worry and
bloat the kernel to prepare for it.

>   If so, the goal for this
> revision is to collect detailed feedback and, where appropriate,
> Reviewed-by tags.
> 
> Expected host state clobbering behavior for TDX
> ===============================================
> We also want to call for discussions about the expected host state
> clobbering behavior for TDX here for future features.
> 
> For a normal VMX guest, VM entry/exit behavior for a given piece of CPU
> state is architecturally defined: state is either switched by hardware via
> VMCS host/guest fields, or left as the guest value on VM exit and managed
> by KVM in software.
> 
> For TDs, the host/guest transition goes through TDH.VP.ENTER, and what the
> TDX module does with a given piece of host state is defined by the TDX
> module ABI rather than by the x86 architecture.
> 
> What we would like to align on is the expected baseline behavior of
> TDH.VP.ENTER for future features.  The proposal is to have TDX simply
> match VMX behavior, i.e. on return from TDH.VP.ENTER, state that VMX would
> restore from the VMCS host fields is restored, and state that VMX would
> leave as the guest value is clobbered.  That keeps a single model for VMM,
> and means enabling a new feature for TDs requires the same work flow as
> enabling it for VMX.

Ideally the TDX save/restore would share code with normal VMs. On the other hand
if we don't share enter/exit paths sufficiently, we may need to duplicate some
save/restore in tdx code. Depending on how much of which category we have, it
could be better for the kernel to have either one.

And if TDX always saved/restored all state across VP.ENTER, then we don't need
bit filtering? What are the problems then with exposing everything to userspace
as we currently do?

> 
> FRED is a useful concrete example.  Under VMX, the FRED host state in
> IA32_FRED_CONFIG, IA32_FRED_STKLVLS, IA32_FRED_RSP1-3 and
> IA32_FRED_SSP1-3 is covered by the VMCS host-state area, so the TDX module
> is expected to restore these MSRs on TDH.VP.ENTER return.  IA32_FRED_RSP0
> and IA32_PL0_SSP (a.k.a. IA32_FRED_SSP0) are handled by software, so the
> TDX module is expected to clobber them on TDH.VP.ENTER return.

And so the ability to have a design like this for the feature depends on CPUID
bit filtering to be in place, otherwise new modules on old kernels can clobber
host state unexpectedly. Future features that follow this approach will need
some VMM opt-in to say "VMM is filtering CPUID bit config", so TDX can safely
expose new clobbering bits. Otherwise, features like FRED will be problems on
old kernels. Do we want it? Where would it get plugged in?

> 
> The series
> ==========
> 
> Starting with v2 [2], the series takes a simpler, TDX-contained approach
> instead of the comprehensive CPUID paranoid verification framework across
> VMX, SVM, and TDX proposed in v1 [3].  It validates only the TDX directly
> configurable CPUID bits, which are reported by the TDX module in
> CPUID_CONFIG fields that the VMM can configure for a TD.  All filtering
> and validation logic is isolated within TDX code.  This is sufficient to
> address the host clobbering issue because:
> - The TDX module will not introduce new host state clobbering features
>   that are fixed-1.
> - Non-directly configurable feature bits (i.e. features controlled by XFAM
>   or ATTRIBUTES) cannot be enabled by userspace without KVM's support.
> 
> Specifically, this series builds a KVM-side allowlist of supported TDX
> directly configurable CPUID bits to:
>  - Filter KVM_TDX_CAPABILITIES
>    Replace the hardcoded denylist to only report configurable bits that
>    KVM explicitly supports.
>  - Validate KVM_TDX_INIT_VM
>    Reject any configurable bit that the TDX module allows but KVM does
>    not support, as well as CPUID entries with an unexpected subleaf.
> 
> With this allowlist, newly added TDX configurable CPUID bits will not be
> exposed to userspace until KVM explicitly opts in after fulfilling the
> necessary virtualization requirements.
> 
> The allowlist consists of two parts:
> - Feature CPUID bits, which are tracked in tdx_cpu_cfg_caps[] following
>   the organization of kvm_cpu_caps[].  It holds KVM's supported masks for
>   the TDX configurable CPUID feature bits.
> - Non-feature multi-bit fields, which are handled at runtime for the CPUID
>   registers holding such fields.
> 
> For compatibility with older TDX modules that report CORE_CAPABILITIES as
> fixed-1, report CORE_CAPABILITIES as configurable even though KVM does not
> support guest access to MSR_IA32_CORE_CAPS.  This allows userspace to keep
> enabling CORE_CAPABILITIES when the bit changes from fixed-1 to directly
> configurable, and allows userspace to infer that the bit is no longer
> fixed-1 so it can adjust its expectations.
> 
> Known limitation:
> - The series does not check KVM_SET_CPUID2 input for consistency with the
>   CPUID configuration supplied through KVM_TDX_INIT_VM.  This is not
>   required for host safety today because KVM does not use its vCPU CPUID
>   model to decide whether to manage host-clobbering state for TDs.  A
>   consistency check should be added if KVM ever starts relying on the vCPU
>   CPUID model for such decisions.


  parent reply	other threads:[~2026-08-27 19:33 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-27  3:18 [PATCH v3 0/4] KVM: TDX: Validate directly configurable CPUID bits Binbin Wu
2026-08-27  3:18 ` [PATCH v3 1/4] KVM: TDX: Track configurable CPUID bits allowed by KVM Binbin Wu
2026-08-27  3:18 ` [PATCH v3 2/4] KVM: TDX: Report CORE_CAPABILITIES as configurable Binbin Wu
2026-08-27  3:18 ` [PATCH v3 3/4] KVM: TDX: Filter configurable CPUID bits Binbin Wu
2026-08-27  3:18 ` [PATCH v3 4/4] KVM: TDX: Validate userspace CPUID input for KVM_TDX_INIT_VM Binbin Wu
2026-08-27  3:24   ` sashiko-bot
2026-08-27  7:25     ` Binbin Wu
2026-08-27 19:33 ` Edgecombe, Rick P [this message]
2026-08-28  3:19   ` [PATCH v3 0/4] KVM: TDX: Validate directly configurable CPUID bits Binbin Wu
2026-08-28 16:58     ` Edgecombe, Rick P

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e2f8f7976ac6a54e0bbda0e65ed9990940d9fef3.camel@intel.com \
    --to=rick.p.edgecombe@intel.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=binbin.wu@linux.intel.com \
    --cc=chao.gao@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=kas@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nik.borisov@suse.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=xiaoyao.li@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox