diff mbox

[Xen-devel,v4,04/10] xen/arm: set GICH_HCR_UIE if all the LRs are in use

Message ID 1395232325-19226-4-git-send-email-stefano.stabellini@eu.citrix.com
State New
Headers show

Commit Message

Stefano Stabellini March 19, 2014, 12:31 p.m. UTC
On return to guest, if there are no free LRs and we still have more
interrupt to inject, set GICH_HCR_UIE so that we are going to receive a
maintenance interrupt when no pending interrupts are present in the LR
registers.
The maintenance interrupt handler won't do anything anymore, but
receiving the interrupt is going to cause gic_inject to be called on
return to guest that is going to clear the old LRs and inject new
interrupts.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

---

Changes in v2:
- disable/enable the GICH_HCR_UIE bit in GICH_HCR;
- only enable GICH_HCR_UIE if this_cpu(lr_mask) == ((1 << nr_lrs) - 1).
---
 xen/arch/arm/gic.c |    6 ++++++
 1 file changed, 6 insertions(+)

Comments

Julien Grall March 19, 2014, 1:49 p.m. UTC | #1
On 03/19/2014 12:31 PM, Stefano Stabellini wrote:
> On return to guest, if there are no free LRs and we still have more
> interrupt to inject, set GICH_HCR_UIE so that we are going to receive a
> maintenance interrupt when no pending interrupts are present in the LR
> registers.
> The maintenance interrupt handler won't do anything anymore, but
> receiving the interrupt is going to cause gic_inject to be called on
> return to guest that is going to clear the old LRs and inject new
> interrupts.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Acked-by: Julien Grall <julien.grall@linaro.org>
Ian Campbell March 21, 2014, 1:06 p.m. UTC | #2
On Wed, 2014-03-19 at 12:31 +0000, Stefano Stabellini wrote:
> On return to guest, if there are no free LRs and we still have more
> interrupt to inject, set GICH_HCR_UIE so that we are going to receive a
> maintenance interrupt when no pending interrupts are present in the LR
> registers.
> The maintenance interrupt handler won't do anything anymore, but
> receiving the interrupt is going to cause gic_inject to be called on
> return to guest that is going to clear the old LRs and inject new
> interrupts.

Can you add a comment to the (now dummy) interrupt handler explaining
this please.

> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> ---
> 
> Changes in v2:
> - disable/enable the GICH_HCR_UIE bit in GICH_HCR;
> - only enable GICH_HCR_UIE if this_cpu(lr_mask) == ((1 << nr_lrs) - 1).
> ---
>  xen/arch/arm/gic.c |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 32d3bea..d445e8b 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -790,6 +790,12 @@ void gic_inject(void)
>          vgic_vcpu_inject_irq(current, current->domain->arch.evtchn_irq);
>  
>      gic_restore_pending_irqs(current);
> +
> +    if ( !list_empty(&current->arch.vgic.lr_pending) &&
> +         this_cpu(lr_mask) == ((1 << nr_lrs) - 1) )

Helper like lr_all_full?

> +        GICH[GICH_HCR] |= GICH_HCR_UIE;
> +    else
> +        GICH[GICH_HCR] &= ~GICH_HCR_UIE;
>  }
>  
>  int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,
Ian Campbell March 21, 2014, 1:07 p.m. UTC | #3
On Wed, 2014-03-19 at 12:31 +0000, Stefano Stabellini wrote:
> On return to guest, if there are no free LRs and we still have more
> interrupt to inject, set GICH_HCR_UIE so that we are going to receive a
> maintenance interrupt when no pending interrupts are present in the LR
> registers.

Should this go before the previous patch? Otherwise how to things work
between #3 and #4? This would be harmless to go in first I think, apart
from some spurious maintenance interrupts?

> The maintenance interrupt handler won't do anything anymore, but
> receiving the interrupt is going to cause gic_inject to be called on
> return to guest that is going to clear the old LRs and inject new
> interrupts.
> 
> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> ---
> 
> Changes in v2:
> - disable/enable the GICH_HCR_UIE bit in GICH_HCR;
> - only enable GICH_HCR_UIE if this_cpu(lr_mask) == ((1 << nr_lrs) - 1).
> ---
>  xen/arch/arm/gic.c |    6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 32d3bea..d445e8b 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -790,6 +790,12 @@ void gic_inject(void)
>          vgic_vcpu_inject_irq(current, current->domain->arch.evtchn_irq);
>  
>      gic_restore_pending_irqs(current);
> +
> +    if ( !list_empty(&current->arch.vgic.lr_pending) &&
> +         this_cpu(lr_mask) == ((1 << nr_lrs) - 1) )
> +        GICH[GICH_HCR] |= GICH_HCR_UIE;
> +    else
> +        GICH[GICH_HCR] &= ~GICH_HCR_UIE;
>  }
>  
>  int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,
Stefano Stabellini March 21, 2014, 4:03 p.m. UTC | #4
On Fri, 21 Mar 2014, Ian Campbell wrote:
> On Wed, 2014-03-19 at 12:31 +0000, Stefano Stabellini wrote:
> > On return to guest, if there are no free LRs and we still have more
> > interrupt to inject, set GICH_HCR_UIE so that we are going to receive a
> > maintenance interrupt when no pending interrupts are present in the LR
> > registers.
> > The maintenance interrupt handler won't do anything anymore, but
> > receiving the interrupt is going to cause gic_inject to be called on
> > return to guest that is going to clear the old LRs and inject new
> > interrupts.
> 
> Can you add a comment to the (now dummy) interrupt handler explaining
> this please.

Sure


> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - disable/enable the GICH_HCR_UIE bit in GICH_HCR;
> > - only enable GICH_HCR_UIE if this_cpu(lr_mask) == ((1 << nr_lrs) - 1).
> > ---
> >  xen/arch/arm/gic.c |    6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> > index 32d3bea..d445e8b 100644
> > --- a/xen/arch/arm/gic.c
> > +++ b/xen/arch/arm/gic.c
> > @@ -790,6 +790,12 @@ void gic_inject(void)
> >          vgic_vcpu_inject_irq(current, current->domain->arch.evtchn_irq);
> >  
> >      gic_restore_pending_irqs(current);
> > +
> > +    if ( !list_empty(&current->arch.vgic.lr_pending) &&
> > +         this_cpu(lr_mask) == ((1 << nr_lrs) - 1) )
> 
> Helper like lr_all_full?

Good idea


> > +        GICH[GICH_HCR] |= GICH_HCR_UIE;
> > +    else
> > +        GICH[GICH_HCR] &= ~GICH_HCR_UIE;
> >  }
> >  
> >  int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,
> 
>
Stefano Stabellini March 21, 2014, 4:05 p.m. UTC | #5
On Fri, 21 Mar 2014, Ian Campbell wrote:
> On Wed, 2014-03-19 at 12:31 +0000, Stefano Stabellini wrote:
> > On return to guest, if there are no free LRs and we still have more
> > interrupt to inject, set GICH_HCR_UIE so that we are going to receive a
> > maintenance interrupt when no pending interrupts are present in the LR
> > registers.
> 
> Should this go before the previous patch? Otherwise how to things work
> between #3 and #4? This would be harmless to go in first I think, apart
> from some spurious maintenance interrupts?

In practice you always receive timer interrupts so things would work
even without this patch.  However like you say moving this patch earlier
is harmless, so I'll do it.


> > The maintenance interrupt handler won't do anything anymore, but
> > receiving the interrupt is going to cause gic_inject to be called on
> > return to guest that is going to clear the old LRs and inject new
> > interrupts.
> > 
> > Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> > 
> > ---
> > 
> > Changes in v2:
> > - disable/enable the GICH_HCR_UIE bit in GICH_HCR;
> > - only enable GICH_HCR_UIE if this_cpu(lr_mask) == ((1 << nr_lrs) - 1).
> > ---
> >  xen/arch/arm/gic.c |    6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> > index 32d3bea..d445e8b 100644
> > --- a/xen/arch/arm/gic.c
> > +++ b/xen/arch/arm/gic.c
> > @@ -790,6 +790,12 @@ void gic_inject(void)
> >          vgic_vcpu_inject_irq(current, current->domain->arch.evtchn_irq);
> >  
> >      gic_restore_pending_irqs(current);
> > +
> > +    if ( !list_empty(&current->arch.vgic.lr_pending) &&
> > +         this_cpu(lr_mask) == ((1 << nr_lrs) - 1) )
> > +        GICH[GICH_HCR] |= GICH_HCR_UIE;
> > +    else
> > +        GICH[GICH_HCR] &= ~GICH_HCR_UIE;
> >  }
> >  
> >  int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,
> 
>
diff mbox

Patch

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 32d3bea..d445e8b 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -790,6 +790,12 @@  void gic_inject(void)
         vgic_vcpu_inject_irq(current, current->domain->arch.evtchn_irq);
 
     gic_restore_pending_irqs(current);
+
+    if ( !list_empty(&current->arch.vgic.lr_pending) &&
+         this_cpu(lr_mask) == ((1 << nr_lrs) - 1) )
+        GICH[GICH_HCR] |= GICH_HCR_UIE;
+    else
+        GICH[GICH_HCR] &= ~GICH_HCR_UIE;
 }
 
 int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,