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

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

KVM: only abort guest entry if timer count goes from 0->1



Only abort guest entry if the timer count went from 0->1, since for 1->2
or larger the bit will either be set already or a timer irq will have
been injected.

Using atomic_inc_and_test() for it also introduces an SMP barrier
to the LAPIC version (thought it was unecessary because of timer
migration, but guest can be scheduled to a different pCPU between exit
and kvm_vcpu_block(), so there is the possibility for a race).

Noticed by Avi.

Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 7f39f8ac
Loading
Loading
Loading
Loading
+4 −7
Original line number Diff line number Diff line
@@ -198,15 +198,12 @@ static int __pit_timer_fn(struct kvm_kpit_state *ps)
	struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0];
	struct kvm_kpit_timer *pt = &ps->pit_timer;

	atomic_inc(&pt->pending);
	smp_mb__after_atomic_inc();
	if (vcpu0) {
	if (!atomic_inc_and_test(&pt->pending))
		set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests);
		if (waitqueue_active(&vcpu0->wq)) {
	if (vcpu0 && 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);
+2 −2
Original line number Diff line number Diff line
@@ -945,7 +945,7 @@ static int __apic_timer_fn(struct kvm_lapic *apic)
	int result = 0;
	wait_queue_head_t *q = &apic->vcpu->wq;

	atomic_inc(&apic->timer.pending);
	if(!atomic_inc_and_test(&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;