aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Christopherson <sean.j.christopherson@intel.com>2019-05-07 15:17:55 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2019-06-18 05:47:41 -0400
commitc5f2c76643b612ffa47e4660c8f44deba619b068 (patch)
treed4893e980f629441b857ef9e4877e14ec0617198
parent70f932ecdfe6b593ef6784d55d2c096aafac1510 (diff)
KVM: VMX: Shadow VMCS pin controls
Prepare to shadow all major control fields on a per-VMCS basis, which allows KVM to avoid costly VMWRITEs when switching between vmcs01 and vmcs02. Shadowing pin controls also allows a future patch to remove the per-VMCS 'hv_timer_armed' flag, as the shadow copy is a superset of said flag. Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/vmx/nested.c3
-rw-r--r--arch/x86/kvm/vmx/vmx.c10
-rw-r--r--arch/x86/kvm/vmx/vmx.h2
3 files changed, 8 insertions, 7 deletions
diff --git a/arch/x86/kvm/vmx/nested.c b/arch/x86/kvm/vmx/nested.c
index cd33f3109f24..8617d305fbbd 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -285,6 +285,7 @@ static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs)
285 285
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 vmx_segment_cache_clear(vmx); 289 vmx_segment_cache_clear(vmx);
289} 290}
290 291
@@ -2026,7 +2027,7 @@ static void prepare_vmcs02_early(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
2026 } else { 2027 } else {
2027 exec_control &= ~PIN_BASED_POSTED_INTR; 2028 exec_control &= ~PIN_BASED_POSTED_INTR;
2028 } 2029 }
2029 vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, exec_control); 2030 pin_controls_init(vmx, exec_control);
2030 2031
2031 /* 2032 /*
2032 * EXEC CONTROLS 2033 * EXEC CONTROLS
diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c
index 0e722fa5e189..a709afb04c28 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -3844,7 +3844,7 @@ static void vmx_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
3844{ 3844{
3845 struct vcpu_vmx *vmx = to_vmx(vcpu); 3845 struct vcpu_vmx *vmx = to_vmx(vcpu);
3846 3846
3847 vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_ctrl(vmx)); 3847 pin_controls_set(vmx, vmx_pin_based_exec_ctrl(vmx));
3848 if (cpu_has_secondary_exec_ctrls()) { 3848 if (cpu_has_secondary_exec_ctrls()) {
3849 if (kvm_vcpu_apicv_active(vcpu)) 3849 if (kvm_vcpu_apicv_active(vcpu))
3850 vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL, 3850 vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL,
@@ -4042,7 +4042,7 @@ static void vmx_vcpu_setup(struct vcpu_vmx *vmx)
4042 vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */ 4042 vmcs_write64(VMCS_LINK_POINTER, -1ull); /* 22.3.1.5 */
4043 4043
4044 /* Control */ 4044 /* Control */
4045 vmcs_write32(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_ctrl(vmx)); 4045 pin_controls_init(vmx, vmx_pin_based_exec_ctrl(vmx));
4046 vmx->hv_deadline_tsc = -1; 4046 vmx->hv_deadline_tsc = -1;
4047 4047
4048 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx_exec_control(vmx)); 4048 vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, vmx_exec_control(vmx));
@@ -6366,8 +6366,7 @@ static void vmx_arm_hv_timer(struct vcpu_vmx *vmx, u32 val)
6366{ 6366{
6367 vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, val); 6367 vmcs_write32(VMX_PREEMPTION_TIMER_VALUE, val);
6368 if (!vmx->loaded_vmcs->hv_timer_armed) 6368 if (!vmx->loaded_vmcs->hv_timer_armed)
6369 vmcs_set_bits(PIN_BASED_VM_EXEC_CONTROL, 6369 pin_controls_setbit(vmx, PIN_BASED_VMX_PREEMPTION_TIMER);
6370 PIN_BASED_VMX_PREEMPTION_TIMER);
6371 vmx->loaded_vmcs->hv_timer_armed = true; 6370 vmx->loaded_vmcs->hv_timer_armed = true;
6372} 6371}
6373 6372
@@ -6396,8 +6395,7 @@ static void vmx_update_hv_timer(struct kvm_vcpu *vcpu)
6396 } 6395 }
6397 6396
6398 if (vmx->loaded_vmcs->hv_timer_armed) 6397 if (vmx->loaded_vmcs->hv_timer_armed)
6399 vmcs_clear_bits(PIN_BASED_VM_EXEC_CONTROL, 6398 pin_controls_clearbit(vmx, PIN_BASED_VMX_PREEMPTION_TIMER);
6400 PIN_BASED_VMX_PREEMPTION_TIMER);
6401 vmx->loaded_vmcs->hv_timer_armed = false; 6399 vmx->loaded_vmcs->hv_timer_armed = false;
6402} 6400}
6403 6401
diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index db4f9289d5da..1cdcaf8a6d97 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -88,6 +88,7 @@ struct pt_desc {
88struct vmx_controls_shadow { 88struct vmx_controls_shadow {
89 u32 vm_entry; 89 u32 vm_entry;
90 u32 vm_exit; 90 u32 vm_exit;
91 u32 pin;
91}; 92};
92 93
93/* 94/*
@@ -423,6 +424,7 @@ static inline void lname##_controls_clearbit(struct vcpu_vmx *vmx, u32 val) \
423} 424}
424BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS) 425BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS)
425BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS) 426BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS)
427BUILD_CONTROLS_SHADOW(pin, PIN_BASED_VM_EXEC_CONTROL)
426 428
427static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx) 429static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx)
428{ 430{