Skip to content

Commit

Permalink
KVM: Close minor race in signal handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Avi Kivity committed Oct 13, 2007
1 parent 3090dd7 commit 7e66f35
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 20 deletions.
19 changes: 10 additions & 9 deletions drivers/kvm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,11 +1398,19 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
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))
Expand Down Expand Up @@ -1582,13 +1590,6 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)

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);
Expand Down
23 changes: 12 additions & 11 deletions drivers/kvm/vmx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2066,9 +2066,6 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)

preempt_disable();

if (!vcpu->mmio_read_completed)
do_interrupt_requests(vcpu, kvm_run);

vmx_save_host_state(vmx);
kvm_load_guest_fpu(vcpu);

Expand All @@ -2079,6 +2076,18 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)

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))
Expand Down Expand Up @@ -2227,14 +2236,6 @@ static int vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)

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;
Expand Down

0 comments on commit 7e66f35

Please sign in to comment.