diff options
author | Avi Kivity <avi@qumranet.com> | 2007-08-15 15:23:34 +0300 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2007-10-13 10:18:23 +0200 |
commit | 7e66f350cfc853043bfa71b281581dd6f92fa347 (patch) | |
tree | bbf821c3fd4578cfacb07deaa59f18da5eaa4411 /drivers/kvm | |
parent | 3090dd7377c7eb5cbe229e2a538f9dc7e5b06814 (diff) | |
download | op-kernel-dev-7e66f350cfc853043bfa71b281581dd6f92fa347.zip op-kernel-dev-7e66f350cfc853043bfa71b281581dd6f92fa347.tar.gz |
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>
Diffstat (limited to 'drivers/kvm')
-rw-r--r-- | drivers/kvm/svm.c | 19 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 23 |
2 files changed, 22 insertions, 20 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index e3c6d89..cc674bf 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -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); diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 906d4fa..a9b4cb5 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -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; |