Commit b4b65b56 authored by Paolo Bonzini's avatar Paolo Bonzini

KVM: x86: cleanup freeing of nested state

Ensure that the VCPU free path goes through vmx_leave_nested and
thus nested_vmx_vmexit, so that the cancellation of the timer does
not have to be in free_nested.  In addition, because some paths through
nested_vmx_vmexit do not go through sync_vmcs12, the cancellation of
the timer is moved there.
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 81b01667
...@@ -211,7 +211,6 @@ static void free_nested(struct kvm_vcpu *vcpu) ...@@ -211,7 +211,6 @@ static void free_nested(struct kvm_vcpu *vcpu)
if (!vmx->nested.vmxon && !vmx->nested.smm.vmxon) if (!vmx->nested.vmxon && !vmx->nested.smm.vmxon)
return; return;
hrtimer_cancel(&vmx->nested.preemption_timer);
vmx->nested.vmxon = false; vmx->nested.vmxon = false;
vmx->nested.smm.vmxon = false; vmx->nested.smm.vmxon = false;
free_vpid(vmx->nested.vpid02); free_vpid(vmx->nested.vpid02);
...@@ -274,6 +273,7 @@ static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs) ...@@ -274,6 +273,7 @@ static void vmx_switch_vmcs(struct kvm_vcpu *vcpu, struct loaded_vmcs *vmcs)
void nested_vmx_free_vcpu(struct kvm_vcpu *vcpu) void nested_vmx_free_vcpu(struct kvm_vcpu *vcpu)
{ {
vcpu_load(vcpu); vcpu_load(vcpu);
vmx_leave_nested(vcpu);
vmx_switch_vmcs(vcpu, &to_vmx(vcpu)->vmcs01); vmx_switch_vmcs(vcpu, &to_vmx(vcpu)->vmcs01);
free_nested(vcpu); free_nested(vcpu);
vcpu_put(vcpu); vcpu_put(vcpu);
...@@ -3438,13 +3438,10 @@ static void sync_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12) ...@@ -3438,13 +3438,10 @@ static void sync_vmcs12(struct kvm_vcpu *vcpu, struct vmcs12 *vmcs12)
else else
vmcs12->guest_activity_state = GUEST_ACTIVITY_ACTIVE; vmcs12->guest_activity_state = GUEST_ACTIVITY_ACTIVE;
if (nested_cpu_has_preemption_timer(vmcs12)) { if (nested_cpu_has_preemption_timer(vmcs12) &&
if (vmcs12->vm_exit_controls & vmcs12->vm_exit_controls & VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)
VM_EXIT_SAVE_VMX_PREEMPTION_TIMER)
vmcs12->vmx_preemption_timer_value = vmcs12->vmx_preemption_timer_value =
vmx_get_preemption_timer_value(vcpu); vmx_get_preemption_timer_value(vcpu);
hrtimer_cancel(&to_vmx(vcpu)->nested.preemption_timer);
}
/* /*
* In some cases (usually, nested EPT), L2 is allowed to change its * In some cases (usually, nested EPT), L2 is allowed to change its
...@@ -3852,6 +3849,9 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, ...@@ -3852,6 +3849,9 @@ void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
leave_guest_mode(vcpu); leave_guest_mode(vcpu);
if (nested_cpu_has_preemption_timer(vmcs12))
hrtimer_cancel(&to_vmx(vcpu)->nested.preemption_timer);
if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING) if (vmcs12->cpu_based_vm_exec_control & CPU_BASED_USE_TSC_OFFSETING)
vcpu->arch.tsc_offset -= vmcs12->tsc_offset; vcpu->arch.tsc_offset -= vmcs12->tsc_offset;
......
...@@ -6546,7 +6546,6 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu) ...@@ -6546,7 +6546,6 @@ static void vmx_free_vcpu(struct kvm_vcpu *vcpu)
if (enable_pml) if (enable_pml)
vmx_destroy_pml_buffer(vmx); vmx_destroy_pml_buffer(vmx);
free_vpid(vmx->vpid); free_vpid(vmx->vpid);
leave_guest_mode(vcpu);
nested_vmx_free_vcpu(vcpu); nested_vmx_free_vcpu(vcpu);
free_loaded_vmcs(vmx->loaded_vmcs); free_loaded_vmcs(vmx->loaded_vmcs);
kfree(vmx->guest_msrs); kfree(vmx->guest_msrs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment