diff options
-rw-r--r-- | arch/ia64/include/asm/kvm.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm.h | 1 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 9 | ||||
-rw-r--r-- | virt/kvm/irq_comm.c | 31 |
4 files changed, 25 insertions, 17 deletions
diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h index 18a7e49abbc5..bc90c75adf67 100644 --- a/arch/ia64/include/asm/kvm.h +++ b/arch/ia64/include/asm/kvm.h | |||
@@ -60,6 +60,7 @@ struct kvm_ioapic_state { | |||
60 | #define KVM_IRQCHIP_PIC_MASTER 0 | 60 | #define KVM_IRQCHIP_PIC_MASTER 0 |
61 | #define KVM_IRQCHIP_PIC_SLAVE 1 | 61 | #define KVM_IRQCHIP_PIC_SLAVE 1 |
62 | #define KVM_IRQCHIP_IOAPIC 2 | 62 | #define KVM_IRQCHIP_IOAPIC 2 |
63 | #define KVM_NR_IRQCHIPS 3 | ||
63 | 64 | ||
64 | #define KVM_CONTEXT_SIZE 8*1024 | 65 | #define KVM_CONTEXT_SIZE 8*1024 |
65 | 66 | ||
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h index 4a5fe914dc59..f02e87a5206f 100644 --- a/arch/x86/include/asm/kvm.h +++ b/arch/x86/include/asm/kvm.h | |||
@@ -79,6 +79,7 @@ struct kvm_ioapic_state { | |||
79 | #define KVM_IRQCHIP_PIC_MASTER 0 | 79 | #define KVM_IRQCHIP_PIC_MASTER 0 |
80 | #define KVM_IRQCHIP_PIC_SLAVE 1 | 80 | #define KVM_IRQCHIP_PIC_SLAVE 1 |
81 | #define KVM_IRQCHIP_IOAPIC 2 | 81 | #define KVM_IRQCHIP_IOAPIC 2 |
82 | #define KVM_NR_IRQCHIPS 3 | ||
82 | 83 | ||
83 | /* for KVM_GET_REGS and KVM_SET_REGS */ | 84 | /* for KVM_GET_REGS and KVM_SET_REGS */ |
84 | struct kvm_regs { | 85 | struct kvm_regs { |
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index f403e66557fb..cc2d7493598b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -131,7 +131,10 @@ struct kvm_kernel_irq_routing_entry { | |||
131 | struct hlist_node link; | 131 | struct hlist_node link; |
132 | }; | 132 | }; |
133 | 133 | ||
134 | #ifdef __KVM_HAVE_IOAPIC | ||
135 | |||
134 | struct kvm_irq_routing_table { | 136 | struct kvm_irq_routing_table { |
137 | int chip[KVM_NR_IRQCHIPS][KVM_IOAPIC_NUM_PINS]; | ||
135 | struct kvm_kernel_irq_routing_entry *rt_entries; | 138 | struct kvm_kernel_irq_routing_entry *rt_entries; |
136 | u32 nr_rt_entries; | 139 | u32 nr_rt_entries; |
137 | /* | 140 | /* |
@@ -141,6 +144,12 @@ struct kvm_irq_routing_table { | |||
141 | struct hlist_head map[0]; | 144 | struct hlist_head map[0]; |
142 | }; | 145 | }; |
143 | 146 | ||
147 | #else | ||
148 | |||
149 | struct kvm_irq_routing_table {}; | ||
150 | |||
151 | #endif | ||
152 | |||
144 | struct kvm { | 153 | struct kvm { |
145 | spinlock_t mmu_lock; | 154 | spinlock_t mmu_lock; |
146 | spinlock_t requests_lock; | 155 | spinlock_t requests_lock; |
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 81950f6f6fd9..59cf8dae0062 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -175,25 +175,16 @@ void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) | |||
175 | { | 175 | { |
176 | struct kvm_irq_ack_notifier *kian; | 176 | struct kvm_irq_ack_notifier *kian; |
177 | struct hlist_node *n; | 177 | struct hlist_node *n; |
178 | unsigned gsi = pin; | 178 | int gsi; |
179 | int i; | ||
180 | 179 | ||
181 | trace_kvm_ack_irq(irqchip, pin); | 180 | trace_kvm_ack_irq(irqchip, pin); |
182 | 181 | ||
183 | for (i = 0; i < kvm->irq_routing->nr_rt_entries; i++) { | 182 | gsi = kvm->irq_routing->chip[irqchip][pin]; |
184 | struct kvm_kernel_irq_routing_entry *e; | 183 | if (gsi != -1) |
185 | e = &kvm->irq_routing->rt_entries[i]; | 184 | hlist_for_each_entry(kian, n, &kvm->arch.irq_ack_notifier_list, |
186 | if (e->type == KVM_IRQ_ROUTING_IRQCHIP && | 185 | link) |
187 | e->irqchip.irqchip == irqchip && | 186 | if (kian->gsi == gsi) |
188 | e->irqchip.pin == pin) { | 187 | kian->irq_acked(kian); |
189 | gsi = e->gsi; | ||
190 | break; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | hlist_for_each_entry(kian, n, &kvm->arch.irq_ack_notifier_list, link) | ||
195 | if (kian->gsi == gsi) | ||
196 | kian->irq_acked(kian); | ||
197 | } | 188 | } |
198 | 189 | ||
199 | void kvm_register_irq_ack_notifier(struct kvm *kvm, | 190 | void kvm_register_irq_ack_notifier(struct kvm *kvm, |
@@ -332,6 +323,9 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, | |||
332 | } | 323 | } |
333 | e->irqchip.irqchip = ue->u.irqchip.irqchip; | 324 | e->irqchip.irqchip = ue->u.irqchip.irqchip; |
334 | e->irqchip.pin = ue->u.irqchip.pin + delta; | 325 | e->irqchip.pin = ue->u.irqchip.pin + delta; |
326 | if (e->irqchip.pin >= KVM_IOAPIC_NUM_PINS) | ||
327 | goto out; | ||
328 | rt->chip[ue->u.irqchip.irqchip][e->irqchip.pin] = ue->gsi; | ||
335 | break; | 329 | break; |
336 | case KVM_IRQ_ROUTING_MSI: | 330 | case KVM_IRQ_ROUTING_MSI: |
337 | e->set = kvm_set_msi; | 331 | e->set = kvm_set_msi; |
@@ -356,7 +350,7 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
356 | unsigned flags) | 350 | unsigned flags) |
357 | { | 351 | { |
358 | struct kvm_irq_routing_table *new, *old; | 352 | struct kvm_irq_routing_table *new, *old; |
359 | u32 i, nr_rt_entries = 0; | 353 | u32 i, j, nr_rt_entries = 0; |
360 | int r; | 354 | int r; |
361 | 355 | ||
362 | for (i = 0; i < nr; ++i) { | 356 | for (i = 0; i < nr; ++i) { |
@@ -377,6 +371,9 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
377 | new->rt_entries = (void *)&new->map[nr_rt_entries]; | 371 | new->rt_entries = (void *)&new->map[nr_rt_entries]; |
378 | 372 | ||
379 | new->nr_rt_entries = nr_rt_entries; | 373 | new->nr_rt_entries = nr_rt_entries; |
374 | for (i = 0; i < 3; i++) | ||
375 | for (j = 0; j < KVM_IOAPIC_NUM_PINS; j++) | ||
376 | new->chip[i][j] = -1; | ||
380 | 377 | ||
381 | for (i = 0; i < nr; ++i) { | 378 | for (i = 0; i < nr; ++i) { |
382 | r = -EINVAL; | 379 | r = -EINVAL; |