[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH 19/24] ARM: vITS: handle DISCARD command
The DISCARD command drops the connection between a DeviceID/EventID and an LPI/collection pair. We mark the respective structure entries as not allocated and make sure that any queued IRQs are removed. Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx> --- xen/arch/arm/gic-its.c | 21 +++++++++++++++++++ xen/arch/arm/vgic-its.c | 48 +++++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/gic-its.h | 5 +++++ 3 files changed, 74 insertions(+) diff --git a/xen/arch/arm/gic-its.c b/xen/arch/arm/gic-its.c index d1b1cbb..766a7cb 100644 --- a/xen/arch/arm/gic-its.c +++ b/xen/arch/arm/gic-its.c @@ -634,6 +634,27 @@ int gicv3_lpi_change_vcpu(struct domain *d, uint32_t host_lpi, int new_vcpu_id) return 0; } +/* Looks up a given host LPI assigned to that domain and returns the + * connected virtual LPI number. Also stores the target vcpu ID in + * the passed vcpu_id pointer. + * Returns 0 if no host LPI could be found for that domain, or the + * virtual LPI number (>= 8192) if the lookup succeeded. + */ +uint32_t gicv3_lpi_lookup_lpi(struct domain *d, uint32_t host_lpi, int *vcpu_id) +{ + union host_lpi *hlpip, hlpi; + + hlpip = gic_find_host_lpi(host_lpi, d); + if ( !hlpip ) + return 0; + + hlpi.data = hlpip->data; + if ( vcpu_id ) + *vcpu_id = hlpi.vcpu_id; + + return hlpi.virt_lpi; +} + void gicv3_its_dt_init(const struct dt_device_node *node) { const struct dt_device_node *its = NULL; diff --git a/xen/arch/arm/vgic-its.c b/xen/arch/arm/vgic-its.c index c0a60ad..028d234 100644 --- a/xen/arch/arm/vgic-its.c +++ b/xen/arch/arm/vgic-its.c @@ -367,6 +367,51 @@ out_unlock: return 0; } +static int its_handle_discard(struct virt_its *its, uint64_t *cmdptr) +{ + uint32_t devid = its_cmd_get_deviceid(cmdptr); + uint32_t eventid = its_cmd_get_id(cmdptr); + struct pending_irq *pirq; + struct vits_itte *itte; + struct vcpu *vcpu; + uint32_t vlpi; + int ret = -1, vcpu_id; + + spin_lock(&its->its_lock); + itte = get_devid_evid(its, devid, eventid); + if ( !itte ) + goto out_unlock; + + vlpi = gicv3_lpi_lookup_lpi(its->d, itte->hlpi, &vcpu_id); + if ( !vlpi ) + goto out_unlock; + + vcpu = its->d->vcpu[vcpu_id]; + + pirq = lpi_to_pending(vcpu, vlpi, false); + if ( pirq ) + { + clear_bit(GIC_IRQ_GUEST_QUEUED, &pirq->status); + gic_remove_from_queues(vcpu, vlpi); + + /* Mark this pending IRQ struct as availabe again. */ + if ( !test_bit(GIC_IRQ_GUEST_VISIBLE, &pirq->status) ) + pirq->irq = 0; + } + + gicv3_lpi_drop_host_lpi(its->hw_its, devid, eventid, itte->hlpi); + + itte->hlpi = 0; /* Mark this ITTE as unused. */ + ret = 0; + + put_devid_evid(its, itte); + +out_unlock: + spin_unlock(&its->its_lock); + + return ret; +} + #define ITS_CMD_BUFFER_SIZE(baser) ((((baser) & 0xff) + 1) << 12) static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, @@ -390,6 +435,9 @@ static int vgic_its_handle_cmds(struct domain *d, struct virt_its *its, case GITS_CMD_CLEAR: its_handle_clear(its, cmdptr); break; + case GITS_CMD_DISCARD: + its_handle_discard(its, cmdptr); + break; case GITS_CMD_INT: its_handle_int(its, cmdptr); break; diff --git a/xen/include/asm-arm/gic-its.h b/xen/include/asm-arm/gic-its.h index 7e1142f..3f5698d 100644 --- a/xen/include/asm-arm/gic-its.h +++ b/xen/include/asm-arm/gic-its.h @@ -133,6 +133,11 @@ int gicv3_its_map_device(struct host_its *hw_its, struct domain *d, int gicv3_lpi_allocate_host_lpi(struct host_its *its, uint32_t devid, uint32_t eventid, struct vcpu *v, int virt_lpi); +/* Given a physical LPI, looks up and returns the associated virtual LPI + * and the target VCPU in the given domain. + */ +uint32_t gicv3_lpi_lookup_lpi(struct domain *d, uint32_t host_lpi, + int *vcpu_id); int gicv3_lpi_change_vcpu(struct domain *d, uint32_t host_lpi, int new_vcpu_id); int gicv3_lpi_drop_host_lpi(struct host_its *its, uint32_t devid, uint32_t eventid, -- 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 |