mirror of
https://github.com/torvalds/linux.git
synced 2024-12-01 08:31:37 +00:00
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: Carsten Otte <cotte@de.ibm.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
parent
1f0d0f094d
commit
e52b2af541
@ -339,6 +339,11 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
|
||||
if (kvm_cpu_has_interrupt(vcpu))
|
||||
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)) {
|
||||
VCPU_EVENT(vcpu, 3, "%s", "disabled wait");
|
||||
__unset_cpu_idle(vcpu);
|
||||
@ -366,8 +371,6 @@ int kvm_s390_handle_wait(struct kvm_vcpu *vcpu)
|
||||
no_timer:
|
||||
spin_lock_bh(&vcpu->arch.local_int.float_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);
|
||||
while (list_empty(&vcpu->arch.local_int.list) &&
|
||||
list_empty(&vcpu->arch.local_int.float_int->list) &&
|
||||
|
Loading…
Reference in New Issue
Block a user