aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx/nested.c
diff options
context:
space:
mode:
authorSean Christopherson <sean.j.christopherson@intel.com>2019-05-07 15:17:56 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2019-06-18 05:47:42 -0400
commit2183f5645ae7e074ed1777f3de9a782dd23db248 (patch)
tree6643b8e5b7f221af98d4337ef111cf0a2d76105c /arch/x86/kvm/vmx/nested.c
parentc5f2c76643b612ffa47e4660c8f44deba619b068 (diff)
KVM: VMX: Shadow VMCS primary execution controls
Prepare to shadow all major control fields on a per-VMCS basis, which allows KVM to avoid VMREADs when switching between vmcs01 and vmcs02, and more importantly can eliminate costly VMWRITEs to controls when preparing vmcs02. Shadowing exec controls also saves a VMREAD when opening virtual INTR/NMI windows, yay... Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'arch/x86/kvm/vmx/nested.c')
-rw-r--r--arch/x86/kvm/vmx/nested.c14
1 files changed, 6 insertions, 8 deletions
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index 8617d305fbbd..3f80df186476 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -286,6 +286,7 @@ static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs)
286 vm_entry_controls_reset_shadow(vmx); 286 vm_entry_controls_reset_shadow(vmx);
287 vm_exit_controls_reset_shadow(vmx); 287 vm_exit_controls_reset_shadow(vmx);
288 pin_controls_reset_shadow(vmx); 288 pin_controls_reset_shadow(vmx);
289 exec_controls_reset_shadow(vmx);
289 vmx_segment_cache_clear(vmx); 290 vmx_segment_cache_clear(vmx);
290} 291}
291 292
@@ -2052,7 +2053,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
2052 */ 2053 */
2053 exec_control &= ~CPU_BASED_USE_IO_BITMAPS; 2054 exec_control &= ~CPU_BASED_USE_IO_BITMAPS;
2054 exec_control |= CPU_BASED_UNCOND_IO_EXITING; 2055 exec_control |= CPU_BASED_UNCOND_IO_EXITING;
2055 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, exec_control); 2056 exec_controls_init(vmx, exec_control);
2056 2057
2057 /* 2058 /*
2058 * SECONDARY EXEC CONTROLS 2059 * SECONDARY EXEC CONTROLS
@@ -2873,8 +2874,7 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
2873 * _not_ what the processor does but it's basically the 2874 * _not_ what the processor does but it's basically the
2874 * only possibility we have. 2875 * only possibility we have.
2875 */ 2876 */
2876 vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL, 2877 exec_controls_clearbit(vmx, CPU_BASED_TPR_SHADOW);
2877 CPU_BASED_TPR_SHADOW);
2878 } else { 2878 } else {
2879 /* 2879 /*
2880 * Write an illegal value to VIRTUAL_APIC_PAGE_ADDR to 2880 * Write an illegal value to VIRTUAL_APIC_PAGE_ADDR to
@@ -2896,11 +2896,9 @@ static void nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
2896 } 2896 }
2897 } 2897 }
2898 if (nested_vmx_prepare_msr_bitmap(vcpu, vmcs12)) 2898 if (nested_vmx_prepare_msr_bitmap(vcpu, vmcs12))
2899 vmcs_set_bits(CPU_BASED_VM_EXEC_CONTROL, 2899 exec_controls_setbit(vmx, CPU_BASED_USE_MSR_BITMAPS);
2900 CPU_BASED_USE_MSR_BITMAPS);
2901 else 2900 else
2902 vmcs_clear_bits(CPU_BASED_VM_EXEC_CONTROL, 2901 exec_controls_clearbit(vmx, CPU_BASED_USE_MSR_BITMAPS);
2903 CPU_BASED_USE_MSR_BITMAPS);
2904} 2902}
2905 2903
2906/* 2904/*
@@ -2953,7 +2951,7 @@ int nested_vmx_enter_non_root_mode(struct kvm_vcpu *vcpu, bool from_vmentry)
2953 u32 exit_reason = EXIT_REASON_INVALID_STATE; 2951 u32 exit_reason = EXIT_REASON_INVALID_STATE;
2954 u32 exit_qual; 2952 u32 exit_qual;
2955 2953
2956 evaluate_pending_interrupts = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL) & 2954 evaluate_pending_interrupts = exec_controls_get(vmx) &
2957 (CPU_BASED_VIRTUAL_INTR_PENDING | CPU_BASED_VIRTUAL_NMI_PENDING); 2955 (CPU_BASED_VIRTUAL_INTR_PENDING | CPU_BASED_VIRTUAL_NMI_PENDING);
2958 if (likely(!evaluate_pending_interrupts) && kvm_vcpu_apicv_active(vcpu)) 2956 if (likely(!evaluate_pending_interrupts) && kvm_vcpu_apicv_active(vcpu))
2959 evaluate_pending_interrupts |= vmx_has_apicv_interrupt(vcpu); 2957 evaluate_pending_interrupts |= vmx_has_apicv_interrupt(vcpu);