[Xen-devel,RFC,26/49] ARM: new VGIC: Implement vgic_vcpu_pending_irq

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

Commit Message

Andre Przywara Feb. 9, 2018, 2:39 p.m.
Tell Xen whether a particular VCPU has an IRQ that needs handling
in the guest. This is used to decide whether a VCPU is runnable.

This is based on Linux commit 90eee56c5f90, written by Eric Auger.

Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
---
 xen/arch/arm/vgic/vgic.c | 32 ++++++++++++++++++++++++++++++++
 1 file changed, 32 insertions(+)

Comments

Julien Grall Feb. 13, 2018, 4:35 p.m. | #1
Hi,

On 09/02/18 14:39, Andre Przywara wrote:
> Tell Xen whether a particular VCPU has an IRQ that needs handling
> in the guest. This is used to decide whether a VCPU is runnable.
> 
> This is based on Linux commit 90eee56c5f90, written by Eric Auger.
> 
> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
> ---
>   xen/arch/arm/vgic/vgic.c | 32 ++++++++++++++++++++++++++++++++
>   1 file changed, 32 insertions(+)
> 
> diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
> index f4f2a04a60..9e7fb1edcb 100644
> --- a/xen/arch/arm/vgic/vgic.c
> +++ b/xen/arch/arm/vgic/vgic.c
> @@ -646,6 +646,38 @@ void gic_inject(void)
>       vgic_restore_state(current);
>   }
>   
> +static int vgic_vcpu_pending_irq(struct vcpu *vcpu)
> +{
> +    struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
> +    struct vgic_irq *irq;
> +    bool pending = false;
> +    unsigned long flags;
> +
> +    if ( !vcpu->domain->arch.vgic.enabled )
> +        return false;
> +
> +    spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);
> +
> +    list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list)
> +    {
> +        spin_lock(&irq->irq_lock);
> +        pending = irq_is_pending(irq) && irq->enabled;
> +        spin_unlock(&irq->irq_lock);
> +
> +        if ( pending )
> +            break;
> +    }
> +
> +    spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);
> +
> +    return pending;
> +}
> +
> +int gic_events_need_delivery(void)

You probably want to rename that function or just expose 
vgic_vcpu_pending_irq().

Cheers,
Julien Grall Feb. 13, 2018, 4:36 p.m. | #2
On 13/02/18 16:35, Julien Grall wrote:
> Hi,
> 
> On 09/02/18 14:39, Andre Przywara wrote:
>> Tell Xen whether a particular VCPU has an IRQ that needs handling
>> in the guest. This is used to decide whether a VCPU is runnable.

I forgot to mention one thing. This is not the main usage of this 
function in Xen. That function will mostly be used to check whether we 
need to preempt an hypercall to run interrupt.

Please update the commit message accordingly.

>>
>> This is based on Linux commit 90eee56c5f90, written by Eric Auger.
>>
>> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
>> ---
>>   xen/arch/arm/vgic/vgic.c | 32 ++++++++++++++++++++++++++++++++
>>   1 file changed, 32 insertions(+)
>>
>> diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
>> index f4f2a04a60..9e7fb1edcb 100644
>> --- a/xen/arch/arm/vgic/vgic.c
>> +++ b/xen/arch/arm/vgic/vgic.c
>> @@ -646,6 +646,38 @@ void gic_inject(void)
>>       vgic_restore_state(current);
>>   }
>> +static int vgic_vcpu_pending_irq(struct vcpu *vcpu)
>> +{
>> +    struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
>> +    struct vgic_irq *irq;
>> +    bool pending = false;
>> +    unsigned long flags;
>> +
>> +    if ( !vcpu->domain->arch.vgic.enabled )
>> +        return false;
>> +
>> +    spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);
>> +
>> +    list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list)
>> +    {
>> +        spin_lock(&irq->irq_lock);
>> +        pending = irq_is_pending(irq) && irq->enabled;
>> +        spin_unlock(&irq->irq_lock);
>> +
>> +        if ( pending )
>> +            break;
>> +    }
>> +
>> +    spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);
>> +
>> +    return pending;
>> +}
>> +
>> +int gic_events_need_delivery(void)
> 
> You probably want to rename that function or just expose 
> vgic_vcpu_pending_irq().
> 
> Cheers,
>

Patch

diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
index f4f2a04a60..9e7fb1edcb 100644
--- a/xen/arch/arm/vgic/vgic.c
+++ b/xen/arch/arm/vgic/vgic.c
@@ -646,6 +646,38 @@  void gic_inject(void)
     vgic_restore_state(current);
 }
 
+static int vgic_vcpu_pending_irq(struct vcpu *vcpu)
+{
+    struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu;
+    struct vgic_irq *irq;
+    bool pending = false;
+    unsigned long flags;
+
+    if ( !vcpu->domain->arch.vgic.enabled )
+        return false;
+
+    spin_lock_irqsave(&vgic_cpu->ap_list_lock, flags);
+
+    list_for_each_entry(irq, &vgic_cpu->ap_list_head, ap_list)
+    {
+        spin_lock(&irq->irq_lock);
+        pending = irq_is_pending(irq) && irq->enabled;
+        spin_unlock(&irq->irq_lock);
+
+        if ( pending )
+            break;
+    }
+
+    spin_unlock_irqrestore(&vgic_cpu->ap_list_lock, flags);
+
+    return pending;
+}
+
+int gic_events_need_delivery(void)
+{
+    return vgic_vcpu_pending_irq(current);
+}
+
 /*
  * Local variables:
  * mode: C