From 7e66f350cfc853043bfa71b281581dd6f92fa347 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Wed, 15 Aug 2007 15:23:34 +0300 Subject: [PATCH] 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 --- drivers/kvm/svm.c | 19 ++++++++++--------- 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 e3c6d891326b..cc674bfd31d9 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c @@ -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)) @@ -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); 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 @@ 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); @@ -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)) @@ -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; -- GitLab