diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-04-21 10:44:56 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:45 -0400 |
commit | 8061823a25218174f30c3dd943989e1d72f7d06e (patch) | |
tree | ee94e6ac86efe3c0bdeb933b8538ae06e99f6fe3 | |
parent | 3438253926822a6bf8487b4f7d82f26a2c0b2388 (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>
-rw-r--r-- | arch/x86/kvm/irq.c | 7 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 11 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 18 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 4 |
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); | |||
3069 | static int dm_request_for_irq_injection(struct kvm_vcpu *vcpu, | 3069 | static 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 | ||
3092 | static void vapic_enter(struct kvm_vcpu *vcpu) | 3092 | static void vapic_enter(struct kvm_vcpu *vcpu) |