[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v2 20/27] ARM: vITS: handle MAPTI command



Hi,

On 24/03/17 14:54, Julien Grall wrote:
> Hi Andre,
> 
> On 03/16/2017 11:20 AM, Andre Przywara wrote:
>> The MAPTI commands associates a DeviceID/EventID pair with a LPI/CPU
>> pair and actually instantiates LPI interrupts.
>> We connect the already allocated host LPI to this virtual LPI, so that
>> any triggering IRQ on the host can be quickly forwarded to a guest.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
>> ---
>>  xen/arch/arm/gic-v3-its.c        | 63
>> ++++++++++++++++++++++++++++++++++++++++
>>  xen/arch/arm/gic-v3-lpi.c        | 18 ++++++++++++
>>  xen/arch/arm/vgic-v3-its.c       | 27 +++++++++++++++--
>>  xen/include/asm-arm/gic_v3_its.h |  6 ++++
>>  4 files changed, 112 insertions(+), 2 deletions(-)
>>
>> diff --git a/xen/arch/arm/gic-v3-its.c b/xen/arch/arm/gic-v3-its.c
>> index 5a2dbec..e2fcf50 100644
>> --- a/xen/arch/arm/gic-v3-its.c
>> +++ b/xen/arch/arm/gic-v3-its.c
>> @@ -724,6 +724,69 @@ restart:
>>      spin_unlock(&d->arch.vgic.its_devices_lock);
>>  }
>>
>> +/*
>> + * Translates an event for a given guest device ID into the
>> associated host
>> + * LPI number. This can be used to look up the mapped guest LPI.
>> + */
>> +static uint32_t translate_event(struct domain *d, paddr_t doorbell,
>> +                                uint32_t devid, uint32_t eventid)
>> +{
>> +    struct rb_node *node;
>> +    struct its_devices *dev;
>> +    uint32_t host_lpi = 0;
>> +    int cmp;
>> +
>> +    spin_lock(&d->arch.vgic.its_devices_lock);
>> +    node = d->arch.vgic.its_devices.rb_node;
>> +    while (node)
>> +    {
>> +        dev = rb_entry(node, struct its_devices, rbnode);
>> +        cmp = compare_its_guest_devices(dev, doorbell, devid);
>> +
>> +        if ( !cmp )
>> +        {
>> +            if ( eventid >= dev->eventids )
>> +                goto out;
>> +
>> +            host_lpi = dev->host_lpis[eventid / LPI_BLOCK] +
>> +                                (eventid % LPI_BLOCK);
>> +            if ( !is_lpi(host_lpi) )
> 
> Hmmm, I don't understand this check. host_lpi should always be an LPI. No?

Looks like. Dropped in v4.

>> +                host_lpi = 0;
>> +            goto out;
>> +        }
>> +
>> +        if ( cmp > 0 )
>> +            node = node->rb_left;
>> +        else
>> +            node = node->rb_right;
>> +    }
>> +
>> +out:
>> +    spin_unlock(&d->arch.vgic.its_devices_lock);
>> +
>> +    return host_lpi;
>> +}
>> +
>> +/*
>> + * Connects the event ID for an already assigned device to the given
>> VCPU/vLPI
>> + * pair. The corresponding physical LPI is already mapped on the host
>> side
>> + * (when assigning the physical device to the guest), so we just
>> connect the
>> + * target VCPU/vLPI pair to that interrupt to inject it properly if
>> it fires.
>> + */
>> +int gicv3_assign_guest_event(struct domain *d, paddr_t doorbell_address,
>> +                             uint32_t devid, uint32_t eventid,
> 
> It looks like to me that devid is the virtual deviceID. If so, please
> prefix with 'v', otherwise 'p'.

Fixed in v4.

>> +                             struct vcpu *v, uint32_t virt_lpi)
>> +{
>> +    uint32_t host_lpi = translate_event(d, doorbell_address, devid,
>> eventid);
>> +
>> +    if ( !host_lpi )
>> +        return -ENOENT;
>> +
>> +    gicv3_lpi_update_host_entry(host_lpi, d->domain_id, v->vcpu_id,
>> virt_lpi);
>> +
>> +    return 0;
>> +}
>> +
>>  /* 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/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c
>> index 994698e..c110ec9 100644
>> --- a/xen/arch/arm/gic-v3-lpi.c
>> +++ b/xen/arch/arm/gic-v3-lpi.c
>> @@ -153,6 +153,24 @@ void do_LPI(unsigned int lpi)
>>      vgic_vcpu_inject_irq(vcpu, hlpi.virt_lpi);
>>  }
>>
>> +int gicv3_lpi_update_host_entry(uint32_t host_lpi, int domain_id,
>> +                                unsigned int vcpu_id, uint32_t virt_lpi)
>> +{
>> +    union host_lpi *hlpip, hlpi;
>> +
>> +    host_lpi -= LPI_OFFSET;
> 
> I would add an ASSERT(host_lpi > LPI_OFFSET);

Fixed in v4.

>> +
>> +    hlpip = &lpi_data.host_lpis[host_lpi /
>> HOST_LPIS_PER_PAGE][host_lpi % HOST_LPIS_PER_PAGE];
>> +
>> +    hlpi.virt_lpi = virt_lpi;
>> +    hlpi.dom_id = domain_id;
>> +    hlpi.vcpu_id = vcpu_id;
>> +
>> +    write_u64_atomic(&hlpip->data, hlpi.data);
>> +
>> +    return 0;
>> +}
>> +
>>  static int gicv3_lpi_allocate_pendtable(uint64_t *reg)
>>  {
>>      uint64_t val;
>> diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
>> index c26d5d4..600ff69 100644
>> --- a/xen/arch/arm/vgic-v3-its.c
>> +++ b/xen/arch/arm/vgic-v3-its.c
>> @@ -167,8 +167,8 @@ static bool read_itte(struct virt_its *its,
>> uint32_t devid, uint32_t evid,
>>  }
>>
>>  #define SKIP_LPI_UPDATE 1
>> -bool write_itte(struct virt_its *its, uint32_t devid, uint32_t evid,
>> -                uint32_t collid, uint32_t vlpi, struct vcpu **vcpu)
>> +static bool write_itte(struct virt_its *its, uint32_t devid, uint32_t
>> evid,
>> +                       uint32_t collid, uint32_t vlpi, struct vcpu
>> **vcpu)
> 
> Please explain in the commit message why you move to static.

Fixed in v4.

> 
>>  {
>>      struct vits_itte *itte;
>>
>> @@ -332,6 +332,25 @@ static int its_handle_mapd(struct virt_its *its,
>> uint64_t *cmdptr)
>>      return 0;
>>  }
>>
>> +static int its_handle_mapti(struct virt_its *its, uint64_t *cmdptr)
>> +{
>> +    uint32_t devid = its_cmd_get_deviceid(cmdptr);
>> +    uint32_t eventid = its_cmd_get_id(cmdptr);
>> +    uint32_t intid = its_cmd_get_physical_id(cmdptr);
>> +    int collid = its_cmd_get_collection(cmdptr);
> 
> This should be unsigned.

Fixed in v4.

>> +    struct vcpu *vcpu;
>> +
>> +    if ( its_cmd_get_command(cmdptr) == GITS_CMD_MAPI )
>> +        intid = eventid;
>> +
>> +    if ( !write_itte(its, devid, eventid, collid, intid, &vcpu) )
>> +        return -1;
>> +
>> +    gicv3_assign_guest_event(its->d, its->doorbell_address, devid,
>> eventid, vcpu, intid);
> 
> If you have a function returning an error, then you should check it and
> not ignoring it.

Fixed in v3.

Cheers,
Andre.

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.