[Xen-devel,v3,29/39] ARM: new VGIC: Handle virtual IRQ allocation/reservation

Message ID 20180321163235.12529-30-andre.przywara@linaro.org
State New
Headers show
Series
  • New VGIC(-v2) implementation
Related show

Commit Message

Andre Przywara March 21, 2018, 4:32 p.m.
To find an unused virtual IRQ number Xen uses a scheme to track used
virtual IRQs.
Implement this interface in the new VGIC to make the Xen core/arch code
happy.
This is actually somewhat VGIC agnostic, so is mostly a copy of the code
from the old VGIC. But it has to live in the VGIC files, so we can't
easily reuse the existing implementation.

Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
Acked-by: Julien Grall <julien.grall@arm.com>
---
 xen/arch/arm/vgic/vgic.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

Comments

Stefano Stabellini March 27, 2018, 10:38 p.m. | #1
On Wed, 21 Mar 2018, Andre Przywara wrote:
> To find an unused virtual IRQ number Xen uses a scheme to track used
> virtual IRQs.
> Implement this interface in the new VGIC to make the Xen core/arch code
> happy.
> This is actually somewhat VGIC agnostic, so is mostly a copy of the code
> from the old VGIC. But it has to live in the VGIC files, so we can't
> easily reuse the existing implementation.
> 
> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
> Acked-by: Julien Grall <julien.grall@arm.com>

These are exactly identical to the existing functions. I wonder why we
can't reuse them. In any case, I assume you know what you are doing from
the code integration point of view :-)

Acked-by: Stefano Stabellini <sstabellini@kernel.org>


> ---
>  xen/arch/arm/vgic/vgic.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
> 
> diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
> index 3d818a98ad..8aaad4bffa 100644
> --- a/xen/arch/arm/vgic/vgic.c
> +++ b/xen/arch/arm/vgic/vgic.c
> @@ -722,6 +722,50 @@ bool vgic_evtchn_irq_pending(struct vcpu *v)
>      return pending;
>  }
>  
> +bool vgic_reserve_virq(struct domain *d, unsigned int virq)
> +{
> +    if ( virq >= vgic_num_irqs(d) )
> +        return false;
> +
> +    return !test_and_set_bit(virq, d->arch.vgic.allocated_irqs);
> +}
> +
> +int vgic_allocate_virq(struct domain *d, bool spi)
> +{
> +    int first, end;
> +    unsigned int virq;
> +
> +    if ( !spi )
> +    {
> +        /* We only allocate PPIs. SGIs are all reserved */
> +        first = 16;
> +        end = 32;
> +    }
> +    else
> +    {
> +        first = 32;
> +        end = vgic_num_irqs(d);
> +    }
> +
> +    /*
> +     * There is no spinlock to protect allocated_irqs, therefore
> +     * test_and_set_bit may fail. If so retry it.
> +     */
> +    do
> +    {
> +        virq = find_next_zero_bit(d->arch.vgic.allocated_irqs, end, first);
> +        if ( virq >= end )
> +            return -1;
> +    } while ( test_and_set_bit(virq, d->arch.vgic.allocated_irqs) );
> +
> +    return virq;
> +}
> +
> +void vgic_free_virq(struct domain *d, unsigned int virq)
> +{
> +    clear_bit(virq, d->arch.vgic.allocated_irqs);
> +}
> +
>  struct irq_desc *vgic_get_hw_irq_desc(struct domain *d, struct vcpu *v,
>                                        unsigned int virq)
>  {
> -- 
> 2.14.1
>
Andre Przywara March 28, 2018, 9:17 a.m. | #2
Hi,

On 27/03/18 23:38, Stefano Stabellini wrote:
> On Wed, 21 Mar 2018, Andre Przywara wrote:
>> To find an unused virtual IRQ number Xen uses a scheme to track used
>> virtual IRQs.
>> Implement this interface in the new VGIC to make the Xen core/arch code
>> happy.
>> This is actually somewhat VGIC agnostic, so is mostly a copy of the code
>> from the old VGIC. But it has to live in the VGIC files, so we can't
>> easily reuse the existing implementation.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
>> Acked-by: Julien Grall <julien.grall@arm.com>
> 
> These are exactly identical to the existing functions. I wonder why we
> can't reuse them. In any case, I assume you know what you are doing from
> the code integration point of view :-)

They are, but there is no real shared VGIC code at the moment, and I
didn't want to introduce anything just for those simple functions,
especially with the prospect of the existing code going away anyway later.

> Acked-by: Stefano Stabellini <sstabellini@kernel.org>

Thanks!
Andre.

> 
> 
>> ---
>>  xen/arch/arm/vgic/vgic.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 44 insertions(+)
>>
>> diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
>> index 3d818a98ad..8aaad4bffa 100644
>> --- a/xen/arch/arm/vgic/vgic.c
>> +++ b/xen/arch/arm/vgic/vgic.c
>> @@ -722,6 +722,50 @@ bool vgic_evtchn_irq_pending(struct vcpu *v)
>>      return pending;
>>  }
>>  
>> +bool vgic_reserve_virq(struct domain *d, unsigned int virq)
>> +{
>> +    if ( virq >= vgic_num_irqs(d) )
>> +        return false;
>> +
>> +    return !test_and_set_bit(virq, d->arch.vgic.allocated_irqs);
>> +}
>> +
>> +int vgic_allocate_virq(struct domain *d, bool spi)
>> +{
>> +    int first, end;
>> +    unsigned int virq;
>> +
>> +    if ( !spi )
>> +    {
>> +        /* We only allocate PPIs. SGIs are all reserved */
>> +        first = 16;
>> +        end = 32;
>> +    }
>> +    else
>> +    {
>> +        first = 32;
>> +        end = vgic_num_irqs(d);
>> +    }
>> +
>> +    /*
>> +     * There is no spinlock to protect allocated_irqs, therefore
>> +     * test_and_set_bit may fail. If so retry it.
>> +     */
>> +    do
>> +    {
>> +        virq = find_next_zero_bit(d->arch.vgic.allocated_irqs, end, first);
>> +        if ( virq >= end )
>> +            return -1;
>> +    } while ( test_and_set_bit(virq, d->arch.vgic.allocated_irqs) );
>> +
>> +    return virq;
>> +}
>> +
>> +void vgic_free_virq(struct domain *d, unsigned int virq)
>> +{
>> +    clear_bit(virq, d->arch.vgic.allocated_irqs);
>> +}
>> +
>>  struct irq_desc *vgic_get_hw_irq_desc(struct domain *d, struct vcpu *v,
>>                                        unsigned int virq)
>>  {
>> -- 
>> 2.14.1
>>

Patch

diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
index 3d818a98ad..8aaad4bffa 100644
--- a/xen/arch/arm/vgic/vgic.c
+++ b/xen/arch/arm/vgic/vgic.c
@@ -722,6 +722,50 @@  bool vgic_evtchn_irq_pending(struct vcpu *v)
     return pending;
 }
 
+bool vgic_reserve_virq(struct domain *d, unsigned int virq)
+{
+    if ( virq >= vgic_num_irqs(d) )
+        return false;
+
+    return !test_and_set_bit(virq, d->arch.vgic.allocated_irqs);
+}
+
+int vgic_allocate_virq(struct domain *d, bool spi)
+{
+    int first, end;
+    unsigned int virq;
+
+    if ( !spi )
+    {
+        /* We only allocate PPIs. SGIs are all reserved */
+        first = 16;
+        end = 32;
+    }
+    else
+    {
+        first = 32;
+        end = vgic_num_irqs(d);
+    }
+
+    /*
+     * There is no spinlock to protect allocated_irqs, therefore
+     * test_and_set_bit may fail. If so retry it.
+     */
+    do
+    {
+        virq = find_next_zero_bit(d->arch.vgic.allocated_irqs, end, first);
+        if ( virq >= end )
+            return -1;
+    } while ( test_and_set_bit(virq, d->arch.vgic.allocated_irqs) );
+
+    return virq;
+}
+
+void vgic_free_virq(struct domain *d, unsigned int virq)
+{
+    clear_bit(virq, d->arch.vgic.allocated_irqs);
+}
+
 struct irq_desc *vgic_get_hw_irq_desc(struct domain *d, struct vcpu *v,
                                       unsigned int virq)
 {