summaryrefslogtreecommitdiffstats
path: root/drivers/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-08-15 15:23:34 +0300
committerAvi Kivity <avi@qumranet.com>2007-10-13 10:18:23 +0200
commit7e66f350cfc853043bfa71b281581dd6f92fa347 (patch)
treebbf821c3fd4578cfacb07deaa59f18da5eaa4411 /drivers/kvm
parent3090dd7377c7eb5cbe229e2a538f9dc7e5b06814 (diff)
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.c19
-rw-r--r--drivers/kvm/vmx.c23
2 files changed, 22 insertions, 20 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index e3c6d891326..cc674bfd31d 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 906d4fa13d1..a9b4cb51dec 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;