diff options
author | Sean Christopherson <sean.j.christopherson@intel.com> | 2019-05-07 15:17:56 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-06-18 05:47:42 -0400 |
commit | 2183f5645ae7e074ed1777f3de9a782dd23db248 (patch) | |
tree | 6643b8e5b7f221af98d4337ef111cf0a2d76105c /arch/x86/kvm/vmx/nested.c | |
parent | c5f2c76643b612ffa47e4660c8f44deba619b068 (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.c | 14 |
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); |