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

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

KVM: close timer injection race window in __vcpu_run



If a timer fires after kvm_inject_pending_timer_irqs() but before
local_irq_disable() the code will enter guest mode and only inject such
timer interrupt the next time an unrelated event causes an exit.

It would be simpler if the timer->pending irq conversion could be done
with IRQ's disabled, so that the above problem cannot happen.

For now introduce a new vcpu requests bit to cancel guest entry.

Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent d4acf7e7
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -200,10 +200,13 @@ int __pit_timer_fn(struct kvm_kpit_state *ps)

	atomic_inc(&pt->pending);
	smp_mb__after_atomic_inc();
	if (vcpu0 && waitqueue_active(&vcpu0->wq)) {
	if (vcpu0) {
		set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
		if (waitqueue_active(&vcpu0->wq)) {
			vcpu0->arch.mp_state = KVM_MP_STATE_RUNNABLE;
			wake_up_interruptible(&vcpu0->wq);
		}
	}

	pt->timer.expires = ktime_add_ns(pt->timer.expires, pt->period);
	pt->scheduled = ktime_to_ns(pt->timer.expires);
+1 −0
Original line number Diff line number Diff line
@@ -940,6 +940,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
	wait_queue_head_t *q = &apic->vcpu->wq;

	atomic_inc(&apic->timer.pending);
	set_bit(KVM_REQ_PENDING_TIMER, &apic->vcpu->requests);
	if (waitqueue_active(q)) {
		apic->vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE;
		wake_up_interruptible(q);
+1 −0
Original line number Diff line number Diff line
@@ -2774,6 +2774,7 @@ again:
		}
	}

	clear_bit(KVM_REQ_PENDING_TIMER, &vcpu->requests);
	kvm_inject_pending_timer_irqs(vcpu);

	preempt_disable();
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
#define KVM_REQ_REPORT_TPR_ACCESS  2
#define KVM_REQ_MMU_RELOAD         3
#define KVM_REQ_TRIPLE_FAULT       4
#define KVM_REQ_PENDING_TIMER      5

struct kvm_vcpu;
extern struct kmem_cache *kvm_vcpu_cache;