aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-09-20 06:43:14 -0400
committerAvi Kivity <avi@redhat.com>2011-09-25 12:52:59 -0400
commit7460fb4a340033107530df19e7e125bd0969bfb2 (patch)
tree02f2aedd48af0a2e316b28d6a5b21a7a96442ac6 /arch
parent1cd196ea42c526549ded4fd29809c3fdaa4a7f41 (diff)
KVM: Fix simultaneous NMIs
If simultaneous NMIs happen, we're supposed to queue the second and next (collapsing them), but currently we sometimes collapse the second into the first. Fix by using a counter for pending NMIs instead of a bool; since the counter limit depends on whether the processor is currently in an NMI handler, which can only be checked in vcpu context (via the NMI mask), we add a new KVM_REQ_NMI to request recalculation of the counter. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/include/asm/kvm_host.h5
-rw-r--r--arch/x86/kvm/x86.c48
2 files changed, 34 insertions, 19 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index 6ab4241c27cb..ab62711ccb78 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -413,8 +413,9 @@ struct kvm_vcpu_arch {
413 u32 tsc_catchup_mult; 413 u32 tsc_catchup_mult;
414 s8 tsc_catchup_shift; 414 s8 tsc_catchup_shift;
415 415
416 bool nmi_pending; 416 atomic_t nmi_queued; /* unprocessed asynchronous NMIs */
417 bool nmi_injected; 417 unsigned nmi_pending; /* NMI queued after currently running handler */
418 bool nmi_injected; /* Trying to inject an NMI this entry */
418 419
419 struct mtrr_state_type mtrr_state; 420 struct mtrr_state_type mtrr_state;
420 u32 pat; 421 u32 pat;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 6b37f18a1663..d51e40733fcb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -83,6 +83,7 @@ static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
83static void update_cr8_intercept(struct kvm_vcpu *vcpu); 83static void update_cr8_intercept(struct kvm_vcpu *vcpu);
84static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid, 84static int kvm_dev_ioctl_get_supported_cpuid(struct kvm_cpuid2 *cpuid,
85 struct kvm_cpuid_entry2 __user *entries); 85 struct kvm_cpuid_entry2 __user *entries);
86static void process_nmi(struct kvm_vcpu *vcpu);
86 87
87struct kvm_x86_ops *kvm_x86_ops; 88struct kvm_x86_ops *kvm_x86_ops;
88EXPORT_SYMBOL_GPL(kvm_x86_ops); 89EXPORT_SYMBOL_GPL(kvm_x86_ops);
@@ -359,8 +360,8 @@ void kvm_propagate_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault)
359 360
360void kvm_inject_nmi(struct kvm_vcpu *vcpu) 361void kvm_inject_nmi(struct kvm_vcpu *vcpu)
361{ 362{
362 kvm_make_request(KVM_REQ_EVENT, vcpu); 363 atomic_inc(&vcpu->arch.nmi_queued);
363 vcpu->arch.nmi_pending = 1; 364 kvm_make_request(KVM_REQ_NMI, vcpu);
364} 365}
365EXPORT_SYMBOL_GPL(kvm_inject_nmi); 366EXPORT_SYMBOL_GPL(kvm_inject_nmi);
366 367
@@ -2827,6 +2828,7 @@ static int kvm_vcpu_ioctl_x86_set_mce(struct kvm_vcpu *vcpu,
2827static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, 2828static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
2828 struct kvm_vcpu_events *events) 2829 struct kvm_vcpu_events *events)
2829{ 2830{
2831 process_nmi(vcpu);
2830 events->exception.injected = 2832 events->exception.injected =
2831 vcpu->arch.exception.pending && 2833 vcpu->arch.exception.pending &&
2832 !kvm_exception_is_soft(vcpu->arch.exception.nr); 2834 !kvm_exception_is_soft(vcpu->arch.exception.nr);
@@ -2844,7 +2846,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu,
2844 KVM_X86_SHADOW_INT_MOV_SS | KVM_X86_SHADOW_INT_STI); 2846 KVM_X86_SHADOW_INT_MOV_SS | KVM_X86_SHADOW_INT_STI);
2845 2847
2846 events->nmi.injected = vcpu->arch.nmi_injected; 2848 events->nmi.injected = vcpu->arch.nmi_injected;
2847 events->nmi.pending = vcpu->arch.nmi_pending; 2849 events->nmi.pending = vcpu->arch.nmi_pending != 0;
2848 events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu); 2850 events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu);
2849 events->nmi.pad = 0; 2851 events->nmi.pad = 0;
2850 2852
@@ -2864,6 +2866,7 @@ static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu,
2864 | KVM_VCPUEVENT_VALID_SHADOW)) 2866 | KVM_VCPUEVENT_VALID_SHADOW))
2865 return -EINVAL; 2867 return -EINVAL;
2866 2868
2869 process_nmi(vcpu);
2867 vcpu->arch.exception.pending = events->exception.injected; 2870 vcpu->arch.exception.pending = events->exception.injected;
2868 vcpu->arch.exception.nr = events->exception.nr; 2871 vcpu->arch.exception.nr = events->exception.nr;
2869 vcpu->arch.exception.has_error_code = events->exception.has_error_code; 2872 vcpu->arch.exception.has_error_code = events->exception.has_error_code;
@@ -4763,7 +4766,7 @@ int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip)
4763 kvm_set_rflags(vcpu, ctxt->eflags); 4766 kvm_set_rflags(vcpu, ctxt->eflags);
4764 4767
4765 if (irq == NMI_VECTOR) 4768 if (irq == NMI_VECTOR)
4766 vcpu->arch.nmi_pending = false; 4769 vcpu->arch.nmi_pending = 0;
4767 else 4770 else
4768 vcpu->arch.interrupt.pending = false; 4771 vcpu->arch.interrupt.pending = false;
4769 4772
@@ -5572,7 +5575,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu)
5572 /* try to inject new event if pending */ 5575 /* try to inject new event if pending */
5573 if (vcpu->arch.nmi_pending) { 5576 if (vcpu->arch.nmi_pending) {
5574 if (kvm_x86_ops->nmi_allowed(vcpu)) { 5577 if (kvm_x86_ops->nmi_allowed(vcpu)) {
5575 vcpu->arch.nmi_pending = false; 5578 --vcpu->arch.nmi_pending;
5576 vcpu->arch.nmi_injected = true; 5579 vcpu->arch.nmi_injected = true;
5577 kvm_x86_ops->set_nmi(vcpu); 5580 kvm_x86_ops->set_nmi(vcpu);
5578 } 5581 }
@@ -5604,10 +5607,26 @@ static void kvm_put_guest_xcr0(struct kvm_vcpu *vcpu)
5604 } 5607 }
5605} 5608}
5606 5609
5610static void process_nmi(struct kvm_vcpu *vcpu)
5611{
5612 unsigned limit = 2;
5613
5614 /*
5615 * x86 is limited to one NMI running, and one NMI pending after it.
5616 * If an NMI is already in progress, limit further NMIs to just one.
5617 * Otherwise, allow two (and we'll inject the first one immediately).
5618 */
5619 if (kvm_x86_ops->get_nmi_mask(vcpu) || vcpu->arch.nmi_injected)
5620 limit = 1;
5621
5622 vcpu->arch.nmi_pending += atomic_xchg(&vcpu->arch.nmi_queued, 0);
5623 vcpu->arch.nmi_pending = min(vcpu->arch.nmi_pending, limit);
5624 kvm_make_request(KVM_REQ_EVENT, vcpu);
5625}
5626
5607static int vcpu_enter_guest(struct kvm_vcpu *vcpu) 5627static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5608{ 5628{
5609 int r; 5629 int r;
5610 bool nmi_pending;
5611 bool req_int_win = !irqchip_in_kernel(vcpu->kvm) && 5630 bool req_int_win = !irqchip_in_kernel(vcpu->kvm) &&
5612 vcpu->run->request_interrupt_window; 5631 vcpu->run->request_interrupt_window;
5613 5632
@@ -5647,6 +5666,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5647 } 5666 }
5648 if (kvm_check_request(KVM_REQ_STEAL_UPDATE, vcpu)) 5667 if (kvm_check_request(KVM_REQ_STEAL_UPDATE, vcpu))
5649 record_steal_time(vcpu); 5668 record_steal_time(vcpu);
5669 if (kvm_check_request(KVM_REQ_NMI, vcpu))
5670 process_nmi(vcpu);
5650 5671
5651 } 5672 }
5652 5673
@@ -5654,19 +5675,11 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
5654 if (unlikely(r)) 5675 if (unlikely(r))
5655 goto out; 5676 goto out;
5656 5677
5657 /*
5658 * An NMI can be injected between local nmi_pending read and
5659 * vcpu->arch.nmi_pending read inside inject_pending_event().
5660 * But in that case, KVM_REQ_EVENT will be set, which makes
5661 * the race described above benign.
5662 */
5663 nmi_pending = ACCESS_ONCE(vcpu->arch.nmi_pending);
5664
5665 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) { 5678 if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
5666 inject_pending_event(vcpu); 5679 inject_pending_event(vcpu);
5667 5680
5668 /* enable NMI/IRQ window open exits if needed */ 5681 /* enable NMI/IRQ window open exits if needed */
5669 if (nmi_pending) 5682 if (vcpu->arch.nmi_pending)
5670 kvm_x86_ops->enable_nmi_window(vcpu); 5683 kvm_x86_ops->enable_nmi_window(vcpu);
5671 else if (kvm_cpu_has_interrupt(vcpu) || req_int_win) 5684 else if (kvm_cpu_has_interrupt(vcpu) || req_int_win)
5672 kvm_x86_ops->enable_irq_window(vcpu); 5685 kvm_x86_ops->enable_irq_window(vcpu);
@@ -6374,7 +6387,8 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu)
6374 6387
6375int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu) 6388int kvm_arch_vcpu_reset(struct kvm_vcpu *vcpu)
6376{ 6389{
6377 vcpu->arch.nmi_pending = false; 6390 atomic_set(&vcpu->arch.nmi_queued, 0);
6391 vcpu->arch.nmi_pending = 0;
6378 vcpu->arch.nmi_injected = false; 6392 vcpu->arch.nmi_injected = false;
6379 6393
6380 vcpu->arch.switch_db_regs = 0; 6394 vcpu->arch.switch_db_regs = 0;
@@ -6649,7 +6663,7 @@ int kvm_arch_vcpu_runnable(struct kvm_vcpu *vcpu)
6649 !vcpu->arch.apf.halted) 6663 !vcpu->arch.apf.halted)
6650 || !list_empty_careful(&vcpu->async_pf.done) 6664 || !list_empty_careful(&vcpu->async_pf.done)
6651 || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED 6665 || vcpu->arch.mp_state == KVM_MP_STATE_SIPI_RECEIVED
6652 || vcpu->arch.nmi_pending || 6666 || atomic_read(&vcpu->arch.nmi_queued) ||
6653 (kvm_arch_interrupt_allowed(vcpu) && 6667 (kvm_arch_interrupt_allowed(vcpu) &&
6654 kvm_cpu_has_interrupt(vcpu)); 6668 kvm_cpu_has_interrupt(vcpu));
6655} 6669}