diff options
Diffstat (limited to 'virt/kvm/irq_comm.c')
-rw-r--r-- | virt/kvm/irq_comm.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c index 6c946141dbcc..fadf4408a820 100644 --- a/virt/kvm/irq_comm.c +++ b/virt/kvm/irq_comm.c | |||
@@ -146,8 +146,8 @@ static int kvm_set_msi(struct kvm_kernel_irq_routing_entry *e, | |||
146 | */ | 146 | */ |
147 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) | 147 | int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) |
148 | { | 148 | { |
149 | struct kvm_kernel_irq_routing_entry *e; | 149 | struct kvm_kernel_irq_routing_entry *e, irq_set[KVM_NR_IRQCHIPS]; |
150 | int ret = -1; | 150 | int ret = -1, i = 0; |
151 | struct kvm_irq_routing_table *irq_rt; | 151 | struct kvm_irq_routing_table *irq_rt; |
152 | struct hlist_node *n; | 152 | struct hlist_node *n; |
153 | 153 | ||
@@ -162,14 +162,19 @@ int kvm_set_irq(struct kvm *kvm, int irq_source_id, u32 irq, int level) | |||
162 | rcu_read_lock(); | 162 | rcu_read_lock(); |
163 | irq_rt = rcu_dereference(kvm->irq_routing); | 163 | irq_rt = rcu_dereference(kvm->irq_routing); |
164 | if (irq < irq_rt->nr_rt_entries) | 164 | if (irq < irq_rt->nr_rt_entries) |
165 | hlist_for_each_entry(e, n, &irq_rt->map[irq], link) { | 165 | hlist_for_each_entry(e, n, &irq_rt->map[irq], link) |
166 | int r = e->set(e, kvm, irq_source_id, level); | 166 | irq_set[i++] = *e; |
167 | if (r < 0) | ||
168 | continue; | ||
169 | |||
170 | ret = r + ((ret < 0) ? 0 : ret); | ||
171 | } | ||
172 | rcu_read_unlock(); | 167 | rcu_read_unlock(); |
168 | |||
169 | while(i--) { | ||
170 | int r; | ||
171 | r = irq_set[i].set(&irq_set[i], kvm, irq_source_id, level); | ||
172 | if (r < 0) | ||
173 | continue; | ||
174 | |||
175 | ret = r + ((ret < 0) ? 0 : ret); | ||
176 | } | ||
177 | |||
173 | return ret; | 178 | return ret; |
174 | } | 179 | } |
175 | 180 | ||