From: Sohil Mehta <sohil.mehta@intel.com>
To: kvm@vger.kernel.org, x86@kernel.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>,
Jonathan Corbet <corbet@lwn.net>,
Shuah Khan <skhan@linuxfoundation.org>,
Thomas Gleixner <tglx@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H . Peter Anvin" <hpa@zytor.com>, Xin Li <xin@zytor.com>,
Andy Lutomirski <luto@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Tom Lendacky <thomas.lendacky@amd.com>,
Nikunj A Dadhania <nikunj@amd.com>,
Shivansh Dhiman <shivansh.dhiman@amd.com>,
David Woodhouse <dwmw@amazon.co.uk>,
Chao Gao <chao.gao@intel.com>,
Binbin Wu <binbin.wu@linux.intel.com>,
Sohil Mehta <sohil.mehta@intel.com>,
Zhao Liu <zhao1.liu@intel.com>, Yosry Ahmed <yosry@kernel.org>,
David Matlack <dmatlack@google.com>,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: [PATCH v10 24/28] KVM: nVMX: Validate FRED-related VMCS fields
Date: Fri, 11 Sep 2026 14:36:54 -0700 [thread overview]
Message-ID: <20260911213659.2025974-25-sohil.mehta@intel.com> (raw)
In-Reply-To: <20260911213659.2025974-1-sohil.mehta@intel.com>
From: "Xin Li (Intel)" <xin@zytor.com>
Extend nested VMX field validation to include FRED-specific VMCS fields,
mirroring hardware behavior.
This enables support for nested FRED by ensuring control and guest/host
state fields are properly checked.
Signed-off-by: Xin Li (Intel) <xin@zytor.com>
Signed-off-by: Sohil Mehta <sohil.mehta@intel.com>
---
v10:
- Use has_nested_exception to describe the event being injected rather
than the CPU capability, for consistency with has_error_code (Chao).
- Restructure the interruption-information checks into a switch on the
interruption type (Chao).
- Add a CC() statement to the reserved interruption type check so a
VM-entry failure can be correlated with a specific check (Chao).
- Reject the nested-exception bit (bit 13) for interruption types other
than hardware exception, and fold in the nested-exception capability
check.
- Bound the "other event" vector explicitly instead of relying on a
default arm.
- Reject a zero VM-entry instruction length when injecting SYSCALL or
SYSENTER if the vCPU doesn't enumerate zero-length instruction
injection.
---
arch/x86/kvm/vmx/nested.c | 119 +++++++++++++++++++++++++++++++++-----
arch/x86/kvm/vmx/nested.h | 5 ++
2 files changed, 111 insertions(+), 13 deletions(-)
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 83e846fb3fc8..3e0a1ed6440d 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -3111,6 +3111,8 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu,
struct vmcs12 *vmcs12)
{
struct vcpu_vmx *vmx = to_vmx(vcpu);
+ bool fred_enabled = (vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) &&
+ (vmcs12->guest_cr4 & X86_CR4_FRED);
if (CC(!vmx_control_verify(vmcs12->vm_entry_controls,
vmx->nested.msrs.entry_ctls_low,
@@ -3128,22 +3130,11 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu,
u8 vector = intr_info & INTR_INFO_VECTOR_MASK;
u32 intr_type = intr_info & INTR_INFO_INTR_TYPE_MASK;
bool has_error_code = intr_info & INTR_INFO_DELIVER_CODE_MASK;
+ bool has_nested_exception = intr_info & INTR_INFO_NESTED_EXCEPTION_MASK;
bool urg = nested_cpu_has2(vmcs12,
SECONDARY_EXEC_UNRESTRICTED_GUEST);
bool prot_mode = !urg || vmcs12->guest_cr0 & X86_CR0_PE;
- /* VM-entry interruption-info field: interruption type */
- if (CC(intr_type == INTR_TYPE_RESERVED) ||
- CC(intr_type == INTR_TYPE_OTHER_EVENT &&
- !nested_cpu_supports_monitor_trap_flag(vcpu)))
- return -EINVAL;
-
- /* VM-entry interruption-info field: vector */
- if (CC(intr_type == INTR_TYPE_NMI_INTR && vector != NMI_VECTOR) ||
- CC(intr_type == INTR_TYPE_HARD_EXCEPTION && vector > 31) ||
- CC(intr_type == INTR_TYPE_OTHER_EVENT && vector != 0))
- return -EINVAL;
-
/*
* Cannot deliver error code in real mode or if the interrupt
* type is not hardware exception. For other cases, do the
@@ -3167,8 +3158,28 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu,
if (CC(intr_info & INTR_INFO_RESVD_BITS_MASK))
return -EINVAL;
- /* VM-entry instruction length */
+ if (CC(intr_type == INTR_TYPE_RESERVED))
+ return -EINVAL;
+
+ /*
+ * Only for hardware exceptions and when the CPU enumerates
+ * VMX nested-exception support, bit 13 (indicating a nested
+ * exception) has value 1. Otherwise it is reserved.
+ */
+ if (CC(has_nested_exception &&
+ (intr_type != INTR_TYPE_HARD_EXCEPTION ||
+ !nested_cpu_has_nested_exception(vcpu))))
+ return -EINVAL;
+
switch (intr_type) {
+ case INTR_TYPE_NMI_INTR:
+ if (CC(vector != NMI_VECTOR))
+ return -EINVAL;
+ break;
+ case INTR_TYPE_HARD_EXCEPTION:
+ if (CC(vector > 31))
+ return -EINVAL;
+ break;
case INTR_TYPE_SOFT_EXCEPTION:
case INTR_TYPE_SOFT_INTR:
case INTR_TYPE_PRIV_SW_EXCEPTION:
@@ -3176,6 +3187,28 @@ static int nested_check_vm_entry_controls(struct kvm_vcpu *vcpu,
CC(vmcs12->vm_entry_instruction_len == 0 &&
CC(!nested_cpu_has_zero_length_injection(vcpu))))
return -EINVAL;
+ break;
+ case INTR_TYPE_OTHER_EVENT:
+ if (CC(vector > 2))
+ return -EINVAL;
+
+ switch (vector) {
+ case 0:
+ if (CC(!nested_cpu_supports_monitor_trap_flag(vcpu)))
+ return -EINVAL;
+ break;
+ case 1:
+ case 2:
+ if (CC(!fred_enabled))
+ return -EINVAL;
+ if (CC(vmcs12->vm_entry_instruction_len > X86_MAX_INSTRUCTION_LENGTH))
+ return -EINVAL;
+ if (CC(vmcs12->vm_entry_instruction_len == 0 &&
+ !nested_cpu_has_zero_length_injection(vcpu)))
+ return -EINVAL;
+ break;
+ }
+ break;
}
}
@@ -3262,9 +3295,27 @@ static int nested_vmx_check_host_state(struct kvm_vcpu *vcpu,
if (ia32e) {
if (CC(!(vmcs12->host_cr4 & X86_CR4_PAE)))
return -EINVAL;
+ if (nested_cpu_load_host_fred_state(vmcs12)) {
+ if (CC(vmcs12->host_ia32_fred_config & FRED_CONFIG_RESERVED) ||
+ CC(vmcs12->host_ia32_fred_rsp1 & GENMASK_ULL(5, 0)) ||
+ CC(vmcs12->host_ia32_fred_rsp2 & GENMASK_ULL(5, 0)) ||
+ CC(vmcs12->host_ia32_fred_rsp3 & GENMASK_ULL(5, 0)) ||
+ CC(vmcs12->host_ia32_fred_ssp1 & GENMASK_ULL(2, 0)) ||
+ CC(vmcs12->host_ia32_fred_ssp2 & GENMASK_ULL(2, 0)) ||
+ CC(vmcs12->host_ia32_fred_ssp3 & GENMASK_ULL(2, 0)) ||
+ CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_config & PAGE_MASK, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_rsp1, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_rsp2, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_rsp3, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_ssp1, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_ssp2, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->host_ia32_fred_ssp3, vcpu)))
+ return -EINVAL;
+ }
} else {
if (CC(vmcs12->vm_entry_controls & VM_ENTRY_IA32E_MODE) ||
CC(vmcs12->host_cr4 & X86_CR4_PCIDE) ||
+ CC(vmcs12->host_cr4 & X86_CR4_FRED) ||
CC((vmcs12->host_rip) >> 32))
return -EINVAL;
}
@@ -3447,6 +3498,48 @@ static int nested_vmx_check_guest_state(struct kvm_vcpu *vcpu,
CC((vmcs12->guest_bndcfgs & MSR_IA32_BNDCFGS_RSVD))))
return -EINVAL;
+ if (ia32e) {
+ if (nested_cpu_load_guest_fred_state(vmcs12)) {
+ if (CC(vmcs12->guest_ia32_fred_config & FRED_CONFIG_RESERVED) ||
+ CC(vmcs12->guest_ia32_fred_rsp1 & GENMASK_ULL(5, 0)) ||
+ CC(vmcs12->guest_ia32_fred_rsp2 & GENMASK_ULL(5, 0)) ||
+ CC(vmcs12->guest_ia32_fred_rsp3 & GENMASK_ULL(5, 0)) ||
+ CC(vmcs12->guest_ia32_fred_ssp1 & GENMASK_ULL(2, 0)) ||
+ CC(vmcs12->guest_ia32_fred_ssp2 & GENMASK_ULL(2, 0)) ||
+ CC(vmcs12->guest_ia32_fred_ssp3 & GENMASK_ULL(2, 0)) ||
+ CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_config & PAGE_MASK, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_rsp1, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_rsp2, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_rsp3, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_ssp1, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_ssp2, vcpu)) ||
+ CC(is_noncanonical_msr_address(vmcs12->guest_ia32_fred_ssp3, vcpu)))
+ return -EINVAL;
+ }
+ if (vmcs12->guest_cr4 & X86_CR4_FRED) {
+ unsigned int ss_dpl = VMX_AR_DPL(vmcs12->guest_ss_ar_bytes);
+
+ if (CC(ss_dpl == 1 || ss_dpl == 2))
+ return -EINVAL;
+
+ switch (ss_dpl) {
+ case 0:
+ if (CC(!(vmcs12->guest_cs_ar_bytes & VMX_AR_L_MASK)))
+ return -EINVAL;
+ break;
+ case 3:
+ if (CC(vmcs12->guest_rflags & X86_EFLAGS_IOPL))
+ return -EINVAL;
+ if (CC(vmcs12->guest_interruptibility_info & GUEST_INTR_STATE_STI))
+ return -EINVAL;
+ break;
+ }
+ }
+ } else {
+ if (CC(vmcs12->guest_cr4 & X86_CR4_FRED))
+ return -EINVAL;
+ }
+
if (vmcs12->vm_entry_controls & VM_ENTRY_LOAD_CET_STATE) {
if (nested_vmx_check_cet_state_common(vcpu, vmcs12->guest_s_cet,
vmcs12->guest_ssp,
diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index dc5a1e9cb4e9..551121824128 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -334,6 +334,11 @@ static inline bool nested_cpu_has_no_hw_errcode_cc(struct kvm_vcpu *vcpu)
return to_vmx(vcpu)->nested.msrs.basic & VMX_BASIC_NO_HW_ERROR_CODE_CC;
}
+static inline bool nested_cpu_has_nested_exception(struct kvm_vcpu *vcpu)
+{
+ return to_vmx(vcpu)->nested.msrs.basic & VMX_BASIC_NESTED_EXCEPTION;
+}
+
/* No difference in the restrictions on guest and host CR4 in VMX operation. */
#define nested_guest_cr4_valid nested_cr4_valid
#define nested_host_cr4_valid nested_cr4_valid
--
2.43.0
next prev parent reply other threads:[~2026-09-11 21:43 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-11 21:36 [PATCH v10 00/28] KVM: Enable FRED support with KVM VMX Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 01/28] KVM: VMX: Enable support for secondary VM exit controls Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 02/28] KVM: VMX: Initialize VM entry/exit FRED controls in vmcs_config Sohil Mehta
2026-09-11 22:00 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 03/28] KVM: VMX: Disable FRED if FRED consistency checks fail Sohil Mehta
2026-09-11 22:08 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 04/28] x86/cea: Prefix event stack names with ESTACK_ Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 05/28] x86/cea: Use array indexing to simplify exception stack access Sohil Mehta
2026-09-11 21:57 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 06/28] x86/fred: Export this_cpu_fred_rsp() for KVM usage Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 07/28] KVM: VMX: Initialize VMCS FRED fields Sohil Mehta
2026-09-11 22:10 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 08/28] KVM: VMX: Set FRED MSR intercepts Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 09/28] KVM: VMX: Save/restore guest FRED RSP0 Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 10/28] KVM: VMX: Add support for saving and restoring FRED MSRs Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 11/28] KVM: x86: Add a helper to detect if FRED is enabled for a vCPU Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 12/28] KVM: x86: Add a new save/restore flag for FRED metadata Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 13/28] KVM: VMX: Virtualize FRED nested exception tracking Sohil Mehta
2026-09-11 22:09 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 14/28] KVM: VMX: Virtualize FRED event_data Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 15/28] KVM: x86: Include CR4.FRED in the emulator CR4 write mask Sohil Mehta
2026-09-11 22:14 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 16/28] KVM: x86: Mark CR4.FRED as not reserved Sohil Mehta
2026-09-11 22:14 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 17/28] KVM: x86: Handle CR4.FRED when emulating RSM Sohil Mehta
2026-09-11 22:15 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 18/28] KVM: VMX: Dump FRED context in dump_vmcs() Sohil Mehta
2026-09-11 22:11 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 19/28] KVM: x86: Advertise support for FRED Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 20/28] KVM: nVMX: Enable support for secondary VM exit controls Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 21/28] KVM: nVMX: Handle FRED VMCS fields in nested VMX context Sohil Mehta
2026-09-11 22:34 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 22/28] KVM: nVMX: Restrict event data VMCS fields to FRED-supported hosts Sohil Mehta
2026-09-11 22:20 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 23/28] KVM: nVMX: Shadow ORIGINAL_EVENT_DATA and INJECTED_EVENT_DATA fields Sohil Mehta
2026-09-11 21:36 ` Sohil Mehta [this message]
2026-09-11 22:29 ` [PATCH v10 24/28] KVM: nVMX: Validate FRED-related VMCS fields sashiko-bot
2026-09-11 21:36 ` [PATCH v10 25/28] KVM: nVMX: Enable VMX FRED controls Sohil Mehta
2026-09-11 22:37 ` sashiko-bot
2026-09-11 21:36 ` [PATCH v10 26/28] KVM: selftests: Add FRED MSRs to msrs_test Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 27/28] KVM: selftests: Add a new VM guest mode to run user level code Sohil Mehta
2026-09-11 21:36 ` [PATCH v10 28/28] KVM: selftests: Add fred exception tests Sohil Mehta
2026-09-11 22:32 ` sashiko-bot
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=20260911213659.2025974-25-sohil.mehta@intel.com \
--to=sohil.mehta@intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=binbin.wu@linux.intel.com \
--cc=bp@alien8.de \
--cc=chao.gao@intel.com \
--cc=corbet@lwn.net \
--cc=dave.hansen@linux.intel.com \
--cc=dmatlack@google.com \
--cc=dwmw@amazon.co.uk \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.com \
--cc=nikunj@amd.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=seanjc@google.com \
--cc=shivansh.dhiman@amd.com \
--cc=skhan@linuxfoundation.org \
--cc=tglx@kernel.org \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
--cc=xin@zytor.com \
--cc=yosry@kernel.org \
--cc=zhao1.liu@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.