[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <efc567ad1a1e4b6045323f2e78bc51ff948f9a75.1770116051.git.isaku.yamahata@intel.com>
Date: Tue, 3 Feb 2026 10:16:54 -0800
From: isaku.yamahata@...el.com
To: kvm@...r.kernel.org
Cc: isaku.yamahata@...el.com,
isaku.yamahata@...il.com,
Paolo Bonzini <pbonzini@...hat.com>,
Sean Christopherson <seanjc@...gle.com>,
linux-kernel@...r.kernel.org
Subject: [PATCH 11/32] KVM: nVMX: Add tertiary VM-execution control VMCS support
From: Isaku Yamahata <isaku.yamahata@...el.com>
Support tertiary processor-based VM-execution control VMCS field.
Signed-off-by: Isaku Yamahata <isaku.yamahata@...el.com>
---
arch/x86/kvm/vmx/hyperv.c | 10 ++++++++++
arch/x86/kvm/vmx/nested.c | 17 +++++++++++++++++
arch/x86/kvm/vmx/nested.h | 7 +++++++
arch/x86/kvm/vmx/vmcs12.c | 1 +
arch/x86/kvm/vmx/vmcs12.h | 3 ++-
5 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/hyperv.c b/arch/x86/kvm/vmx/hyperv.c
index 2731c2e4b0e5..70e210472681 100644
--- a/arch/x86/kvm/vmx/hyperv.c
+++ b/arch/x86/kvm/vmx/hyperv.c
@@ -166,6 +166,12 @@ static bool nested_evmcs_is_valid_controls(enum evmcs_ctrl_type ctrl_type,
return !(val & ~evmcs_get_supported_ctls(ctrl_type));
}
+static bool nested_evmcs_is_valid_controls64(enum evmcs_ctrl_type ctrl_type,
+ u64 val)
+{
+ return !(val & ~evmcs_get_supported_ctls(ctrl_type));
+}
+
int nested_evmcs_check_controls(struct vmcs12 *vmcs12)
{
if (CC(!nested_evmcs_is_valid_controls(EVMCS_PINCTRL,
@@ -188,6 +194,10 @@ int nested_evmcs_check_controls(struct vmcs12 *vmcs12)
vmcs12->vm_entry_controls)))
return -EINVAL;
+ if (CC(!nested_evmcs_is_valid_controls64(EVMCS_3RDEXEC,
+ vmcs12->tertiary_vm_exec_control)))
+ return -EINVAL;
+
/*
* VM-Func controls are 64-bit, but KVM currently doesn't support any
* controls in bits 63:32, i.e. dropping those bits on the consistency
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 8cd56e9f1cf0..3e02dee38e9c 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -1813,6 +1813,7 @@ static void copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, u32 hv_clean_fields
vmcs12->vm_exit_controls = evmcs->vm_exit_controls;
vmcs12->secondary_vm_exec_control =
evmcs->secondary_vm_exec_control;
+ vmcs12->tertiary_vm_exec_control = 0;
}
if (unlikely(!(hv_clean_fields &
@@ -2510,6 +2511,17 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0
secondary_exec_controls_set(vmx, exec_control);
}
+ /*
+ * TERTIARY EXEC CONTROLS
+ */
+ if (cpu_has_tertiary_exec_ctrls()) {
+ u64 ctls = 0;
+
+ /* guest apic timer virtualization will come */
+
+ tertiary_exec_controls_set(vmx, ctls);
+ }
+
/*
* ENTRY CONTROLS
*
@@ -2955,6 +2967,11 @@ static int nested_check_vm_execution_controls(struct kvm_vcpu *vcpu,
vmx->nested.msrs.secondary_ctls_high)))
return -EINVAL;
+ if (nested_cpu_has(vmcs12, CPU_BASED_ACTIVATE_TERTIARY_CONTROLS) &&
+ CC(!vmx_control64_verify(vmcs12->tertiary_vm_exec_control,
+ vmx->nested.msrs.tertiary_ctls)))
+ return -EINVAL;
+
if (CC(vmcs12->cr3_target_count > nested_cpu_vmx_misc_cr3_count(vcpu)) ||
nested_vmx_check_io_bitmap_controls(vcpu, vmcs12) ||
nested_vmx_check_msr_bitmap_controls(vcpu, vmcs12) ||
diff --git a/arch/x86/kvm/vmx/nested.h b/arch/x86/kvm/vmx/nested.h
index d6d89ae1daec..2a3768a194fe 100644
--- a/arch/x86/kvm/vmx/nested.h
+++ b/arch/x86/kvm/vmx/nested.h
@@ -170,6 +170,13 @@ static inline bool nested_cpu_has2(struct vmcs12 *vmcs12, u32 bit)
(vmcs12->secondary_vm_exec_control & bit);
}
+static inline bool nested_cpu_has3(struct vmcs12 *vmcs12, u64 bit)
+{
+ return (vmcs12->cpu_based_vm_exec_control &
+ CPU_BASED_ACTIVATE_TERTIARY_CONTROLS) &&
+ (vmcs12->tertiary_vm_exec_control & bit);
+}
+
static inline bool nested_cpu_has_preemption_timer(struct vmcs12 *vmcs12)
{
return vmcs12->pin_based_vm_exec_control &
diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c
index 4233b5ca9461..2a21864a020a 100644
--- a/arch/x86/kvm/vmx/vmcs12.c
+++ b/arch/x86/kvm/vmx/vmcs12.c
@@ -38,6 +38,7 @@ const unsigned short vmcs12_field_offsets[] = {
FIELD64(PML_ADDRESS, pml_address),
FIELD64(TSC_OFFSET, tsc_offset),
FIELD64(TSC_MULTIPLIER, tsc_multiplier),
+ FIELD64(TERTIARY_VM_EXEC_CONTROL, tertiary_vm_exec_control),
FIELD64(VIRTUAL_APIC_PAGE_ADDR, virtual_apic_page_addr),
FIELD64(APIC_ACCESS_ADDR, apic_access_addr),
FIELD64(POSTED_INTR_DESC_ADDR, posted_intr_desc_addr),
diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h
index 4ad6b16525b9..db1f86a48343 100644
--- a/arch/x86/kvm/vmx/vmcs12.h
+++ b/arch/x86/kvm/vmx/vmcs12.h
@@ -71,7 +71,7 @@ struct __packed vmcs12 {
u64 pml_address;
u64 encls_exiting_bitmap;
u64 tsc_multiplier;
- u64 padding64[1]; /* room for future expansion */
+ u64 tertiary_vm_exec_control;
/*
* To allow migration of L1 (complete with its L2 guests) between
* machines of different natural widths (32 or 64 bit), we cannot have
@@ -261,6 +261,7 @@ static inline void vmx_check_vmcs12_offsets(void)
CHECK_OFFSET(pml_address, 312);
CHECK_OFFSET(encls_exiting_bitmap, 320);
CHECK_OFFSET(tsc_multiplier, 328);
+ CHECK_OFFSET(tertiary_vm_exec_control, 336);
CHECK_OFFSET(cr0_guest_host_mask, 344);
CHECK_OFFSET(cr4_guest_host_mask, 352);
CHECK_OFFSET(cr0_read_shadow, 360);
--
2.45.2
Powered by blists - more mailing lists