On 21/05/2017 05:32, Wanpeng Li wrote: > CPU0 CPU1 > > vmx_cancel_hv_timer > vCPU0's vmx->hv_deadline_tsc = -1 > > preempt occur > > clear preemption timer field in CPU1's active vmcs > vCPU0's apic_timer.hv_timer_in_use = false > vmx_vcpu_run(vCPU0) > vmx_arm_hv_timer > if (vmx->hv_deadline_tsc == -1) > nothing change > > handle_preemption_timer(vCPU0) > kvm_lapic_expired_hv_timer > WARN_ON(!apic->lapic_timer.hv_timer_in_use); I think it's more like this, what do you think? CPU0 CPU1 preemption timer vmexit handle_preemption_timer(vCPU0) kvm_lapic_expired_hv_timer vmx_cancel_hv_timer vmx->hv_deadline_tsc = -1 vmcs_clear_bits /* hv_timer_in_use still true */ sched_out sched_in kvm_arch_vcpu_load vmx_set_hv_timer write vmx->hv_deadline_tsc vmcs_set_bits /* back in kvm_lapic_expired_hv_timer */ hv_timer_in_use = false ... vmx_vcpu_run vmx_arm_hv_run write preemption timer deadline spurious preemption timer vmexit handle_preemption_timer(vCPU0) kvm_lapic_expired_hv_timer WARN_ON(!apic->lapic_timer.hv_timer_in_use); Thanks, Paolo