summaryrefslogtreecommitdiffstats
path: root/virt/kvm/irqchip.c
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2014-06-30 06:51:10 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-08-05 08:26:16 -0400
commit8ba918d488caded2c4368b0b922eb905fe3bb101 (patch)
tree6b14bc6c9b763e5dd7b641c902db3fd04b4d4b89 /virt/kvm/irqchip.c
parent56f89f3629ffd1a21d38c3d0bea23deac0e284ce (diff)
KVM: irqchip: Provide and use accessors for irq routing table
This provides accessor functions for the KVM interrupt mappings, in order to reduce the amount of code that accesses the fields of the kvm_irq_routing_table struct, and restrict that code to one file, virt/kvm/irqchip.c. The new functions are kvm_irq_map_gsi(), which maps from a global interrupt number to a set of IRQ routing entries, and kvm_irq_map_chip_pin, which maps from IRQ chip and pin numbers to a global interrupt number. This also moves the update of kvm_irq_routing_table::chip[][] into irqchip.c, out of the various kvm_set_routing_entry implementations. That means that none of the kvm_set_routing_entry implementations need the kvm_irq_routing_table argument anymore, so this removes it. This does not change any locking or data lifetime rules. Signed-off-by: Paul Mackerras <paulus@samba.org> Tested-by: Eric Auger <eric.auger@linaro.org> Tested-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'virt/kvm/irqchip.c')
-rw-r--r--virt/kvm/irqchip.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
index b43c275775cd..f4648dd94888 100644
--- a/virt/kvm/irqchip.c
+++ b/virt/kvm/irqchip.c
@@ -31,13 +31,37 @@
31#include <trace/events/kvm.h> 31#include <trace/events/kvm.h>
32#include "irq.h" 32#include "irq.h"
33 33
34int kvm_irq_map_gsi(struct kvm_kernel_irq_routing_entry *entries,
35 struct kvm_irq_routing_table *irq_rt, int gsi)
36{
37 struct kvm_kernel_irq_routing_entry *e;
38 int n = 0;
39
40 if (gsi < irq_rt->nr_rt_entries) {
41 hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
42 entries[n] = *e;
43 ++n;
44 }
45 }
46
47 return n;
48}
49
50int kvm_irq_map_chip_pin(struct kvm_irq_routing_table *irq_rt,
51 unsigned irqchip, unsigned pin)
52{
53 return irq_rt->chip[irqchip][pin];
54}
55
34bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin) 56bool kvm_irq_has_notifier(struct kvm *kvm, unsigned irqchip, unsigned pin)
35{ 57{
58 struct kvm_irq_routing_table *irq_rt;
36 struct kvm_irq_ack_notifier *kian; 59 struct kvm_irq_ack_notifier *kian;
37 int gsi, idx; 60 int gsi, idx;
38 61
39 idx = srcu_read_lock(&kvm->irq_srcu); 62 idx = srcu_read_lock(&kvm->irq_srcu);
40 gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin]; 63 irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
64 gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
41 if (gsi != -1) 65 if (gsi != -1)
42 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, 66 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
43 link) 67 link)
@@ -54,13 +78,15 @@ EXPORT_SYMBOL_GPL(kvm_irq_has_notifier);
54 78
55void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin) 79void kvm_notify_acked_irq(struct kvm *kvm, unsigned irqchip, unsigned pin)
56{ 80{
81 struct kvm_irq_routing_table *irq_rt;
57 struct kvm_irq_ack_notifier *kian; 82 struct kvm_irq_ack_notifier *kian;
58 int gsi, idx; 83 int gsi, idx;
59 84
60 trace_kvm_ack_irq(irqchip, pin); 85 trace_kvm_ack_irq(irqchip, pin);
61 86
62 idx = srcu_read_lock(&kvm->irq_srcu); 87 idx = srcu_read_lock(&kvm->irq_srcu);
63 gsi = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu)->chip[irqchip][pin]; 88 irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
89 gsi = kvm_irq_map_chip_pin(irq_rt, irqchip, pin);
64 if (gsi != -1) 90 if (gsi != -1)
65 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list, 91 hlist_for_each_entry_rcu(kian, &kvm->irq_ack_notifier_list,
66 link) 92 link)
@@ -115,8 +141,8 @@ int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi)
115int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level, 141int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
116 bool line_status) 142 bool line_status)
117{ 143{
118 struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; 144 struct kvm_kernel_irq_routing_entry irq_set[KVM_NR_IRQCHIPS];
119 int ret = -1, i = 0, idx; 145 int ret = -1, i, idx;
120 struct kvm_irq_routing_table *irq_rt; 146 struct kvm_irq_routing_table *irq_rt;
121 147
122 trace_kvm_set_irq(irq, level, irq_source_id); 148 trace_kvm_set_irq(irq, level, irq_source_id);
@@ -127,9 +153,7 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level,
127 */ 153 */
128 idx = srcu_read_lock(&kvm->irq_srcu); 154 idx = srcu_read_lock(&kvm->irq_srcu);
129 irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu); 155 irq_rt = srcu_dereference(kvm->irq_routing, &kvm->irq_srcu);
130 if (irq < irq_rt->nr_rt_entries) 156 i = kvm_irq_map_gsi(irq_set, irq_rt, irq);
131 hlist_for_each_entry(e, &irq_rt->map[irq], link)
132 irq_set[i++] = *e;
133 srcu_read_unlock(&kvm->irq_srcu, idx); 157 srcu_read_unlock(&kvm->irq_srcu, idx);
134 158
135 while(i--) { 159 while(i--) {
@@ -171,9 +195,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
171 195
172 e->gsi = ue->gsi; 196 e->gsi = ue->gsi;
173 e->type = ue->type; 197 e->type = ue->type;
174 r = kvm_set_routing_entry(rt, e, ue); 198 r = kvm_set_routing_entry(e, ue);
175 if (r) 199 if (r)
176 goto out; 200 goto out;
201 if (e->type == KVM_IRQ_ROUTING_IRQCHIP)
202 rt->chip[e->irqchip.irqchip][e->irqchip.pin] = e->gsi;
177 203
178 hlist_add_head(&e->link, &rt->map[e->gsi]); 204 hlist_add_head(&e->link, &rt->map[e->gsi]);
179 r = 0; 205 r = 0;