On Fri, Apr 19, 2013 at 04:06:18PM +0200, Alexander Graf wrote: > 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@xxxxxxx> Acked-by: Michael S. Tsirkin <mst@xxxxxxxxxx> > --- > include/linux/kvm_host.h | 3 ++ > virt/kvm/irq_comm.c | 76 ++--------------------------------------- > virt/kvm/irqchip.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 91 insertions(+), 73 deletions(-) > > diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h > index a7bfe9d..dcef724 100644 > --- a/include/linux/kvm_host.h > +++ b/include/linux/kvm_host.h > @@ -961,6 +961,9 @@ int kvm_set_irq_routing(struct kvm *kvm, > const struct kvm_irq_routing_entry *entries, > unsigned nr, > unsigned flags); > +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, > + struct kvm_kernel_irq_routing_entry *e, > + const struct kvm_irq_routing_entry *ue); > void kvm_free_irq_routing(struct kvm *kvm); > > int kvm_send_userspace_msi(struct kvm *kvm, struct kvm_msi *msi); > diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c > index d5008f4..e2e6b44 100644 > --- a/virt/kvm/irq_comm.c > +++ b/virt/kvm/irq_comm.c > @@ -271,27 +271,14 @@ void kvm_fire_mask_notifiers(struct kvm *kvm, unsigned irqchip, unsigned pin, > rcu_read_unlock(); > } > > -static int setup_routing_entry(struct kvm_irq_routing_table *rt, > - struct kvm_kernel_irq_routing_entry *e, > - const struct kvm_irq_routing_entry *ue) > +int kvm_set_routing_entry(struct kvm_irq_routing_table *rt, > + struct kvm_kernel_irq_routing_entry *e, > + const struct kvm_irq_routing_entry *ue) > { > int r = -EINVAL; > int delta; > unsigned max_pin; > - struct kvm_kernel_irq_routing_entry *ei; > > - /* > - * Do not allow GSI to be mapped to the same irqchip more than once. > - * Allow only one to one mapping between GSI and MSI. > - */ > - hlist_for_each_entry(ei, &rt->map[ue->gsi], link) > - if (ei->type == KVM_IRQ_ROUTING_MSI || > - ue->type == KVM_IRQ_ROUTING_MSI || > - ue->u.irqchip.irqchip == ei->irqchip.irqchip) > - return r; > - > - e->gsi = ue->gsi; > - e->type = ue->type; > switch (ue->type) { > case KVM_IRQ_ROUTING_IRQCHIP: > delta = 0; > @@ -328,68 +315,11 @@ static int setup_routing_entry(struct kvm_irq_routing_table *rt, > goto out; > } > > - hlist_add_head(&e->link, &rt->map[e->gsi]); > r = 0; > out: > return r; > } > > -int kvm_set_irq_routing(struct kvm *kvm, > - const struct kvm_irq_routing_entry *ue, > - unsigned nr, > - unsigned flags) > -{ > - struct kvm_irq_routing_table *new, *old; > - u32 i, j, nr_rt_entries = 0; > - int r; > - > - for (i = 0; i < nr; ++i) { > - if (ue[i].gsi >= KVM_MAX_IRQ_ROUTES) > - return -EINVAL; > - nr_rt_entries = max(nr_rt_entries, ue[i].gsi); > - } > - > - nr_rt_entries += 1; > - > - new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)) > - + (nr * sizeof(struct kvm_kernel_irq_routing_entry)), > - GFP_KERNEL); > - > - if (!new) > - return -ENOMEM; > - > - new->rt_entries = (void *)&new->map[nr_rt_entries]; > - > - new->nr_rt_entries = nr_rt_entries; > - for (i = 0; i < 3; i++) > - for (j = 0; j < KVM_IRQCHIP_NUM_PINS; j++) > - new->chip[i][j] = -1; > - > - for (i = 0; i < nr; ++i) { > - r = -EINVAL; > - if (ue->flags) > - goto out; > - r = setup_routing_entry(new, &new->rt_entries[i], ue); > - if (r) > - goto out; > - ++ue; > - } > - > - mutex_lock(&kvm->irq_lock); > - old = kvm->irq_routing; > - kvm_irq_routing_update(kvm, new); > - mutex_unlock(&kvm->irq_lock); > - > - synchronize_rcu(); > - > - new = old; > - r = 0; > - > -out: > - kfree(new); > - return r; > -} > - > #define IOAPIC_ROUTING_ENTRY(irq) \ > { .gsi = irq, .type = KVM_IRQ_ROUTING_IRQCHIP, \ > .u.irqchip.irqchip = KVM_IRQCHIP_IOAPIC, .u.irqchip.pin = (irq) } > diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c > index 12f7f26..20dc9e4 100644 > --- a/virt/kvm/irqchip.c > +++ b/virt/kvm/irqchip.c > @@ -150,3 +150,88 @@ void kvm_free_irq_routing(struct kvm *kvm) > at this stage */ > kfree(kvm->irq_routing); > } > + > +static int setup_routing_entry(struct kvm_irq_routing_table *rt, > + struct kvm_kernel_irq_routing_entry *e, > + const struct kvm_irq_routing_entry *ue) > +{ > + int r = -EINVAL; > + struct kvm_kernel_irq_routing_entry *ei; > + > + /* > + * Do not allow GSI to be mapped to the same irqchip more than once. > + * Allow only one to one mapping between GSI and MSI. > + */ > + hlist_for_each_entry(ei, &rt->map[ue->gsi], link) > + if (ei->type == KVM_IRQ_ROUTING_MSI || > + ue->type == KVM_IRQ_ROUTING_MSI || > + ue->u.irqchip.irqchip == ei->irqchip.irqchip) > + return r; > + > + e->gsi = ue->gsi; > + e->type = ue->type; > + r = kvm_set_routing_entry(rt, e, ue); > + if (r) > + goto out; > + > + hlist_add_head(&e->link, &rt->map[e->gsi]); > + r = 0; > +out: > + return r; > +} > + > +int kvm_set_irq_routing(struct kvm *kvm, > + const struct kvm_irq_routing_entry *ue, > + unsigned nr, > + unsigned flags) > +{ > + struct kvm_irq_routing_table *new, *old; > + u32 i, j, nr_rt_entries = 0; > + int r; > + > + for (i = 0; i < nr; ++i) { > + if (ue[i].gsi >= KVM_MAX_IRQ_ROUTES) > + return -EINVAL; > + nr_rt_entries = max(nr_rt_entries, ue[i].gsi); > + } > + > + nr_rt_entries += 1; > + > + new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)) > + + (nr * sizeof(struct kvm_kernel_irq_routing_entry)), > + GFP_KERNEL); > + > + if (!new) > + return -ENOMEM; > + > + new->rt_entries = (void *)&new->map[nr_rt_entries]; > + > + new->nr_rt_entries = nr_rt_entries; > + for (i = 0; i < KVM_NR_IRQCHIPS; i++) > + for (j = 0; j < KVM_IRQCHIP_NUM_PINS; j++) > + new->chip[i][j] = -1; > + > + for (i = 0; i < nr; ++i) { > + r = -EINVAL; > + if (ue->flags) > + goto out; > + r = setup_routing_entry(new, &new->rt_entries[i], ue); > + if (r) > + goto out; > + ++ue; > + } > + > + mutex_lock(&kvm->irq_lock); > + old = kvm->irq_routing; > + kvm_irq_routing_update(kvm, new); > + mutex_unlock(&kvm->irq_lock); > + > + synchronize_rcu(); > + > + new = old; > + r = 0; > + > +out: > + kfree(new); > + return r; > +} > -- > 1.6.0.2 > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html