[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v11 21/34] ARM: vITS: provide access to struct pending_irq
For each device we allocate one struct pending_irq for each virtual event (MSI). Provide a helper function which returns the pointer to the appropriate struct, to be able to find the right struct when given a virtual deviceID/eventID pair. Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> Acked-by: Julien Grall <julien.grall@xxxxxxx> --- xen/arch/arm/gic-v3-its.c | 59 ++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/gic_v3_its.h | 4 +++ 2 files changed, 63 insertions(+) diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c index aebc257..38f0840 100644 --- a/xen/arch/arm/gic-v3-its.c +++ b/xen/arch/arm/gic-v3-its.c @@ -800,6 +800,65 @@ out: return ret; } +/* Must be called with the its_device_lock held. */ +static struct its_device *get_its_device(struct domain *d, paddr_t vdoorbell, + uint32_t vdevid) +{ + struct rb_node *node = d->arch.vgic.its_devices.rb_node; + struct its_device *dev; + + ASSERT(spin_is_locked(&d->arch.vgic.its_devices_lock)); + + while (node) + { + int cmp; + + dev = rb_entry(node, struct its_device, rbnode); + cmp = compare_its_guest_devices(dev, vdoorbell, vdevid); + + if ( !cmp ) + return dev; + + if ( cmp > 0 ) + node = node->rb_left; + else + node = node->rb_right; + } + + return NULL; +} + +static struct pending_irq *get_event_pending_irq(struct domain *d, + paddr_t vdoorbell_address, + uint32_t vdevid, + uint32_t eventid, + uint32_t *host_lpi) +{ + struct its_device *dev; + struct pending_irq *pirq = NULL; + + spin_lock(&d->arch.vgic.its_devices_lock); + dev = get_its_device(d, vdoorbell_address, vdevid); + if ( dev && eventid < dev->eventids ) + { + pirq = &dev->pend_irqs[eventid]; + if ( host_lpi ) + *host_lpi = dev->host_lpi_blocks[eventid / LPI_BLOCK] + + (eventid % LPI_BLOCK); + } + spin_unlock(&d->arch.vgic.its_devices_lock); + + return pirq; +} + +struct pending_irq *gicv3_its_get_event_pending_irq(struct domain *d, + paddr_t vdoorbell_address, + uint32_t vdevid, + uint32_t eventid) +{ + return get_event_pending_irq(d, vdoorbell_address, vdevid, eventid, NULL); +} + /* Scan the DT for any ITS nodes and create a list of host ITSes out of it. */ void gicv3_its_dt_init(const struct dt_device_node *node) { diff --git a/xen/include/asm-arm/gic_v3_its.h b/xen/include/asm-arm/gic_v3_its.h index 5db7d04..be67726 100644 --- a/xen/include/asm-arm/gic_v3_its.h +++ b/xen/include/asm-arm/gic_v3_its.h @@ -171,6 +171,10 @@ void gicv3_free_host_lpi_block(uint32_t first_lpi); void vgic_vcpu_inject_lpi(struct domain *d, unsigned int virq); +struct pending_irq *gicv3_its_get_event_pending_irq(struct domain *d, + paddr_t vdoorbell_address, + uint32_t vdevid, + uint32_t eventid); #else static inline void gicv3_its_dt_init(const struct dt_device_node *node) -- 2.9.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |