KVM: Close minor race in signal handling
We need to check for signals inside the critical section, otherwise a signal can be sent which we will not notice. Also move the check before entry, so that if the signal happens before the first entry, we exit immediately instead of waiting for something to happen to the guest. Signed-off-by: Avi Kivity <avi@qumranet.com>
This commit is contained in:
Родитель
3090dd7377
Коммит
7e66f350cf
|
@ -1398,11 +1398,19 @@ again:
|
|||
if (unlikely(r))
|
||||
return r;
|
||||
|
||||
clgi();
|
||||
|
||||
if (signal_pending(current)) {
|
||||
stgi();
|
||||
++vcpu->stat.signal_exits;
|
||||
post_kvm_run_save(svm, kvm_run);
|
||||
kvm_run->exit_reason = KVM_EXIT_INTR;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
if (!vcpu->mmio_read_completed)
|
||||
do_interrupt_requests(svm, kvm_run);
|
||||
|
||||
clgi();
|
||||
|
||||
vcpu->guest_mode = 1;
|
||||
if (vcpu->requests)
|
||||
if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
|
||||
|
@ -1582,13 +1590,6 @@ again:
|
|||
|
||||
r = handle_exit(svm, kvm_run);
|
||||
if (r > 0) {
|
||||
if (signal_pending(current)) {
|
||||
++vcpu->stat.signal_exits;
|
||||
post_kvm_run_save(svm, kvm_run);
|
||||
kvm_run->exit_reason = KVM_EXIT_INTR;
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
if (dm_request_for_irq_injection(svm, kvm_run)) {
|
||||
++vcpu->stat.request_irq_exits;
|
||||
post_kvm_run_save(svm, kvm_run);
|
||||
|
|
|
@ -2066,9 +2066,6 @@ again:
|
|||
|
||||
preempt_disable();
|
||||
|
||||
if (!vcpu->mmio_read_completed)
|
||||
do_interrupt_requests(vcpu, kvm_run);
|
||||
|
||||
vmx_save_host_state(vmx);
|
||||
kvm_load_guest_fpu(vcpu);
|
||||
|
||||
|
@ -2079,6 +2076,18 @@ again:
|
|||
|
||||
local_irq_disable();
|
||||
|
||||
if (signal_pending(current)) {
|
||||
local_irq_enable();
|
||||
preempt_enable();
|
||||
r = -EINTR;
|
||||
kvm_run->exit_reason = KVM_EXIT_INTR;
|
||||
++vcpu->stat.signal_exits;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!vcpu->mmio_read_completed)
|
||||
do_interrupt_requests(vcpu, kvm_run);
|
||||
|
||||
vcpu->guest_mode = 1;
|
||||
if (vcpu->requests)
|
||||
if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
|
||||
|
@ -2227,14 +2236,6 @@ again:
|
|||
|
||||
r = kvm_handle_exit(kvm_run, vcpu);
|
||||
if (r > 0) {
|
||||
/* Give scheduler a change to reschedule. */
|
||||
if (signal_pending(current)) {
|
||||
r = -EINTR;
|
||||
kvm_run->exit_reason = KVM_EXIT_INTR;
|
||||
++vcpu->stat.signal_exits;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dm_request_for_irq_injection(vcpu, kvm_run)) {
|
||||
r = -EINTR;
|
||||
kvm_run->exit_reason = KVM_EXIT_INTR;
|
||||
|
|
Загрузка…
Ссылка в новой задаче