Skip to content

Commit e8cde09

Browse files
committed
KVM: Move irq routing setup to irqchip.c
Setting up IRQ routes is nothing IOAPIC specific. Extract everything that really is generic code into irqchip.c and only leave the ioapic specific bits to irq_comm.c. Signed-off-by: Alexander Graf <agraf@suse.de> Acked-by: Michael S. Tsirkin <mst@redhat.com>
1 parent 1c9f852 commit e8cde09

File tree

3 files changed

+91
-73
lines changed

3 files changed

+91
-73
lines changed

include/linux/kvm_host.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,9 @@ int kvm_set_irq_routing(struct kvm *kvm,
961961
const struct kvm_irq_routing_entry *entries,
962962
unsigned nr,
963963
unsigned flags);
964+
int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
965+
struct kvm_kernel_irq_routing_entry *e,
966+
const struct kvm_irq_routing_entry *ue);
964967
void kvm_free_irq_routing(struct kvm *kvm);
965968

966969
int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi);

virt/kvm/irq_comm.c

Lines changed: 3 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -271,27 +271,14 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin,
271271
rcu_read_unlock();
272272
}
273273

274-
static int setup_routing_entry(struct kvm_irq_routing_table *rt,
275-
struct kvm_kernel_irq_routing_entry *e,
276-
const struct kvm_irq_routing_entry *ue)
274+
int kvm_set_routing_entry(struct kvm_irq_routing_table *rt,
275+
struct kvm_kernel_irq_routing_entry *e,
276+
const struct kvm_irq_routing_entry *ue)
277277
{
278278
int r = -EINVAL;
279279
int delta;
280280
unsigned max_pin;
281-
struct kvm_kernel_irq_routing_entry *ei;
282281

283-
/*
284-
* Do not allow GSI to be mapped to the same irqchip more than once.
285-
* Allow only one to one mapping between GSI and MSI.
286-
*/
287-
hlist_for_each_entry(ei, &rt->map[ue->gsi], link)
288-
if (ei->type == KVM_IRQ_ROUTING_MSI ||
289-
ue->type == KVM_IRQ_ROUTING_MSI ||
290-
ue->u.irqchip.irqchip == ei->irqchip.irqchip)
291-
return r;
292-
293-
e->gsi = ue->gsi;
294-
e->type = ue->type;
295282
switch (ue->type) {
296283
case KVM_IRQ_ROUTING_IRQCHIP:
297284
delta = 0;
@@ -328,68 +315,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt,
328315
goto out;
329316
}
330317

331-
hlist_add_head(&e->link, &rt->map[e->gsi]);
332318
r = 0;
333319
out:
334320
return r;
335321
}
336322

337-
int kvm_set_irq_routing(struct kvm *kvm,
338-
const struct kvm_irq_routing_entry *ue,
339-
unsigned nr,
340-
unsigned flags)
341-
{
342-
struct kvm_irq_routing_table *new, *old;
343-
u32 i, j, nr_rt_entries = 0;
344-
int r;
345-
346-
for (i = 0; i < nr; ++i) {
347-
if (ue[i].gsi >= KVM_MAX_IRQ_ROUTES)
348-
return -EINVAL;
349-
nr_rt_entries = max(nr_rt_entries, ue[i].gsi);
350-
}
351-
352-
nr_rt_entries += 1;
353-
354-
new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head))
355-
+ (nr * sizeof(struct kvm_kernel_irq_routing_entry)),
356-
GFP_KERNEL);
357-
358-
if (!new)
359-
return -ENOMEM;
360-
361-
new->rt_entries = (void *)&new->map[nr_rt_entries];
362-
363-
new->nr_rt_entries = nr_rt_entries;
364-
for (i = 0; i < 3; i++)
365-
for (j = 0; j < KVM_IRQCHIP_NUM_PINS; j++)
366-
new->chip[i][j] = -1;
367-
368-
for (i = 0; i < nr; ++i) {
369-
r = -EINVAL;
370-
if (ue->flags)
371-
goto out;
372-
r = setup_routing_entry(new, &new->rt_entries[i], ue);
373-
if (r)
374-
goto out;
375-
++ue;
376-
}
377-
378-
mutex_lock(&kvm->irq_lock);
379-
old = kvm->irq_routing;
380-
kvm_irq_routing_update(kvm, new);
381-
mutex_unlock(&kvm->irq_lock);
382-
383-
synchronize_rcu();
384-
385-
new = old;
386-
r = 0;
387-
388-
out:
389-
kfree(new);
390-
return r;
391-
}
392-
393323
#define IOAPIC_ROUTING_ENTRY(irq) \
394324
{ .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \
395325
.u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) }

virt/kvm/irqchip.c

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,88 @@ void kvm_free_irq_routing(struct kvm *kvm)
150150
at this stage */
151151
kfree(kvm->irq_routing);
152152
}
153+
154+
static int setup_routing_entry(struct kvm_irq_routing_table *rt,
155+
struct kvm_kernel_irq_routing_entry *e,
156+
const struct kvm_irq_routing_entry *ue)
157+
{
158+
int r = -EINVAL;
159+
struct kvm_kernel_irq_routing_entry *ei;
160+
161+
/*
162+
* Do not allow GSI to be mapped to the same irqchip more than once.
163+
* Allow only one to one mapping between GSI and MSI.
164+
*/
165+
hlist_for_each_entry(ei, &rt->map[ue->gsi], link)
166+
if (ei->type == KVM_IRQ_ROUTING_MSI ||
167+
ue->type == KVM_IRQ_ROUTING_MSI ||
168+
ue->u.irqchip.irqchip == ei->irqchip.irqchip)
169+
return r;
170+
171+
e->gsi = ue->gsi;
172+
e->type = ue->type;
173+
r = kvm_set_routing_entry(rt, e, ue);
174+
if (r)
175+
goto out;
176+
177+
hlist_add_head(&e->link, &rt->map[e->gsi]);
178+
r = 0;
179+
out:
180+
return r;
181+
}
182+
183+
int kvm_set_irq_routing(struct kvm *kvm,
184+
const struct kvm_irq_routing_entry *ue,
185+
unsigned nr,
186+
unsigned flags)
187+
{
188+
struct kvm_irq_routing_table *new, *old;
189+
u32 i, j, nr_rt_entries = 0;
190+
int r;
191+
192+
for (i = 0; i < nr; ++i) {
193+
if (ue[i].gsi >= KVM_MAX_IRQ_ROUTES)
194+
return -EINVAL;
195+
nr_rt_entries = max(nr_rt_entries, ue[i].gsi);
196+
}
197+
198+
nr_rt_entries += 1;
199+
200+
new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head))
201+
+ (nr * sizeof(struct kvm_kernel_irq_routing_entry)),
202+
GFP_KERNEL);
203+
204+
if (!new)
205+
return -ENOMEM;
206+
207+
new->rt_entries = (void *)&new->map[nr_rt_entries];
208+
209+
new->nr_rt_entries = nr_rt_entries;
210+
for (i = 0; i < KVM_NR_IRQCHIPS; i++)
211+
for (j = 0; j < KVM_IRQCHIP_NUM_PINS; j++)
212+
new->chip[i][j] = -1;
213+
214+
for (i = 0; i < nr; ++i) {
215+
r = -EINVAL;
216+
if (ue->flags)
217+
goto out;
218+
r = setup_routing_entry(new, &new->rt_entries[i], ue);
219+
if (r)
220+
goto out;
221+
++ue;
222+
}
223+
224+
mutex_lock(&kvm->irq_lock);
225+
old = kvm->irq_routing;
226+
kvm_irq_routing_update(kvm, new);
227+
mutex_unlock(&kvm->irq_lock);
228+
229+
synchronize_rcu();
230+
231+
new = old;
232+
r = 0;
233+
234+
out:
235+
kfree(new);
236+
return r;
237+
}

0 commit comments

Comments
 (0)