Message ID | 1366380388-25926-8-git-send-email-agraf@suse.de |
---|---|
State | New, archived |
Headers | show |
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@suse.de> Acked-by: Michael S. Tsirkin <mst@redhat.com> > --- > 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@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
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; +}
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> --- include/linux/kvm_host.h | 3 ++ virt/kvm/irq_comm.c | 76 ++--------------------------------------- virt/kvm/irqchip.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+), 73 deletions(-)