aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorGleb Natapov <gleb@redhat.com>2009-04-21 10:44:56 -0400
committerAvi Kivity <avi@redhat.com>2009-06-10 04:48:45 -0400
commit8061823a25218174f30c3dd943989e1d72f7d06e (patch)
treeee94e6ac86efe3c0bdeb933b8538ae06e99f6fe3 /arch
parent3438253926822a6bf8487b4f7d82f26a2c0b2388 (diff)
KVM: Make kvm_cpu_(has|get)_interrupt() work for userspace irqchip too
At the vector level, kernel and userspace irqchip are fairly similar. Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kvm/irq.c7
-rw-r--r--arch/x86/kvm/svm.c11
-rw-r--r--arch/x86/kvm/vmx.c18
-rw-r--r--arch/x86/kvm/x86.c4
4 files changed, 25 insertions, 15 deletions
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c
index cf17ed52f6fb..11c2757b808f 100644
--- a/arch/x86/kvm/irq.c
+++ b/arch/x86/kvm/irq.c
@@ -24,6 +24,7 @@
24 24
25#include "irq.h" 25#include "irq.h"
26#include "i8254.h" 26#include "i8254.h"
27#include "x86.h"
27 28
28/* 29/*
29 * check if there are pending timer events 30 * check if there are pending timer events
@@ -48,6 +49,9 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
48{ 49{
49 struct kvm_pic *s; 50 struct kvm_pic *s;
50 51
52 if (!irqchip_in_kernel(v->kvm))
53 return v->arch.irq_summary;
54
51 if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */ 55 if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
52 if (kvm_apic_accept_pic_intr(v)) { 56 if (kvm_apic_accept_pic_intr(v)) {
53 s = pic_irqchip(v->kvm); /* PIC */ 57 s = pic_irqchip(v->kvm); /* PIC */
@@ -67,6 +71,9 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
67 struct kvm_pic *s; 71 struct kvm_pic *s;
68 int vector; 72 int vector;
69 73
74 if (!irqchip_in_kernel(v->kvm))
75 return kvm_pop_irq(v);
76
70 vector = kvm_get_apic_interrupt(v); /* APIC */ 77 vector = kvm_get_apic_interrupt(v); /* APIC */
71 if (vector == -1) { 78 if (vector == -1) {
72 if (kvm_apic_accept_pic_intr(v)) { 79 if (kvm_apic_accept_pic_intr(v)) {
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 8fc6eea148e7..6eef6d22e87e 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2091,8 +2091,9 @@ static int interrupt_window_interception(struct vcpu_svm *svm,
2091 * If the user space waits to inject interrupts, exit as soon as 2091 * If the user space waits to inject interrupts, exit as soon as
2092 * possible 2092 * possible
2093 */ 2093 */
2094 if (kvm_run->request_interrupt_window && 2094 if (!irqchip_in_kernel(svm->vcpu.kvm) &&
2095 !svm->vcpu.arch.irq_summary) { 2095 kvm_run->request_interrupt_window &&
2096 !kvm_cpu_has_interrupt(&svm->vcpu)) {
2096 ++svm->vcpu.stat.irq_window_exits; 2097 ++svm->vcpu.stat.irq_window_exits;
2097 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; 2098 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
2098 return 0; 2099 return 0;
@@ -2373,7 +2374,8 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
2373 (svm->vmcb->save.rflags & X86_EFLAGS_IF) && 2374 (svm->vmcb->save.rflags & X86_EFLAGS_IF) &&
2374 (svm->vcpu.arch.hflags & HF_GIF_MASK)); 2375 (svm->vcpu.arch.hflags & HF_GIF_MASK));
2375 2376
2376 if (svm->vcpu.arch.interrupt_window_open && svm->vcpu.arch.irq_summary) 2377 if (svm->vcpu.arch.interrupt_window_open &&
2378 kvm_cpu_has_interrupt(&svm->vcpu))
2377 /* 2379 /*
2378 * If interrupts enabled, and not blocked by sti or mov ss. Good. 2380 * If interrupts enabled, and not blocked by sti or mov ss. Good.
2379 */ 2381 */
@@ -2383,7 +2385,8 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
2383 * Interrupts blocked. Wait for unblock. 2385 * Interrupts blocked. Wait for unblock.
2384 */ 2386 */
2385 if (!svm->vcpu.arch.interrupt_window_open && 2387 if (!svm->vcpu.arch.interrupt_window_open &&
2386 (svm->vcpu.arch.irq_summary || kvm_run->request_interrupt_window)) 2388 (kvm_cpu_has_interrupt(&svm->vcpu) ||
2389 kvm_run->request_interrupt_window))
2387 svm_set_vintr(svm); 2390 svm_set_vintr(svm);
2388 else 2391 else
2389 svm_clear_vintr(svm); 2392 svm_clear_vintr(svm);
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index c6997c0e8ca6..b3292c1ea2f2 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2535,21 +2535,20 @@ static void do_interrupt_requests(struct kvm_vcpu *vcpu,
2535 vmx_inject_nmi(vcpu); 2535 vmx_inject_nmi(vcpu);
2536 if (vcpu->arch.nmi_pending) 2536 if (vcpu->arch.nmi_pending)
2537 enable_nmi_window(vcpu); 2537 enable_nmi_window(vcpu);
2538 else if (vcpu->arch.irq_summary 2538 else if (kvm_cpu_has_interrupt(vcpu) ||
2539 || kvm_run->request_interrupt_window) 2539 kvm_run->request_interrupt_window)
2540 enable_irq_window(vcpu); 2540 enable_irq_window(vcpu);
2541 return; 2541 return;
2542 } 2542 }
2543 2543
2544 if (vcpu->arch.interrupt_window_open) { 2544 if (vcpu->arch.interrupt_window_open) {
2545 if (vcpu->arch.irq_summary && !vcpu->arch.interrupt.pending) 2545 if (kvm_cpu_has_interrupt(vcpu) && !vcpu->arch.interrupt.pending)
2546 kvm_queue_interrupt(vcpu, kvm_pop_irq(vcpu)); 2546 kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu));
2547 2547
2548 if (vcpu->arch.interrupt.pending) 2548 if (vcpu->arch.interrupt.pending)
2549 vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr); 2549 vmx_inject_irq(vcpu, vcpu->arch.interrupt.nr);
2550 } 2550 } else if(kvm_cpu_has_interrupt(vcpu) ||
2551 if (!vcpu->arch.interrupt_window_open && 2551 kvm_run->request_interrupt_window)
2552 (vcpu->arch.irq_summary || kvm_run->request_interrupt_window))
2553 enable_irq_window(vcpu); 2552 enable_irq_window(vcpu);
2554} 2553}
2555 2554
@@ -2976,8 +2975,9 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu,
2976 * If the user space waits to inject interrupts, exit as soon as 2975 * If the user space waits to inject interrupts, exit as soon as
2977 * possible 2976 * possible
2978 */ 2977 */
2979 if (kvm_run->request_interrupt_window && 2978 if (!irqchip_in_kernel(vcpu->kvm) &&
2980 !vcpu->arch.irq_summary) { 2979 kvm_run->request_interrupt_window &&
2980 !kvm_cpu_has_interrupt(vcpu)) {
2981 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; 2981 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
2982 return 0; 2982 return 0;
2983 } 2983 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2bad49b535c8..4c2eb7c0e1fb 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3069,7 +3069,7 @@ EXPORT_SYMBOL_GPL(kvm_emulate_cpuid);
3069static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu, 3069static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu,
3070 struct kvm_run *kvm_run) 3070 struct kvm_run *kvm_run)
3071{ 3071{
3072 return (!vcpu->arch.irq_summary && 3072 return (!irqchip_in_kernel(vcpu->kvm) && !kvm_cpu_has_interrupt(vcpu) &&
3073 kvm_run->request_interrupt_window && 3073 kvm_run->request_interrupt_window &&
3074 vcpu->arch.interrupt_window_open && 3074 vcpu->arch.interrupt_window_open &&
3075 (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF)); 3075 (kvm_x86_ops->get_rflags(vcpu) & X86_EFLAGS_IF));
@@ -3086,7 +3086,7 @@ static void post_kvm_run_save(struct kvm_vcpu *vcpu,
3086 else 3086 else
3087 kvm_run->ready_for_interrupt_injection = 3087 kvm_run->ready_for_interrupt_injection =
3088 (vcpu->arch.interrupt_window_open && 3088 (vcpu->arch.interrupt_window_open &&
3089 vcpu->arch.irq_summary == 0); 3089 !kvm_cpu_has_interrupt(vcpu));
3090} 3090}
3091 3091
3092static void vapic_enter(struct kvm_vcpu *vcpu) 3092static void vapic_enter(struct kvm_vcpu *vcpu)