diff options
author | Gleb Natapov <gleb@redhat.com> | 2009-08-24 04:54:21 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-12-03 02:32:07 -0500 |
commit | 3e71f88bc90792a187703860cf22fbed7c12cbd9 (patch) | |
tree | 91219ea4a7714ac462c30c15314cfb8f25d0f812 /virt/kvm | |
parent | 46e624b95c36d729bdf24010fff11d16f6fe94fa (diff) |
KVM: Maintain back mapping from irqchip/pin to gsi
Maintain back mapping from irqchip/pin to gsi to speedup
interrupt acknowledgment notifications.
[avi: build fix on non-x86/ia64]
Signed-off-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'virt/kvm')
-rw-r--r-- | virt/kvm/irq_comm.c | 31 |
1 files changed, 14 insertions, 17 deletions
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; |