Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d4acf7e7 authored by Marcelo Tosatti's avatar Marcelo Tosatti Committed by Avi Kivity
Browse files

KVM: Fix race between timer migration and vcpu migration



A guest vcpu instance can be scheduled to a different physical CPU
between the test for KVM_REQ_MIGRATE_TIMER and local_irq_disable().

If that happens, the timer will only be migrated to the current pCPU on
the next exit, meaning that guest LAPIC timer event can be delayed until
a host interrupt is triggered.

Fix it by cancelling guest entry if any vcpu request is pending.  This
has the side effect of nicely consolidating vcpu->requests checks.

Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 62786b9e
Loading
Loading
Loading
Loading
+3 −12
Original line number Diff line number Diff line
@@ -2759,6 +2759,8 @@ again:
	if (vcpu->requests) {
		if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests))
			__kvm_migrate_timers(vcpu);
		if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
			kvm_x86_ops->tlb_flush(vcpu);
		if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS,
				       &vcpu->requests)) {
			kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS;
@@ -2781,15 +2783,7 @@ again:

	local_irq_disable();

	if (need_resched()) {
		local_irq_enable();
		preempt_enable();
		r = 1;
		goto out;
	}

	if (vcpu->requests)
		if (test_bit(KVM_REQ_MMU_RELOAD, &vcpu->requests)) {
	if (vcpu->requests || need_resched()) {
		local_irq_enable();
		preempt_enable();
		r = 1;
@@ -2825,9 +2819,6 @@ again:

	kvm_guest_enter();

	if (vcpu->requests)
		if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests))
			kvm_x86_ops->tlb_flush(vcpu);

	KVMTRACE_0D(VMENTRY, vcpu, entryexit);
	kvm_x86_ops->run(vcpu, kvm_run);