aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/irq.c
diff options
context:
space:
mode:
authorEddie Dong <eddie.dong@intel.com>2007-09-12 03:58:04 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:25 -0400
commit97222cc8316328965851ed28d23f6b64b4c912d2 (patch)
tree469b2f72e74046a7aec5061df194c3f68812a224 /drivers/kvm/irq.c
parent7017fc3d1a12e30ea7df4992152978a188433457 (diff)
KVM: Emulate local APIC in kernel
Because lightweight exits (exits which don't involve userspace) are many times faster than heavyweight exits, it makes sense to emulate high usage devices in the kernel. The local APIC is one such device, especially for Windows and for SMP, so we add an APIC model to kvm. It also allows in-kernel host-side drivers to inject interrupts without going through userspace. [compile fix on i386 from Jindrich Makovicka] Signed-off-by: Yaozu (Eddie) Dong <Eddie.Dong@intel.com> Signed-off-by: Qing He <qing.he@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/irq.c')
-rw-r--r--drivers/kvm/irq.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/drivers/kvm/irq.c b/drivers/kvm/irq.c
index b08005ca7050..0b4430a0cae0 100644
--- a/drivers/kvm/irq.c
+++ b/drivers/kvm/irq.c
@@ -30,14 +30,13 @@
30 */ 30 */
31int kvm_cpu_has_interrupt(struct kvm_vcpu *v) 31int kvm_cpu_has_interrupt(struct kvm_vcpu *v)
32{ 32{
33 struct kvm_pic *s = pic_irqchip(v->kvm); 33 struct kvm_pic *s;
34 34
35 if (s->output) /* PIC */ 35 if (kvm_apic_has_interrupt(v) == -1) { /* LAPIC */
36 return 1; 36 s = pic_irqchip(v->kvm); /* PIC */
37 /* 37 return s->output;
38 * TODO: APIC 38 }
39 */ 39 return 1;
40 return 0;
41} 40}
42EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); 41EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
43 42
@@ -46,16 +45,36 @@ EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt);
46 */ 45 */
47int kvm_cpu_get_interrupt(struct kvm_vcpu *v) 46int kvm_cpu_get_interrupt(struct kvm_vcpu *v)
48{ 47{
49 struct kvm_pic *s = pic_irqchip(v->kvm); 48 struct kvm_pic *s;
50 int vector; 49 int vector;
51 50
52 s->output = 0; 51 vector = kvm_get_apic_interrupt(v); /* APIC */
53 vector = kvm_pic_read_irq(s); 52 if (vector == -1) {
54 if (vector != -1) 53 s = pic_irqchip(v->kvm);
55 return vector; 54 s->output = 0; /* PIC */
56 /* 55 vector = kvm_pic_read_irq(s);
57 * TODO: APIC 56 }
58 */ 57 return vector;
59 return -1;
60} 58}
61EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt); 59EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt);
60
61static void vcpu_kick_intr(void *info)
62{
63#ifdef DEBUG
64 struct kvm_vcpu *vcpu = (struct kvm_vcpu *)info;
65 printk(KERN_DEBUG "vcpu_kick_intr %p \n", vcpu);
66#endif
67}
68
69void kvm_vcpu_kick(struct kvm_vcpu *vcpu)
70{
71 int ipi_pcpu = vcpu->cpu;
72
73 if (vcpu->guest_mode)
74 smp_call_function_single(ipi_pcpu, vcpu_kick_intr, vcpu, 0, 0);
75}
76
77void kvm_ioapic_update_eoi(struct kvm *kvm, int vector)
78{
79 /* TODO: for kernel IOAPIC */
80}