From: Vitaly Kuznetsov <vkuznets@redhat.com>
To: kvm@vger.kernel.org, Paolo Bonzini <pbonzini@redhat.com>,
Sean Christopherson <seanjc@google.com>
Cc: Anirudh Rayabharam <anrayabh@linux.microsoft.com>,
Wanpeng Li <wanpengli@tencent.com>,
Jim Mattson <jmattson@google.com>,
Maxim Levitsky <mlevitsk@redhat.com>,
linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v3 09/25] KVM: VMX: nVMX: Support TSC scaling and PERF_GLOBAL_CTRL with enlightened VMCS
Date: Fri, 8 Jul 2022 16:42:07 +0200 [thread overview]
Message-ID: <20220708144223.610080-10-vkuznets@redhat.com> (raw)
In-Reply-To: <20220708144223.610080-1-vkuznets@redhat.com>
Enlightened VMCS v1 got updated and now includes the required fields
for TSC scaling and loading PERF_GLOBAL_CTRL upon VMENTER/VMEXIT
features. For Hyper-V on KVM enablement, KVM can just observe VMX control
MSRs and use the features (with or without eVMCS) when
possible. Hyper-V on KVM case is trickier because of live migration:
the new features require explicit enablement from VMM to not break
it. Luckily, the updated eVMCS revision comes with a feature bit in
CPUID.0x4000000A.EBX.
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
---
arch/x86/kvm/hyperv.c | 2 +-
arch/x86/kvm/vmx/evmcs.c | 88 +++++++++++++++++++++++++++++++--------
arch/x86/kvm/vmx/evmcs.h | 17 ++------
arch/x86/kvm/vmx/nested.c | 2 +-
arch/x86/kvm/vmx/vmx.c | 2 +-
5 files changed, 78 insertions(+), 33 deletions(-)
diff --git a/arch/x86/kvm/hyperv.c b/arch/x86/kvm/hyperv.c
index b666902da4d9..406c5e273983 100644
--- a/arch/x86/kvm/hyperv.c
+++ b/arch/x86/kvm/hyperv.c
@@ -2562,7 +2562,7 @@ int kvm_get_hv_cpuid(struct kvm_vcpu *vcpu, struct kvm_cpuid2 *cpuid,
case HYPERV_CPUID_NESTED_FEATURES:
ent->eax = evmcs_ver;
ent->eax |= HV_X64_NESTED_MSR_BITMAP;
-
+ ent->ebx |= HV_X64_NESTED_EVMCS1_2022_UPDATE;
break;
case HYPERV_CPUID_SYNDBG_VENDOR_AND_MAX_FUNCTIONS:
diff --git a/arch/x86/kvm/vmx/evmcs.c b/arch/x86/kvm/vmx/evmcs.c
index 8bea5dea0341..52a53debd806 100644
--- a/arch/x86/kvm/vmx/evmcs.c
+++ b/arch/x86/kvm/vmx/evmcs.c
@@ -368,7 +368,60 @@ uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu)
return 0;
}
-void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata)
+enum evmcs_v1_revision {
+ EVMCSv1_2016,
+ EVMCSv1_2022,
+};
+
+enum evmcs_unsupported_ctrl_type {
+ EVMCS_EXIT_CTLS,
+ EVMCS_ENTRY_CTLS,
+ EVMCS_2NDEXEC,
+ EVMCS_PINCTRL,
+ EVMCS_VMFUNC,
+};
+
+static u32 evmcs_get_unsupported_ctls(struct kvm_vcpu *vcpu,
+ enum evmcs_unsupported_ctrl_type ctrl_type)
+{
+ struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
+ enum evmcs_v1_revision evmcs_rev = EVMCSv1_2016;
+
+ if (!hv_vcpu)
+ return 0;
+
+ if (hv_vcpu->cpuid_cache.nested_ebx & HV_X64_NESTED_EVMCS1_2022_UPDATE)
+ evmcs_rev = EVMCSv1_2022;
+
+ switch (ctrl_type) {
+ case EVMCS_EXIT_CTLS:
+ if (evmcs_rev == EVMCSv1_2016)
+ return EVMCS1_UNSUPPORTED_VMEXIT_CTRL |
+ VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
+ else
+ return EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
+ case EVMCS_ENTRY_CTLS:
+ if (evmcs_rev == EVMCSv1_2016)
+ return EVMCS1_UNSUPPORTED_VMENTRY_CTRL |
+ VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
+ else
+ return EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
+ case EVMCS_2NDEXEC:
+ if (evmcs_rev == EVMCSv1_2016)
+ return EVMCS1_UNSUPPORTED_2NDEXEC |
+ SECONDARY_EXEC_TSC_SCALING;
+ else
+ return EVMCS1_UNSUPPORTED_2NDEXEC;
+ case EVMCS_PINCTRL:
+ return EVMCS1_UNSUPPORTED_PINCTRL;
+ case EVMCS_VMFUNC:
+ return EVMCS1_UNSUPPORTED_VMFUNC;
+ }
+
+ return 0;
+}
+
+void nested_evmcs_filter_control_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
{
u32 ctl_low = (u32)*pdata;
u32 ctl_high = (u32)(*pdata >> 32);
@@ -380,72 +433,73 @@ void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata)
switch (msr_index) {
case MSR_IA32_VMX_EXIT_CTLS:
case MSR_IA32_VMX_TRUE_EXIT_CTLS:
- ctl_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
+ ctl_high &= ~evmcs_get_unsupported_ctls(vcpu, EVMCS_EXIT_CTLS);
break;
case MSR_IA32_VMX_ENTRY_CTLS:
case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
- ctl_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
+ ctl_high &= ~evmcs_get_unsupported_ctls(vcpu, EVMCS_ENTRY_CTLS);
break;
case MSR_IA32_VMX_PROCBASED_CTLS2:
- ctl_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC;
+ ctl_high &= ~evmcs_get_unsupported_ctls(vcpu, EVMCS_2NDEXEC);
break;
case MSR_IA32_VMX_TRUE_PINBASED_CTLS:
case MSR_IA32_VMX_PINBASED_CTLS:
- ctl_high &= ~EVMCS1_UNSUPPORTED_PINCTRL;
+ ctl_high &= ~evmcs_get_unsupported_ctls(vcpu, EVMCS_PINCTRL);
break;
case MSR_IA32_VMX_VMFUNC:
- ctl_low &= ~EVMCS1_UNSUPPORTED_VMFUNC;
+ ctl_low &= ~evmcs_get_unsupported_ctls(vcpu, EVMCS_VMFUNC);
break;
}
*pdata = ctl_low | ((u64)ctl_high << 32);
}
-int nested_evmcs_check_controls(struct vmcs12 *vmcs12)
+int nested_evmcs_check_controls(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
{
int ret = 0;
u32 unsupp_ctl;
unsupp_ctl = vmcs12->pin_based_vm_exec_control &
- EVMCS1_UNSUPPORTED_PINCTRL;
+ evmcs_get_unsupported_ctls(vcpu, EVMCS_PINCTRL);
if (unsupp_ctl) {
trace_kvm_nested_vmenter_failed(
- "eVMCS: unsupported pin-based VM-execution controls",
+ "eVMCS: unsupported pin-based VM-execution controls: ",
unsupp_ctl);
ret = -EINVAL;
}
unsupp_ctl = vmcs12->secondary_vm_exec_control &
- EVMCS1_UNSUPPORTED_2NDEXEC;
+ evmcs_get_unsupported_ctls(vcpu, EVMCS_2NDEXEC);
if (unsupp_ctl) {
trace_kvm_nested_vmenter_failed(
- "eVMCS: unsupported secondary VM-execution controls",
+ "eVMCS: unsupported secondary VM-execution controls: ",
unsupp_ctl);
ret = -EINVAL;
}
unsupp_ctl = vmcs12->vm_exit_controls &
- EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
+ evmcs_get_unsupported_ctls(vcpu, EVMCS_EXIT_CTLS);
if (unsupp_ctl) {
trace_kvm_nested_vmenter_failed(
- "eVMCS: unsupported VM-exit controls",
+ "eVMCS: unsupported VM-exit controls: ",
unsupp_ctl);
ret = -EINVAL;
}
unsupp_ctl = vmcs12->vm_entry_controls &
- EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
+ evmcs_get_unsupported_ctls(vcpu, EVMCS_ENTRY_CTLS);
if (unsupp_ctl) {
trace_kvm_nested_vmenter_failed(
- "eVMCS: unsupported VM-entry controls",
+ "eVMCS: unsupported VM-entry controls: ",
unsupp_ctl);
ret = -EINVAL;
}
- unsupp_ctl = vmcs12->vm_function_control & EVMCS1_UNSUPPORTED_VMFUNC;
+ unsupp_ctl = vmcs12->vm_function_control &
+ evmcs_get_unsupported_ctls(vcpu, EVMCS_VMFUNC);
if (unsupp_ctl) {
trace_kvm_nested_vmenter_failed(
- "eVMCS: unsupported VM-function controls",
+ "eVMCS: unsupported VM-function controls: ",
unsupp_ctl);
ret = -EINVAL;
}
diff --git a/arch/x86/kvm/vmx/evmcs.h b/arch/x86/kvm/vmx/evmcs.h
index f886a8ff0342..4b809c79ae63 100644
--- a/arch/x86/kvm/vmx/evmcs.h
+++ b/arch/x86/kvm/vmx/evmcs.h
@@ -37,16 +37,9 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs);
* EPTP_LIST_ADDRESS = 0x00002024,
* VMREAD_BITMAP = 0x00002026,
* VMWRITE_BITMAP = 0x00002028,
- *
- * TSC_MULTIPLIER = 0x00002032,
* PLE_GAP = 0x00004020,
* PLE_WINDOW = 0x00004022,
* VMX_PREEMPTION_TIMER_VALUE = 0x0000482E,
- * GUEST_IA32_PERF_GLOBAL_CTRL = 0x00002808,
- * HOST_IA32_PERF_GLOBAL_CTRL = 0x00002c04,
- *
- * Currently unsupported in KVM:
- * GUEST_IA32_RTIT_CTL = 0x00002814,
*/
#define EVMCS1_UNSUPPORTED_PINCTRL (PIN_BASED_POSTED_INTR | \
PIN_BASED_VMX_PREEMPTION_TIMER)
@@ -58,12 +51,10 @@ DECLARE_STATIC_KEY_FALSE(enable_evmcs);
SECONDARY_EXEC_ENABLE_PML | \
SECONDARY_EXEC_ENABLE_VMFUNC | \
SECONDARY_EXEC_SHADOW_VMCS | \
- SECONDARY_EXEC_TSC_SCALING | \
SECONDARY_EXEC_PAUSE_LOOP_EXITING)
#define EVMCS1_UNSUPPORTED_VMEXIT_CTRL \
- (VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL | \
- VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)
-#define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL)
+ (VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)
+#define EVMCS1_UNSUPPORTED_VMENTRY_CTRL (0)
#define EVMCS1_UNSUPPORTED_VMFUNC (VMX_VMFUNC_EPTP_SWITCHING)
struct evmcs_field {
@@ -243,7 +234,7 @@ bool nested_enlightened_vmentry(struct kvm_vcpu *vcpu, u64 *evmcs_gpa);
uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu);
int nested_enable_evmcs(struct kvm_vcpu *vcpu,
uint16_t *vmcs_version);
-void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata);
-int nested_evmcs_check_controls(struct vmcs12 *vmcs12);
+void nested_evmcs_filter_control_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
+int nested_evmcs_check_controls(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12);
#endif /* __KVM_X86_VMX_EVMCS_H */
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 4fc84f0f5875..dcf3ee645212 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -2891,7 +2891,7 @@ static int nested_vmx_check_controls(struct kvm_vcpu *vcpu,
return -EINVAL;
if (to_vmx(vcpu)->nested.enlightened_vmcs_enabled)
- return nested_evmcs_check_controls(vmcs12);
+ return nested_evmcs_check_controls(vcpu, vmcs12);
return 0;
}
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index c30115b9cb33..b4915d841357 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -1858,7 +1858,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
*/
if (!msr_info->host_initiated &&
vmx->nested.enlightened_vmcs_enabled)
- nested_evmcs_filter_control_msr(msr_info->index,
+ nested_evmcs_filter_control_msr(vcpu, msr_info->index,
&msr_info->data);
break;
case MSR_IA32_RTIT_CTL:
--
2.35.3
next prev parent reply other threads:[~2022-07-08 14:43 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-08 14:41 [PATCH v3 00/25] KVM: VMX: Support updated eVMCSv1 revision + use vmcs_config for L1 VMX MSRs Vitaly Kuznetsov
2022-07-08 14:41 ` [PATCH v3 01/25] KVM: x86: hyper-v: Expose access to debug MSRs in the partition privilege flags Vitaly Kuznetsov
2022-07-12 11:49 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 02/25] x86/hyperv: Fix 'struct hv_enlightened_vmcs' definition Vitaly Kuznetsov
2022-07-08 14:42 ` [PATCH v3 03/25] x86/hyperv: Update " Vitaly Kuznetsov
2022-07-12 11:51 ` Maxim Levitsky
2022-07-12 12:19 ` Vitaly Kuznetsov
2022-07-08 14:42 ` [PATCH v3 04/25] KVM: VMX: Define VMCS-to-EVMCS conversion for the new fields Vitaly Kuznetsov
2022-07-12 11:50 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 05/25] KVM: nVMX: Support several new fields in eVMCSv1 Vitaly Kuznetsov
2022-07-12 11:51 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 06/25] KVM: x86: hyper-v: Cache HYPERV_CPUID_NESTED_FEATURES CPUID leaf Vitaly Kuznetsov
2022-07-12 11:51 ` Maxim Levitsky
2022-07-13 15:45 ` Vitaly Kuznetsov
2022-07-08 14:42 ` [PATCH v3 07/25] KVM: selftests: Add ENCLS_EXITING_BITMAP{,HIGH} VMCS fields Vitaly Kuznetsov
2022-07-12 11:51 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 08/25] KVM: selftests: Switch to updated eVMCSv1 definition Vitaly Kuznetsov
2022-07-12 11:52 ` Maxim Levitsky
2022-07-08 14:42 ` Vitaly Kuznetsov [this message]
2022-07-12 11:53 ` [PATCH v3 09/25] KVM: VMX: nVMX: Support TSC scaling and PERF_GLOBAL_CTRL with enlightened VMCS Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 10/25] KVM: selftests: Enable TSC scaling in evmcs selftest Vitaly Kuznetsov
2022-07-12 11:54 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 11/25] KVM: VMX: Get rid of eVMCS specific VMX controls sanitization Vitaly Kuznetsov
2022-07-12 11:54 ` Maxim Levitsky
2022-07-12 12:14 ` Vitaly Kuznetsov
2022-07-12 12:16 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 12/25] KVM: VMX: Check VM_ENTRY_IA32E_MODE in setup_vmcs_config() Vitaly Kuznetsov
2022-07-12 11:55 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 13/25] KVM: VMX: Check CPU_BASED_{INTR,NMI}_WINDOW_EXITING " Vitaly Kuznetsov
2022-07-12 11:55 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 14/25] KVM: VMX: Tweak the special handling of SECONDARY_EXEC_ENCLS_EXITING " Vitaly Kuznetsov
2022-07-12 11:56 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 15/25] KVM: VMX: Extend VMX controls macro shenanigans Vitaly Kuznetsov
2022-07-12 11:56 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 16/25] KVM: VMX: Move CPU_BASED_CR8_{LOAD,STORE}_EXITING filtering out of setup_vmcs_config() Vitaly Kuznetsov
2022-07-12 11:56 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 17/25] KVM: VMX: Add missing VMEXIT controls to vmcs_config Vitaly Kuznetsov
2022-07-12 11:57 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 18/25] KVM: VMX: Add missing CPU based VM execution " Vitaly Kuznetsov
2022-07-12 11:57 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 19/25] KVM: VMX: Adjust CR3/INVPLG interception for EPT=y at runtime, not setup Vitaly Kuznetsov
2022-07-12 11:58 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 20/25] KVM: x86: VMX: Replace some Intel model numbers with mnemonics Vitaly Kuznetsov
2022-07-12 11:58 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 21/25] KVM: VMX: Move LOAD_IA32_PERF_GLOBAL_CTRL errata handling out of setup_vmcs_config() Vitaly Kuznetsov
2022-07-12 11:59 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 22/25] KVM: nVMX: Always set required-1 bits of pinbased_ctls to PIN_BASED_ALWAYSON_WITHOUT_TRUE_MSR Vitaly Kuznetsov
2022-07-12 12:02 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 23/25] KVM: nVMX: Use sanitized allowed-1 bits for VMX control MSRs Vitaly Kuznetsov
2022-07-12 12:11 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 24/25] KVM: VMX: Cache MSR_IA32_VMX_MISC in vmcs_config Vitaly Kuznetsov
2022-07-12 12:11 ` Maxim Levitsky
2022-07-08 14:42 ` [PATCH v3 25/25] KVM: nVMX: Use cached host MSR_IA32_VMX_MISC value for setting up nested MSR Vitaly Kuznetsov
2022-07-12 12:11 ` Maxim Levitsky
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=20220708144223.610080-10-vkuznets@redhat.com \
--to=vkuznets@redhat.com \
--cc=anrayabh@linux.microsoft.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mlevitsk@redhat.com \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
--cc=wanpengli@tencent.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
all inboxes | Powered by JetHome®