[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v4 2/4] x86/physdev: factor out the code to allocate and map a pirq
On 01/06/17 12:49, Roger Pau Monne wrote: > Move the code to allocate and map a domain pirq (either GSI or MSI) > into the x86 irq code base, so that it can be used outside of the > physdev ops. > > This change shouldn't affect the functionality of the already existing > physdev ops. > > Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> As you are moving code, please could you make some style fixes (which can be done on commit if there are no other problems). > --- > Cc: Jan Beulich <jbeulich@xxxxxxxx> > Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > --- > Changes since v3: > - Pass the index parameter to the allocate_pirq function, so that it > can be printed in case of error. > - Remove pointless elses in allocate_pirq. > - Return directly in the last check of allocate_pirq (instead of > storing the error code in the pirq variable. > - allocate_and_map_{gsi/msi}_pirq don't need index to be a pointer. > - Fix the last parameter of the allocate_pirq call in > allocate_and_map_gsi_pirq to use NULL (instead of 0). > - Add an ASSERT_UNREACHABLE if the interrupt type passed to > allocate_and_map_msi_pirq is not of MSI the MSI kind. > - Restore newlines in the physdev_map_pirq switch case. > > Changes since v2: > - Factor out the code to allocate the pirq. > - Fix coding style issues. > - Do not take the pci lock to bind a GSI. > - Pass a type parameter to the MSI bind function. > > Changes since v1: > - New in this version. > --- > xen/arch/x86/irq.c | 159 > ++++++++++++++++++++++++++++++++++++++++++++++ > xen/arch/x86/physdev.c | 122 ++--------------------------------- > xen/include/asm-x86/irq.h | 5 ++ > 3 files changed, 169 insertions(+), 117 deletions(-) > > diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c > index 676ba5216f..5184b6144e 100644 > --- a/xen/arch/x86/irq.c > +++ b/xen/arch/x86/irq.c > @@ -2537,3 +2537,162 @@ bool_t hvm_domain_use_pirq(const struct domain *d, > const struct pirq *pirq) > return is_hvm_domain(d) && pirq && > pirq->arch.hvm.emuirq != IRQ_UNBOUND; > } > + > +static int allocate_pirq(struct domain *d, int index, int pirq, int irq, > + int type, int *nr) > +{ > + int current_pirq; > + > + ASSERT(spin_is_locked(&d->event_lock)); > + current_pirq = domain_irq_to_pirq(d, irq); > + if ( pirq < 0 ) > + { > + if ( current_pirq ) > + { > + dprintk(XENLOG_G_ERR, "dom%d: %d:%d already mapped to %d\n", > + d->domain_id, index, pirq, current_pirq); > + if ( current_pirq < 0 ) > + return -EBUSY; > + } > + else if ( type == MAP_PIRQ_TYPE_MULTI_MSI ) > + { > + if ( *nr <= 0 || *nr > 32 ) > + return -EDOM; > + if ( *nr != 1 && !iommu_intremap ) > + return -EOPNOTSUPP; > + > + while ( *nr & (*nr - 1) ) > + *nr += *nr & -*nr; > + pirq = get_free_pirqs(d, *nr); > + if ( pirq < 0 ) > + { > + while ( (*nr >>= 1) > 1 ) > + if ( get_free_pirqs(d, *nr) > 0 ) > + break; > + dprintk(XENLOG_G_ERR, "dom%d: no block of %d free pirqs\n", > + d->domain_id, *nr << 1); > + } > + } > + else > + { > + pirq = get_free_pirq(d, type); > + if ( pirq < 0 ) > + dprintk(XENLOG_G_ERR, "dom%d: no free pirq\n", d->domain_id); > + } > + } > + else if ( current_pirq && pirq != current_pirq ) > + { > + dprintk(XENLOG_G_ERR, "dom%d: irq %d already mapped to pirq %d\n", > + d->domain_id, irq, current_pirq); > + return -EEXIST; > + } > + > + return pirq; > +} > + > +int allocate_and_map_gsi_pirq(struct domain *d, int index, int *pirq_p) > +{ > + int irq, pirq, ret; > + > + if ( index < 0 || index >= nr_irqs_gsi ) > + { > + dprintk(XENLOG_G_ERR, "dom%d: map invalid irq %d\n", d->domain_id, > + index); > + return -EINVAL; > + } > + > + irq = domain_pirq_to_irq(current->domain, index); > + if ( irq <= 0 ) > + { > + if ( is_hardware_domain(current->domain) ) > + irq = index; > + else > + { > + dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n", > + d->domain_id); > + return -EINVAL; > + } > + } > + > + /* Verify or get pirq. */ > + spin_lock(&d->event_lock); > + pirq = allocate_pirq(d, index, *pirq_p, irq, MAP_PIRQ_TYPE_GSI, NULL); > + if ( pirq < 0 ) > + { > + ret = pirq; > + goto done; > + } > + > + ret = map_domain_pirq(d, pirq, irq, MAP_PIRQ_TYPE_GSI, NULL); > + if ( ret == 0 ) > + *pirq_p = pirq; > + > + done: > + spin_unlock(&d->event_lock); > + > + return ret; > +} > + > +int allocate_and_map_msi_pirq(struct domain *d, int index, int *pirq_p, > + int type, struct msi_info *msi) > +{ > + int irq, pirq, ret; > + > + switch ( type ) > + { > + case MAP_PIRQ_TYPE_MSI: > + if ( !msi->table_base ) > + msi->entry_nr = 1; > + irq = index; > + if ( irq == -1 ) { > + case MAP_PIRQ_TYPE_MULTI_MSI: > + irq = create_irq(NUMA_NO_NODE); } > + > + if ( irq < nr_irqs_gsi || irq >= nr_irqs ) > + { > + dprintk(XENLOG_G_ERR, "dom%d: can't create irq for msi!\n", > + d->domain_id); > + return -EINVAL; > + } > + > + msi->irq = irq; > + break; > + > + default: > + dprintk(XENLOG_G_ERR, "dom%d: wrong pirq type %x\n", > + d->domain_id, type); > + ASSERT_UNREACHABLE(); > + return -EINVAL; > + } > + > + msi->irq = irq; > + > + pcidevs_lock(); > + /* Verify or get pirq. */ > + spin_lock(&d->event_lock); > + pirq = allocate_pirq(d, index, *pirq_p, irq, type, &msi->entry_nr); > + if ( pirq < 0 ) > + { > + ret = pirq; > + goto done; > + } > + > + ret = map_domain_pirq(d, pirq, irq, type, msi); > + if ( ret == 0 ) > + *pirq_p = pirq; > + > + done: > + spin_unlock(&d->event_lock); > + pcidevs_unlock(); > + if ( ret != 0 ) { > + switch ( type ) > + { > + case MAP_PIRQ_TYPE_MSI: > + if ( index == -1 ) > + case MAP_PIRQ_TYPE_MULTI_MSI: > + destroy_irq(irq); > + break; > + } } > + > + return ret; > +} ~Andrew _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |