aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/x86.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2008-12-11 10:54:54 -0500
committerAvi Kivity <avi@redhat.com>2008-12-31 09:55:47 -0500
commit4531220b71f0399e71cda0c4cf749e7281a7416a (patch)
tree2d0b71b97a15bdd6ede42d05b7b9b791c3891eb3 /arch/x86/kvm/x86.c
parent264ff01d55b456932cef03082448b41d2edeb6a1 (diff)
KVM: x86: Rework user space NMI injection as KVM_CAP_USER_NMI
There is no point in doing the ready_for_nmi_injection/ request_nmi_window dance with user space. First, we don't do this for in-kernel irqchip anyway, while the code path is the same as for user space irqchip mode. And second, there is nothing to loose if a pending NMI is overwritten by another one (in contrast to IRQs where we have to save the number). Actually, there is even the risk of raising spurious NMIs this way because the reason for the held-back NMI might already be handled while processing the first one. Therefore this patch creates a simplified user space NMI injection interface, exporting it under KVM_CAP_USER_NMI and dropping the old KVM_CAP_NMI capability. And this time we also take care to provide the interface only on archs supporting NMIs via KVM (right now only x86). Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/x86.c')
-rw-r--r--arch/x86/kvm/x86.c28
1 files changed, 2 insertions, 26 deletions
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 10302d3bd415..0e6aa8141dcd 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2887,37 +2887,18 @@ static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu,
2887 (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF)); 2887 (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF));
2888} 2888}
2889 2889
2890/*
2891 * Check if userspace requested a NMI window, and that the NMI window
2892 * is open.
2893 *
2894 * No need to exit to userspace if we already have a NMI queued.
2895 */
2896static int dm_request_for_nmi_injection(struct kvm_vcpu *vcpu,
2897 struct kvm_run *kvm_run)
2898{
2899 return (!vcpu->arch.nmi_pending &&
2900 kvm_run->request_nmi_window &&
2901 vcpu->arch.nmi_window_open);
2902}
2903
2904static void post_kvm_run_save(struct kvm_vcpu *vcpu, 2890static void post_kvm_run_save(struct kvm_vcpu *vcpu,
2905 struct kvm_run *kvm_run) 2891 struct kvm_run *kvm_run)
2906{ 2892{
2907 kvm_run->if_flag = (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF) != 0; 2893 kvm_run->if_flag = (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF) != 0;
2908 kvm_run->cr8 = kvm_get_cr8(vcpu); 2894 kvm_run->cr8 = kvm_get_cr8(vcpu);
2909 kvm_run->apic_base = kvm_get_apic_base(vcpu); 2895 kvm_run->apic_base = kvm_get_apic_base(vcpu);
2910 if (irqchip_in_kernel(vcpu->kvm)) { 2896 if (irqchip_in_kernel(vcpu->kvm))
2911 kvm_run->ready_for_interrupt_injection = 1; 2897 kvm_run->ready_for_interrupt_injection = 1;
2912 kvm_run->ready_for_nmi_injection = 1; 2898 else
2913 } else {
2914 kvm_run->ready_for_interrupt_injection = 2899 kvm_run->ready_for_interrupt_injection =
2915 (vcpu->arch.interrupt_window_open && 2900 (vcpu->arch.interrupt_window_open &&
2916 vcpu->arch.irq_summary == 0); 2901 vcpu->arch.irq_summary == 0);
2917 kvm_run->ready_for_nmi_injection =
2918 (vcpu->arch.nmi_window_open &&
2919 vcpu->arch.nmi_pending == 0);
2920 }
2921} 2902}
2922 2903
2923static void vapic_enter(struct kvm_vcpu *vcpu) 2904static void vapic_enter(struct kvm_vcpu *vcpu)
@@ -3093,11 +3074,6 @@ static int __vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
3093 } 3074 }
3094 3075
3095 if (r > 0) { 3076 if (r > 0) {
3096 if (dm_request_for_nmi_injection(vcpu, kvm_run)) {
3097 r = -EINTR;
3098 kvm_run->exit_reason = KVM_EXIT_NMI;
3099 ++vcpu->stat.request_nmi_exits;
3100 }
3101 if (dm_request_for_irq_injection(vcpu, kvm_run)) { 3077 if (dm_request_for_irq_injection(vcpu, kvm_run)) {
3102 r = -EINTR; 3078 r = -EINTR;
3103 kvm_run->exit_reason = KVM_EXIT_INTR; 3079 kvm_run->exit_reason = KVM_EXIT_INTR;