|
Alexander Graf |
aee234 |
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
Alexander Graf |
aee234 |
Date: Thu, 24 Aug 2017 13:55:35 +0200
|
|
Alexander Graf |
aee234 |
Subject: KVM: VMX: cache secondary exec controls
|
|
Alexander Graf |
aee234 |
Patch-mainline: v4.14-rc1
|
|
Alexander Graf |
aee234 |
Git-commit: 80154d77c922d0f9bb1e4d115ff760c066c12d8f
|
|
Alexander Graf |
aee234 |
References: bsc#1077761
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
Currently, secondary execution controls are divided in three groups:
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
- static, depending mostly on the module arguments or the processor
|
|
Alexander Graf |
aee234 |
(vmx_secondary_exec_control)
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
- static, depending on CPUID (vmx_cpuid_update)
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
- dynamic, depending on nested VMX or local APIC state
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
Because walking CPUID is expensive, prepare_vmcs02 is using only
|
|
Alexander Graf |
aee234 |
the first group. This however is unnecessarily complicated. Just
|
|
Alexander Graf |
aee234 |
cache the static secondary execution controls, and then prepare_vmcs02
|
|
Alexander Graf |
aee234 |
does not need to compute them every time. Computation of all static
|
|
Alexander Graf |
aee234 |
secondary execution controls is now kept in a single function,
|
|
Alexander Graf |
aee234 |
vmx_compute_secondary_exec_control.
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Alexander Graf |
aee234 |
Acked-by: Alexander Graf <agraf@suse.de>
|
|
Alexander Graf |
aee234 |
---
|
|
Alexander Graf |
aee234 |
arch/x86/kvm/vmx.c | 100 ++++++++++++++++++++++++++++-------------------------
|
|
Alexander Graf |
aee234 |
1 file changed, 54 insertions(+), 46 deletions(-)
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
--- a/arch/x86/kvm/vmx.c
|
|
Alexander Graf |
aee234 |
+++ b/arch/x86/kvm/vmx.c
|
|
Alexander Graf |
aee234 |
@@ -574,6 +574,8 @@
|
|
Alexander Graf |
aee234 |
#endif
|
|
Alexander Graf |
aee234 |
u32 vm_entry_controls_shadow;
|
|
Alexander Graf |
aee234 |
u32 vm_exit_controls_shadow;
|
|
Alexander Graf |
aee234 |
+ u32 secondary_exec_control;
|
|
Alexander Graf |
aee234 |
+
|
|
Alexander Graf |
aee234 |
/*
|
|
Alexander Graf |
aee234 |
* loaded_vmcs points to the VMCS currently used in this vcpu. For a
|
|
Alexander Graf |
aee234 |
* non-nested (L1) guest, it always points to vmcs01. For a nested
|
|
Alexander Graf |
aee234 |
@@ -2797,7 +2799,10 @@
|
|
Alexander Graf |
aee234 |
vmx->nested.nested_vmx_procbased_ctls_low &=
|
|
Alexander Graf |
aee234 |
~(CPU_BASED_CR3_LOAD_EXITING | CPU_BASED_CR3_STORE_EXITING);
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
- /* secondary cpu-based controls */
|
|
Alexander Graf |
aee234 |
+ /*
|
|
Alexander Graf |
aee234 |
+ * secondary cpu-based controls. Do not include those that
|
|
Alexander Graf |
aee234 |
+ * depend on CPUID bits, they are added later by vmx_cpuid_update.
|
|
Alexander Graf |
aee234 |
+ */
|
|
Alexander Graf |
aee234 |
rdmsr(MSR_IA32_VMX_PROCBASED_CTLS2,
|
|
Alexander Graf |
aee234 |
vmx->nested.nested_vmx_secondary_ctls_low,
|
|
Alexander Graf |
aee234 |
vmx->nested.nested_vmx_secondary_ctls_high);
|
|
Alexander Graf |
aee234 |
@@ -2805,7 +2810,6 @@
|
|
Alexander Graf |
aee234 |
vmx->nested.nested_vmx_secondary_ctls_high &=
|
|
Alexander Graf |
aee234 |
SECONDARY_EXEC_RDRAND | SECONDARY_EXEC_RDSEED |
|
|
Alexander Graf |
aee234 |
SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
|
|
Alexander Graf |
aee234 |
- SECONDARY_EXEC_RDTSCP |
|
|
Alexander Graf |
aee234 |
SECONDARY_EXEC_DESC |
|
|
Alexander Graf |
aee234 |
SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE |
|
|
Alexander Graf |
aee234 |
SECONDARY_EXEC_APIC_REGISTER_VIRT |
|
|
Alexander Graf |
aee234 |
@@ -5252,10 +5256,12 @@
|
|
Alexander Graf |
aee234 |
return exec_control;
|
|
Alexander Graf |
aee234 |
}
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
-static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx)
|
|
Alexander Graf |
aee234 |
+static void vmx_compute_secondary_exec_control(struct vcpu_vmx *vmx)
|
|
Alexander Graf |
aee234 |
{
|
|
Alexander Graf |
aee234 |
+ struct kvm_vcpu *vcpu = &vmx->vcpu;
|
|
Alexander Graf |
aee234 |
+
|
|
Alexander Graf |
aee234 |
u32 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl;
|
|
Alexander Graf |
aee234 |
- if (!cpu_need_virtualize_apic_accesses(&vmx->vcpu))
|
|
Alexander Graf |
aee234 |
+ if (!cpu_need_virtualize_apic_accesses(vcpu))
|
|
Alexander Graf |
aee234 |
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
|
|
Alexander Graf |
aee234 |
if (vmx->vpid == 0)
|
|
Alexander Graf |
aee234 |
exec_control &= ~SECONDARY_EXEC_ENABLE_VPID;
|
|
Alexander Graf |
aee234 |
@@ -5269,7 +5275,7 @@
|
|
Alexander Graf |
aee234 |
exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST;
|
|
Alexander Graf |
aee234 |
if (!ple_gap)
|
|
Alexander Graf |
aee234 |
exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING;
|
|
Alexander Graf |
aee234 |
- if (!kvm_vcpu_apicv_active(&vmx->vcpu))
|
|
Alexander Graf |
aee234 |
+ if (!kvm_vcpu_apicv_active(vcpu))
|
|
Alexander Graf |
aee234 |
exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT |
|
|
Alexander Graf |
aee234 |
SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY);
|
|
Alexander Graf |
aee234 |
exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE;
|
|
Alexander Graf |
aee234 |
@@ -5283,7 +5289,43 @@
|
|
Alexander Graf |
aee234 |
if (!enable_pml)
|
|
Alexander Graf |
aee234 |
exec_control &= ~SECONDARY_EXEC_ENABLE_PML;
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
- return exec_control;
|
|
Alexander Graf |
aee234 |
+ if (vmx_rdtscp_supported()) {
|
|
Alexander Graf |
aee234 |
+ bool rdtscp_enabled = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP);
|
|
Alexander Graf |
aee234 |
+ if (!rdtscp_enabled)
|
|
Alexander Graf |
aee234 |
+ exec_control &= ~SECONDARY_EXEC_RDTSCP;
|
|
Alexander Graf |
aee234 |
+
|
|
Alexander Graf |
aee234 |
+ if (nested) {
|
|
Alexander Graf |
aee234 |
+ if (rdtscp_enabled)
|
|
Alexander Graf |
aee234 |
+ vmx->nested.nested_vmx_secondary_ctls_high |=
|
|
Alexander Graf |
aee234 |
+ SECONDARY_EXEC_RDTSCP;
|
|
Alexander Graf |
aee234 |
+ else
|
|
Alexander Graf |
aee234 |
+ vmx->nested.nested_vmx_secondary_ctls_high &=
|
|
Alexander Graf |
aee234 |
+ ~SECONDARY_EXEC_RDTSCP;
|
|
Alexander Graf |
aee234 |
+ }
|
|
Alexander Graf |
aee234 |
+ }
|
|
Alexander Graf |
aee234 |
+
|
|
Alexander Graf |
aee234 |
+ if (vmx_invpcid_supported()) {
|
|
Alexander Graf |
aee234 |
+ /* Exposing INVPCID only when PCID is exposed */
|
|
Alexander Graf |
aee234 |
+ bool invpcid_enabled =
|
|
Alexander Graf |
aee234 |
+ guest_cpuid_has(vcpu, X86_FEATURE_INVPCID) &&
|
|
Alexander Graf |
aee234 |
+ guest_cpuid_has(vcpu, X86_FEATURE_PCID);
|
|
Alexander Graf |
aee234 |
+
|
|
Alexander Graf |
aee234 |
+ if (!invpcid_enabled) {
|
|
Alexander Graf |
aee234 |
+ exec_control &= ~SECONDARY_EXEC_ENABLE_INVPCID;
|
|
Alexander Graf |
aee234 |
+ guest_cpuid_clear(vcpu, X86_FEATURE_INVPCID);
|
|
Alexander Graf |
aee234 |
+ }
|
|
Alexander Graf |
aee234 |
+
|
|
Alexander Graf |
aee234 |
+ if (nested) {
|
|
Alexander Graf |
aee234 |
+ if (invpcid_enabled)
|
|
Alexander Graf |
aee234 |
+ vmx->nested.nested_vmx_secondary_ctls_high |=
|
|
Alexander Graf |
aee234 |
+ SECONDARY_EXEC_ENABLE_INVPCID;
|
|
Alexander Graf |
aee234 |
+ else
|
|
Alexander Graf |
aee234 |
+ vmx->nested.nested_vmx_secondary_ctls_high &=
|
|
Alexander Graf |
aee234 |
+ ~SECONDARY_EXEC_ENABLE_INVPCID;
|
|
Alexander Graf |
aee234 |
+ }
|
|
Alexander Graf |
aee234 |
+ }
|
|
Alexander Graf |
aee234 |
+
|
|
Alexander Graf |
aee234 |
+ vmx->secondary_exec_control = exec_control;
|
|
Alexander Graf |
aee234 |
}
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
static void ept_set_mmio_spte_mask(void)
|
|
Alexander Graf |
aee234 |
@@ -5327,8 +5369,9 @@
|
|
Alexander Graf |
aee234 |
vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx_exec_control(vmx));
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
if (cpu_has_secondary_exec_ctrls()) {
|
|
Alexander Graf |
aee234 |
+ vmx_compute_secondary_exec_control(vmx);
|
|
Alexander Graf |
aee234 |
vmcs_write32(SECONDARY_VM_EXEC_CONTROL,
|
|
Alexander Graf |
aee234 |
- vmx_secondary_exec_control(vmx));
|
|
Alexander Graf |
aee234 |
+ vmx->secondary_exec_control);
|
|
Alexander Graf |
aee234 |
}
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
if (kvm_vcpu_apicv_active(&vmx->vcpu)) {
|
|
Alexander Graf |
aee234 |
@@ -9598,47 +9641,12 @@
|
|
Alexander Graf |
aee234 |
static void vmx_cpuid_update(struct kvm_vcpu *vcpu)
|
|
Alexander Graf |
aee234 |
{
|
|
Alexander Graf |
aee234 |
struct vcpu_vmx *vmx = to_vmx(vcpu);
|
|
Alexander Graf |
aee234 |
- u32 secondary_exec_ctl = vmx_secondary_exec_control(vmx);
|
|
Alexander Graf |
aee234 |
-
|
|
Alexander Graf |
aee234 |
- if (vmx_rdtscp_supported()) {
|
|
Alexander Graf |
aee234 |
- bool rdtscp_enabled = guest_cpuid_has(vcpu, X86_FEATURE_RDTSCP);
|
|
Alexander Graf |
aee234 |
- if (!rdtscp_enabled)
|
|
Alexander Graf |
aee234 |
- secondary_exec_ctl &= ~SECONDARY_EXEC_RDTSCP;
|
|
Alexander Graf |
aee234 |
-
|
|
Alexander Graf |
aee234 |
- if (nested) {
|
|
Alexander Graf |
aee234 |
- if (rdtscp_enabled)
|
|
Alexander Graf |
aee234 |
- vmx->nested.nested_vmx_secondary_ctls_high |=
|
|
Alexander Graf |
aee234 |
- SECONDARY_EXEC_RDTSCP;
|
|
Alexander Graf |
aee234 |
- else
|
|
Alexander Graf |
aee234 |
- vmx->nested.nested_vmx_secondary_ctls_high &=
|
|
Alexander Graf |
aee234 |
- ~SECONDARY_EXEC_RDTSCP;
|
|
Alexander Graf |
aee234 |
- }
|
|
Alexander Graf |
aee234 |
- }
|
|
Alexander Graf |
aee234 |
-
|
|
Alexander Graf |
aee234 |
- if (vmx_invpcid_supported()) {
|
|
Alexander Graf |
aee234 |
- /* Exposing INVPCID only when PCID is exposed */
|
|
Alexander Graf |
aee234 |
- bool invpcid_enabled =
|
|
Alexander Graf |
aee234 |
- guest_cpuid_has(vcpu, X86_FEATURE_INVPCID) &&
|
|
Alexander Graf |
aee234 |
- guest_cpuid_has(vcpu, X86_FEATURE_PCID);
|
|
Alexander Graf |
aee234 |
-
|
|
Alexander Graf |
aee234 |
- if (!invpcid_enabled) {
|
|
Alexander Graf |
aee234 |
- secondary_exec_ctl &= ~SECONDARY_EXEC_ENABLE_INVPCID;
|
|
Alexander Graf |
aee234 |
- guest_cpuid_clear(vcpu, X86_FEATURE_INVPCID);
|
|
Alexander Graf |
aee234 |
- }
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
- if (nested) {
|
|
Alexander Graf |
aee234 |
- if (invpcid_enabled)
|
|
Alexander Graf |
aee234 |
- vmx->nested.nested_vmx_secondary_ctls_high |=
|
|
Alexander Graf |
aee234 |
- SECONDARY_EXEC_ENABLE_INVPCID;
|
|
Alexander Graf |
aee234 |
- else
|
|
Alexander Graf |
aee234 |
- vmx->nested.nested_vmx_secondary_ctls_high &=
|
|
Alexander Graf |
aee234 |
- ~SECONDARY_EXEC_ENABLE_INVPCID;
|
|
Alexander Graf |
aee234 |
- }
|
|
Alexander Graf |
aee234 |
+ if (cpu_has_secondary_exec_ctrls()) {
|
|
Alexander Graf |
aee234 |
+ vmx_compute_secondary_exec_control(vmx);
|
|
Alexander Graf |
aee234 |
+ vmcs_set_secondary_exec_control(vmx->secondary_exec_control);
|
|
Alexander Graf |
aee234 |
}
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
- if (cpu_has_secondary_exec_ctrls())
|
|
Alexander Graf |
aee234 |
- vmcs_set_secondary_exec_control(secondary_exec_ctl);
|
|
Alexander Graf |
aee234 |
-
|
|
Alexander Graf |
aee234 |
if (nested_vmx_allowed(vcpu))
|
|
Alexander Graf |
aee234 |
to_vmx(vcpu)->msr_ia32_feature_control_valid_bits |=
|
|
Alexander Graf |
aee234 |
FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX;
|
|
Alexander Graf |
aee234 |
@@ -10331,7 +10339,7 @@
|
|
Alexander Graf |
aee234 |
enable_ept ? vmcs12->page_fault_error_code_match : 0);
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
if (cpu_has_secondary_exec_ctrls()) {
|
|
Alexander Graf |
aee234 |
- exec_control = vmx_secondary_exec_control(vmx);
|
|
Alexander Graf |
aee234 |
+ exec_control = vmx->secondary_exec_control;
|
|
Alexander Graf |
aee234 |
|
|
Alexander Graf |
aee234 |
/* Take the following fields only from vmcs12 */
|
|
Alexander Graf |
aee234 |
exec_control &= ~(SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
|