aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2007-08-15 08:23:34 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:23 -0400
commit7e66f350cfc853043bfa71b281581dd6f92fa347 (patch)
treebbf821c3fd4578cfacb07deaa59f18da5eaa4411 /drivers
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')
-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 e3c6d891326b..cc674bfd31d9 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1398,11 +1398,19 @@ again:
1398 if (unlikely(r)) 1398 if (unlikely(r))
1399 return r; 1399 return r;
1400 1400
1401 clgi();
1402
1403 if (signal_pending(current)) {
1404 stgi();
1405 ++vcpu->stat.signal_exits;
1406 post_kvm_run_save(svm, kvm_run);
1407 kvm_run->exit_reason = KVM_EXIT_INTR;
1408 return -EINTR;
1409 }
1410
1401 if (!vcpu->mmio_read_completed) 1411 if (!vcpu->mmio_read_completed)
1402 do_interrupt_requests(svm, kvm_run); 1412 do_interrupt_requests(svm, kvm_run);
1403 1413
1404 clgi();
1405
1406 vcpu->guest_mode = 1; 1414 vcpu->guest_mode = 1;
1407 if (vcpu->requests) 1415 if (vcpu->requests)
1408 if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests)) 1416 if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
@@ -1582,13 +1590,6 @@ again:
1582 1590
1583 r = handle_exit(svm, kvm_run); 1591 r = handle_exit(svm, kvm_run);
1584 if (r > 0) { 1592 if (r > 0) {
1585 if (signal_pending(current)) {
1586 ++vcpu->stat.signal_exits;
1587 post_kvm_run_save(svm, kvm_run);
1588 kvm_run->exit_reason = KVM_EXIT_INTR;
1589 return -EINTR;
1590 }
1591
1592 if (dm_request_for_irq_injection(svm, kvm_run)) { 1593 if (dm_request_for_irq_injection(svm, kvm_run)) {
1593 ++vcpu->stat.request_irq_exits; 1594 ++vcpu->stat.request_irq_exits;
1594 post_kvm_run_save(svm, kvm_run); 1595 post_kvm_run_save(svm, kvm_run);
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 906d4fa13d10..a9b4cb51dec8 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -2066,9 +2066,6 @@ again:
2066 2066
2067 preempt_disable(); 2067 preempt_disable();
2068 2068
2069 if (!vcpu->mmio_read_completed)
2070 do_interrupt_requests(vcpu, kvm_run);
2071
2072 vmx_save_host_state(vmx); 2069 vmx_save_host_state(vmx);
2073 kvm_load_guest_fpu(vcpu); 2070 kvm_load_guest_fpu(vcpu);
2074 2071
@@ -2079,6 +2076,18 @@ again:
2079 2076
2080 local_irq_disable(); 2077 local_irq_disable();
2081 2078
2079 if (signal_pending(current)) {
2080 local_irq_enable();
2081 preempt_enable();
2082 r = -EINTR;
2083 kvm_run->exit_reason = KVM_EXIT_INTR;
2084 ++vcpu->stat.signal_exits;
2085 goto out;
2086 }
2087
2088 if (!vcpu->mmio_read_completed)
2089 do_interrupt_requests(vcpu, kvm_run);
2090
2082 vcpu->guest_mode = 1; 2091 vcpu->guest_mode = 1;
2083 if (vcpu->requests) 2092 if (vcpu->requests)
2084 if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests)) 2093 if (test_and_clear_bit(KVM_TLB_FLUSH, &vcpu->requests))
@@ -2227,14 +2236,6 @@ again:
2227 2236
2228 r = kvm_handle_exit(kvm_run, vcpu); 2237 r = kvm_handle_exit(kvm_run, vcpu);
2229 if (r > 0) { 2238 if (r > 0) {
2230 /* Give scheduler a change to reschedule. */
2231 if (signal_pending(current)) {
2232 r = -EINTR;
2233 kvm_run->exit_reason = KVM_EXIT_INTR;
2234 ++vcpu->stat.signal_exits;
2235 goto out;
2236 }
2237
2238 if (dm_request_for_irq_injection(vcpu, kvm_run)) { 2239 if (dm_request_for_irq_injection(vcpu, kvm_run)) {
2239 r = -EINTR; 2240 r = -EINTR;
2240 kvm_run->exit_reason = KVM_EXIT_INTR; 2241 kvm_run->exit_reason = KVM_EXIT_INTR;