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

Re: [PATCH v5 4/4] xen/arm: vgic: free eSPIs using the bitmap index


  • To: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Mykola Kvach <Mykola_Kvach@xxxxxxxx>
  • From: "Orzel, Michal" <michal.orzel@xxxxxxx>
  • Date: Fri, 25 Sep 2026 13:16:54 +0200
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=epam.com smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0)
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=MtltmMtWWSnGRm6iaffboFNVp7fDDjazfKEdFjUABws=; b=DSwUno/d1zUWP7Yxf2YDmLJL92UQjsC/FXivvLa7m3FfgseYJNyUonpkbcHxEyHHQGG02HK13FJZ6FO75k23dg3CCTjsb0fodbvwJtTOMlXfyEWSHo+VbCK3t+7oBhJvEfRWnxrkN2KlnLKTSm1Ii4+CUNSOLXgMQRQP+rT6yJVXUnwfEQyPWrVaR4QJRQkpSevsoweRh/3Le17HkuLVOWXs3J8bBm/uLMIW2DhoDkcEq7JZYT3g30Og3m6JiWBP9EpVx+RwZAOF7Ikzg4SHycCch972Y7mmakBXRQTizhnaC7kee6vZq1ABtOcvN9AJcpigxyAj6kvRy1Wol54WvQ==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=HEt/WXf8HO7t9riEDXERtdfFB7QL8KdvGeQESBCR6txB/pik4wZbn802MkU4EMahhNXg3Eh/BpoFHh+p7GKc4jC48Zpsi2mq+bqyTY3P6dttwY7Ze8XgmBjLZnZVgtPPFkYcKi2+ZzK41LmRh5mspLiQ1tiSelO1+bSkuyQOT5NfIIqeDT63vYEa7QJzuICY4mUc6pSTjc1HlSxudfv3i53b5ztTduRz5vzBTmWbxyK9qcS2qRRyYtOLHoSQHUh+suaHj/zkWr60oaIgFmdGOOtHmvdhvbuDz83K9DY2Lkrza0luVB7Z+erfPaD+8HbtuB9R32SuwnCtcarSdAMHwg==
  • Authentication-results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=amd.com header.i="@amd.com" header.h="From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck"
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, "Stefano Stabellini" <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, "Bertrand Marquis" <bertrand.marquis@xxxxxxx>
  • Delivery-date: Fri, 25 Sep 2026 11:17:11 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>


On 25-Sep-26 00:55, Volodymyr Babchuk wrote:
> Hi Mykola,
> 
> Mykola Kvach <mykola_kvach@xxxxxxxx> writes:
> 
>> The allocated_irqs bitmap in the existing vGIC implementation stores eSPI
>> allocation bits immediately after the regular vIRQ bits.
>> vgic_reserve_virq() converts an eSPI INTID to this compressed bitmap index,
>> but vgic_free_virq() used the raw INTID.
>>
>> Freeing INTID 4096 therefore clears bit 4096 instead of the first eSPI bit.
>> This writes beyond allocated_irqs and leaves the intended eSPI bit set.
>> Valid eSPIs reach this path during DOMCTL bind failure cleanup and unbind,
>> and during vPL011 teardown.
>>
>> Add virq_to_idx(), the inverse of idx_to_virq(), and use it when reserving
>> and freeing vIRQs. Use vgic_is_valid_line() for the validity checks when
>> reserving and freeing vIRQs in both vGIC implementations.
>>
>> Fixes: bdde400c6e1b ("xen/arm: vgic: add resource management for extended 
>> SPIs")
>> Signed-off-by: Mykola Kvach <mykola_kvach@xxxxxxxx>
>> Reviewed-by: Michal Orzel <michal.orzel@xxxxxxx>
>> ---
>> Changes in v5:
>> - Add the vgic_is_valid_line() guard to vgic_free_virq() in the new
>>   vGIC implementation and use the same helper in vgic_reserve_virq().
>>
>> Changes in v4:
>> - Document the compressed bitmap layout with an ASCII diagram above the
>>   conversion helpers and refer to struct vgic_dist for the full layout.
>>
>> Changes in v3:
>> - Adapt virq_to_idx() to the configuration-neutral is_espi() helper.
>>
>> Changes in v2:
>> - Call is_espi() without a configuration guard.
>> ---
>>  xen/arch/arm/vgic.c      | 42 +++++++++++++++++++++++++++++-----------
>>  xen/arch/arm/vgic/vgic.c |  5 ++++-
>>  2 files changed, 35 insertions(+), 12 deletions(-)
>>
>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>> index 0ba13e18da..acded6a40f 100644
>> --- a/xen/arch/arm/vgic.c
>> +++ b/xen/arch/arm/vgic.c
>> @@ -25,6 +25,21 @@
>>  #include <asm/vgic.h>
>>  
>>  
>> +/*
>> + * The allocated_irqs bitmap is compressed: eSPI bits immediately follow
>> + * regular IRQ bits, skipping the gap in the INTID space.
>> + *
>> + *   +-----------+-----------+-------------------+-------------------+
>> + *   |   SGIs    |   PPIs    |       SPIs        |       eSPIs       |
>> + *   +-----------+-----------+-------------------+-------------------+
>> + *   0           16          32                  vgic_num_irqs(d)
>> + *
>> + * INTID ESPI_BASE_INTID maps to bitmap index vgic_num_irqs(d).
>> + * The following idx_to_virq() and virq_to_idx() convert between INTIDs
>> + * and bitmap indexes.
>> + *
>> + * See also the allocated_irqs comment in struct vgic_dist.
>> + */
>>  static inline unsigned int idx_to_virq(struct domain *d, unsigned int idx)
>>  {
>>      if ( idx >= vgic_num_irqs(d) )
>> @@ -33,6 +48,16 @@ static inline unsigned int idx_to_virq(struct domain *d, 
>> unsigned int idx)
>>      return idx;
>>  }
>>  
>> +static inline unsigned int virq_to_idx(struct domain *d, unsigned int virq)
>> +{
>> +    ASSERT(IS_ENABLED(CONFIG_GICV3_ESPI) || !is_espi(virq));
>> +
>> +    if ( IS_ENABLED(CONFIG_GICV3_ESPI) && is_espi(virq) )
>> +        return espi_intid_to_idx(virq) + vgic_num_irqs(d);
>> +
>> +    return virq;
>> +}
>> +
>>  bool vgic_is_valid_line(struct domain *d, unsigned int virq)
>>  {
>>  #ifdef CONFIG_GICV3_ESPI
>> @@ -854,19 +879,11 @@ bool vgic_emulate(struct cpu_user_regs *regs, union 
>> hsr hsr)
>>  
>>  bool vgic_reserve_virq(struct domain *d, unsigned int virq)
>>  {
>> -    unsigned int idx = virq;
>> -
>>      if ( !vgic_is_valid_line(d, virq) )
>>          return false;
>>  
>> -    if ( is_espi(virq) )
>> -    {
>> -        unsigned int num_regular_irqs = vgic_num_irqs(d);
>> -
>> -        idx = espi_intid_to_idx(virq) + num_regular_irqs;
>> -    }
>> -
>> -    return !test_and_set_bit(idx, d->arch.vgic.allocated_irqs);
>> +    return !test_and_set_bit(virq_to_idx(d, virq),
>> +                             d->arch.vgic.allocated_irqs);
>>  }
>>  
>>  int vgic_allocate_virq(struct domain *d, bool spi)
>> @@ -903,7 +920,10 @@ int vgic_allocate_virq(struct domain *d, bool spi)
>>  
>>  void vgic_free_virq(struct domain *d, unsigned int virq)
>>  {
>> -    clear_bit(virq, d->arch.vgic.allocated_irqs);
>> +    if ( !vgic_is_valid_line(d, virq) )
>> +        return;
> 
> I don't think that silently failing is a good idea. It needs an ASSERT()
> at least.
We cannot add ASSERT() here. Take a look at vpl011 init failure path on
vgic_reserve_virq() that is taken to domain_vpl011_deinit(). If you specify
nr_spis not enough to cover for UART IRQ, this can happen. I think I answered
this question some time ago.

~Michal




 


Rackspace

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