diff mbox series

[Xen-devel,46/57] ARM: new VGIC: Add event channel IRQ handling

Message ID 20180305160415.16760-47-andre.przywara@linaro.org
State Superseded
Headers show
Series New VGIC(-v2) implementation | expand

Commit Message

Andre Przywara March 5, 2018, 4:04 p.m. UTC
The Xen core/arch code relies on two abstracted functions to inject an
event channel IRQ and to query its pending state.
Implement those to query the state of the new VGIC implementation.

Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
---
Changelog RFC ... v1:
- add locking

 xen/arch/arm/vgic/vgic.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

Comments

Julien Grall March 9, 2018, 5:40 p.m. UTC | #1
Hi Andre,

On 05/03/18 16:04, Andre Przywara wrote:
> The Xen core/arch code relies on two abstracted functions to inject an
> event channel IRQ and to query its pending state.
> Implement those to query the state of the new VGIC implementation.

The code looks good, but I am wondering why we ever need to call 
vgic_evtchn_irq_pending in local_event_needs_delivery_nomask.

After all, the event channel is an interrupt. So it should already get 
caught by vgic_pending_irq(). If not, then there are no point to wake up 
the vCPU for nothing (it will not get handled). Stefano, do you have 
insight why the current implementation?

Anyway, the code as it is fine so:

Acked-by: Julien Grall <julien.grall@arm.com>

Cheers,

> 
> Signed-off-by: Andre Przywara <andre.przywara@linaro.org>
> ---
> Changelog RFC ... v1:
> - add locking
> 
>   xen/arch/arm/vgic/vgic.c | 23 +++++++++++++++++++++++
>   1 file changed, 23 insertions(+)
> 
> diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
> index 5bbf55da21..0bf257c865 100644
> --- a/xen/arch/arm/vgic/vgic.c
> +++ b/xen/arch/arm/vgic/vgic.c
> @@ -698,6 +698,29 @@ void vgic_kick_vcpus(struct domain *d)
>       }
>   }
>   
> +void arch_evtchn_inject(struct vcpu *v)
> +{
> +    vgic_inject_irq(v->domain, v, v->domain->arch.evtchn_irq, true);
> +}
> +
> +bool vgic_evtchn_irq_pending(struct vcpu *v)
> +{
> +    struct vgic_irq *irq;
> +    unsigned long flags;
> +    bool pending;
> +
> +    /* Does not work for LPIs. */
> +    ASSERT(!is_lpi(v->domain->arch.evtchn_irq));
> +
> +    irq = vgic_get_irq(v->domain, v, v->domain->arch.evtchn_irq);
> +    spin_lock_irqsave(&irq->irq_lock, flags);
> +    pending = irq_is_pending(irq);
> +    spin_unlock_irqrestore(&irq->irq_lock, flags);
> +    vgic_put_irq(v->domain, irq);
> +
> +    return pending;
> +}
> +
>   struct irq_desc *vgic_get_hw_irq_desc(struct domain *d, struct vcpu *v,
>                                         unsigned int virq)
>   {
>
diff mbox series

Patch

diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c
index 5bbf55da21..0bf257c865 100644
--- a/xen/arch/arm/vgic/vgic.c
+++ b/xen/arch/arm/vgic/vgic.c
@@ -698,6 +698,29 @@  void vgic_kick_vcpus(struct domain *d)
     }
 }
 
+void arch_evtchn_inject(struct vcpu *v)
+{
+    vgic_inject_irq(v->domain, v, v->domain->arch.evtchn_irq, true);
+}
+
+bool vgic_evtchn_irq_pending(struct vcpu *v)
+{
+    struct vgic_irq *irq;
+    unsigned long flags;
+    bool pending;
+
+    /* Does not work for LPIs. */
+    ASSERT(!is_lpi(v->domain->arch.evtchn_irq));
+
+    irq = vgic_get_irq(v->domain, v, v->domain->arch.evtchn_irq);
+    spin_lock_irqsave(&irq->irq_lock, flags);
+    pending = irq_is_pending(irq);
+    spin_unlock_irqrestore(&irq->irq_lock, flags);
+    vgic_put_irq(v->domain, irq);
+
+    return pending;
+}
+
 struct irq_desc *vgic_get_hw_irq_desc(struct domain *d, struct vcpu *v,
                                       unsigned int virq)
 {