diff options
author | Sean Christopherson <sean.j.christopherson@intel.com> | 2019-05-07 15:17:55 -0400 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2019-06-18 05:47:41 -0400 |
commit | c5f2c76643b612ffa47e4660c8f44deba619b068 (patch) | |
tree | d4893e980f629441b857ef9e4877e14ec0617198 | |
parent | 70f932ecdfe6b593ef6784d55d2c096aafac1510 (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.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/vmx/vmx.c | 10 | ||||
-rw-r--r-- | arch/x86/kvm/vmx/vmx.h | 2 |
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 { | |||
88 | struct vmx_controls_shadow { | 88 | struct 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 | } |
424 | BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS) | 425 | BUILD_CONTROLS_SHADOW(vm_entry, VM_ENTRY_CONTROLS) |
425 | BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS) | 426 | BUILD_CONTROLS_SHADOW(vm_exit, VM_EXIT_CONTROLS) |
427 | BUILD_CONTROLS_SHADOW(pin, PIN_BASED_VM_EXEC_CONTROL) | ||
426 | 428 | ||
427 | static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx) | 429 | static inline void vmx_segment_cache_clear(struct vcpu_vmx *vmx) |
428 | { | 430 | { |