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

Commit e52b2af5 authored by Carsten Otte's avatar Carsten Otte Committed by Avi Kivity
Browse files

KVM: s390: Fix race condition in kvm_s390_handle_wait



The call to add_timer was issued before local_int.lock was taken and before
timer_due was set to 0. If the timer expires before the lock is being taken,
the timer function will set timer_due to 1 and exit before the vcpu falls
asleep. Depending on other external events, the vcpu might sleep forever.
This fix pulls setting timer_due to the beginning of the function before
add_timer, which ensures correct behavior.

Signed-off-by: default avatarCarsten Otte <cotte@de.ibm.com>
Signed-off-by: default avatarAvi Kivity <avi@qumranet.com>
parent 1f0d0f09
Loading
Loading
Loading
Loading
+5 −2
Original line number Original line Diff line number Diff line
@@ -339,6 +339,11 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
	if (kvm_cpu_has_interrupt(vcpu))
	if (kvm_cpu_has_interrupt(vcpu))
		return 0;
		return 0;


	__set_cpu_idle(vcpu);
	spin_lock_bh(&vcpu->arch.local_int.lock);
	vcpu->arch.local_int.timer_due = 0;
	spin_unlock_bh(&vcpu->arch.local_int.lock);

	if (psw_interrupts_disabled(vcpu)) {
	if (psw_interrupts_disabled(vcpu)) {
		VCPU_EVENT(vcpu, 3, "%s", "disabled wait");
		VCPU_EVENT(vcpu, 3, "%s", "disabled wait");
		__unset_cpu_idle(vcpu);
		__unset_cpu_idle(vcpu);
@@ -366,8 +371,6 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
no_timer:
no_timer:
	spin_lock_bh(&vcpu->arch.local_int.float_int->lock);
	spin_lock_bh(&vcpu->arch.local_int.float_int->lock);
	spin_lock_bh(&vcpu->arch.local_int.lock);
	spin_lock_bh(&vcpu->arch.local_int.lock);
	__set_cpu_idle(vcpu);
	vcpu->arch.local_int.timer_due = 0;
	add_wait_queue(&vcpu->arch.local_int.wq, &wait);
	add_wait_queue(&vcpu->arch.local_int.wq, &wait);
	while (list_empty(&vcpu->arch.local_int.list) &&
	while (list_empty(&vcpu->arch.local_int.list) &&
		list_empty(&vcpu->arch.local_int.float_int->list) &&
		list_empty(&vcpu->arch.local_int.float_int->list) &&