From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail.zytor.com (terminus.zytor.com [198.137.202.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76D962459E3; Wed, 23 Jul 2025 17:54:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.137.202.136 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; cv=none; b=WY0QIjuAcKOJehyNU03F7MbtgJPRReIlOAdAb6Ze+LfoYoNUUmdcvctwUE/54FD2OzrZZEhnLe3DnvIZwcOIPJj/gdUDybldI3rzsuoGlaYpLhRLsQdARtzGfVJq1eod0ZSobw9qY4+fMcGNBzgr02c3ToVckv2wGcMXpVmHnc4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1753293284; c=relaxed/simple; bh=yLJafNzCIkr8cm+K3MVGzcF9qeCDkcZ8/ki+sxYq0Wk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=XXcxFVGG7+dI+8FDQJ39fGITzzOofleH4h8lQi8dajx9BA+RUx81pp7laYKcRlLmdDG0Cl31Hfgggm10h6N76H/rWEmLw3yjWfUBECslIoTCO0q5Q7CrN/KMsmc5t9E5Yu2hExzdx9kabKrdZbcvtuZYc7lgbEoHd3+0+xX38aI= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com; spf=pass smtp.mailfrom=zytor.com; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b=cCqFPoUX; arc=none smtp.client-ip=198.137.202.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=zytor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=zytor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=zytor.com header.i=@zytor.com header.b="cCqFPoUX" Received: from terminus.zytor.com (terminus.zytor.com [IPv6:2607:7c80:54:3:0:0:0:136]) (authenticated bits=0) by mail.zytor.com (8.18.1/8.17.1) with ESMTPSA id 56NHrf091284522 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NO); Wed, 23 Jul 2025 10:54:03 -0700 DKIM-Filter: OpenDKIM Filter v2.11.0 mail.zytor.com 56NHrf091284522 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zytor.com; s=2025072201; t=1753293244; bh=os4Ok/VLeBI2u8zU4x1IGR71AhGTmdvxIlIpHFI3iCo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cCqFPoUXEb3OWe9NteIcsWCfXcW9OzVYhOY4iVtzC2kVR3QdaxspfMLCBgo5lfp1Z 8F0uN5aR/9SBgyX61Z+2eofZjf/85C14Tt8EdQtAYCjYUQxNdAOTXhGv6QEJlYzugz JH7WQflIEzNw2iKD6Mx50D22VIlYI3wQJ+WHbPB346Gr6w9Uo6WkAdWTNg6pPvoIe7 JPqseMOOj6FnpbBjNDidBGJpOiSDE6RP5rJrnZ/cd9tUUm+NV3vGr4dDS5IEZnYFB0 KIbHsmzXpTpD5JB/wXXp//zfCXlWQcvOsBOMbScaXo8VwPMj6hONapwKac5kfOoMl8 Thj1yXjynN5Pg== From: "Xin Li (Intel)" To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org, linux-doc@vger.kernel.org Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net, tglx@linutronix.de, mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com, x86@kernel.org, hpa@zytor.com, xin@zytor.com, luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com, chao.gao@intel.com, hch@infradead.org Subject: [PATCH v5 19/23] KVM: nVMX: Add support for the secondary VM exit controls Date: Wed, 23 Jul 2025 10:53:37 -0700 Message-ID: <20250723175341.1284463-20-xin@zytor.com> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250723175341.1284463-1-xin@zytor.com> References: <20250723175341.1284463-1-xin@zytor.com> Precedence: bulk X-Mailing-List: linux-doc@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Xin Li Enable the secondary VM exit controls to prepare for nested FRED. Signed-off-by: Xin Li Signed-off-by: Xin Li (Intel) Tested-by: Shan Kang Tested-by: Xuelian Guo --- Changes in v5: * Allow writing MSR_IA32_VMX_EXIT_CTLS2 (Sean). * Add TB from Xuelian Guo. Change in v3: * Read secondary VM exit controls from vmcs_conf insteasd of the hardware MSR MSR_IA32_VMX_EXIT_CTLS2 to avoid advertising features to L1 that KVM itself doesn't support, e.g. because the expected entry+exit pairs aren't supported. (Sean Christopherson) --- Documentation/virt/kvm/x86/nested-vmx.rst | 1 + arch/x86/kvm/vmx/capabilities.h | 1 + arch/x86/kvm/vmx/nested.c | 25 ++++++++++++++++++++++- arch/x86/kvm/vmx/vmcs12.c | 1 + arch/x86/kvm/vmx/vmcs12.h | 2 ++ arch/x86/kvm/x86.h | 2 +- 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/Documentation/virt/kvm/x86/nested-vmx.rst b/Documentation/virt/kvm/x86/nested-vmx.rst index ac2095d41f02..e64ef231f310 100644 --- a/Documentation/virt/kvm/x86/nested-vmx.rst +++ b/Documentation/virt/kvm/x86/nested-vmx.rst @@ -217,6 +217,7 @@ struct shadow_vmcs is ever changed. u16 host_fs_selector; u16 host_gs_selector; u16 host_tr_selector; + u64 secondary_vm_exit_controls; }; diff --git a/arch/x86/kvm/vmx/capabilities.h b/arch/x86/kvm/vmx/capabilities.h index 76c69685b9be..6d446574d770 100644 --- a/arch/x86/kvm/vmx/capabilities.h +++ b/arch/x86/kvm/vmx/capabilities.h @@ -37,6 +37,7 @@ struct nested_vmx_msrs { u32 pinbased_ctls_high; u32 exit_ctls_low; u32 exit_ctls_high; + u64 secondary_exit_ctls; u32 entry_ctls_low; u32 entry_ctls_high; u32 misc_low; diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c index b8ea1969113d..4405d176cf74 100644 --- a/arch/x86/kvm/vmx/nested.c +++ b/arch/x86/kvm/vmx/nested.c @@ -1512,6 +1512,11 @@ int vmx_set_vmx_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) return -EINVAL; vmx->nested.msrs.vmfunc_controls = data; return 0; + case MSR_IA32_VMX_EXIT_CTLS2: + if (data & ~vmcs_config.nested.secondary_exit_ctls) + return -EINVAL; + vmx->nested.msrs.secondary_exit_ctls = data; + return 0; default: /* * The rest of the VMX capability MSRs do not support restore. @@ -1551,6 +1556,9 @@ int vmx_get_vmx_msr(struct nested_vmx_msrs *msrs, u32 msr_index, u64 *pdata) if (msr_index == MSR_IA32_VMX_EXIT_CTLS) *pdata |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR; break; + case MSR_IA32_VMX_EXIT_CTLS2: + *pdata = msrs->secondary_exit_ctls; + break; case MSR_IA32_VMX_TRUE_ENTRY_CTLS: case MSR_IA32_VMX_ENTRY_CTLS: *pdata = vmx_control_msr( @@ -2501,6 +2509,11 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct loaded_vmcs *vmcs0 exec_control &= ~VM_EXIT_LOAD_IA32_EFER; vm_exit_controls_set(vmx, exec_control); + if (exec_control & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) { + exec_control = __secondary_vm_exit_controls_get(vmcs01); + secondary_vm_exit_controls_set(vmx, exec_control); + } + /* * Interrupt/Exception Fields */ @@ -7029,7 +7042,7 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf, VM_EXIT_HOST_ADDR_SPACE_SIZE | #endif VM_EXIT_LOAD_IA32_PAT | VM_EXIT_SAVE_IA32_PAT | - VM_EXIT_CLEAR_BNDCFGS; + VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_ACTIVATE_SECONDARY_CONTROLS; msrs->exit_ctls_high |= VM_EXIT_ALWAYSON_WITHOUT_TRUE_MSR | VM_EXIT_LOAD_IA32_EFER | VM_EXIT_SAVE_IA32_EFER | @@ -7038,6 +7051,16 @@ static void nested_vmx_setup_exit_ctls(struct vmcs_config *vmcs_conf, /* We support free control of debug control saving. */ msrs->exit_ctls_low &= ~VM_EXIT_SAVE_DEBUG_CONTROLS; + + if (msrs->exit_ctls_high & VM_EXIT_ACTIVATE_SECONDARY_CONTROLS) { + msrs->secondary_exit_ctls = vmcs_conf->vmexit_2nd_ctrl; + /* + * As the secondary VM exit control is always loaded, do not + * advertise any feature in it to nVMX until its nVMX support + * is ready. + */ + msrs->secondary_exit_ctls &= 0; + } } static void nested_vmx_setup_entry_ctls(struct vmcs_config *vmcs_conf, diff --git a/arch/x86/kvm/vmx/vmcs12.c b/arch/x86/kvm/vmx/vmcs12.c index 106a72c923ca..9fac24fd5b4b 100644 --- a/arch/x86/kvm/vmx/vmcs12.c +++ b/arch/x86/kvm/vmx/vmcs12.c @@ -66,6 +66,7 @@ const unsigned short vmcs12_field_offsets[] = { FIELD64(HOST_IA32_PAT, host_ia32_pat), FIELD64(HOST_IA32_EFER, host_ia32_efer), FIELD64(HOST_IA32_PERF_GLOBAL_CTRL, host_ia32_perf_global_ctrl), + FIELD64(SECONDARY_VM_EXIT_CONTROLS, secondary_vm_exit_controls), FIELD(PIN_BASED_VM_EXEC_CONTROL, pin_based_vm_exec_control), FIELD(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control), FIELD(EXCEPTION_BITMAP, exception_bitmap), diff --git a/arch/x86/kvm/vmx/vmcs12.h b/arch/x86/kvm/vmx/vmcs12.h index 56fd150a6f24..1fe3ed9108aa 100644 --- a/arch/x86/kvm/vmx/vmcs12.h +++ b/arch/x86/kvm/vmx/vmcs12.h @@ -185,6 +185,7 @@ struct __packed vmcs12 { u16 host_gs_selector; u16 host_tr_selector; u16 guest_pml_index; + u64 secondary_vm_exit_controls; }; /* @@ -360,6 +361,7 @@ static inline void vmx_check_vmcs12_offsets(void) CHECK_OFFSET(host_gs_selector, 992); CHECK_OFFSET(host_tr_selector, 994); CHECK_OFFSET(guest_pml_index, 996); + CHECK_OFFSET(secondary_vm_exit_controls, 998); } extern const unsigned short vmcs12_field_offsets[]; diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index aff93c5b2484..bdd37bce0bc9 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h @@ -94,7 +94,7 @@ do { \ * associated feature that KVM supports for nested virtualization. */ #define KVM_FIRST_EMULATED_VMX_MSR MSR_IA32_VMX_BASIC -#define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_VMFUNC +#define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_EXIT_CTLS2 #define KVM_DEFAULT_PLE_GAP 128 #define KVM_VMX_DEFAULT_PLE_WINDOW 4096 -- 2.50.1