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

Re: [Xen-devel] [RFC 05/19] xen/arm: Release IRQ routed to a domain when it's destroying



On Mon, 16 Jun 2014, Julien Grall wrote:
> Xen has to release IRQ routed to a domain in order to reuse later. Currently
> only SPIs can be routed to the guest so we only need to browse SPIs for a
> specific domain.
> 
> Futhermore, a guest can crash and let the IRQ in an incorrect state (i.e has
> not being EOIed). Add a function to reset a given IRQ to allow Xen route again
> the IRQ in the future.
> 
> Also, reset the desc->handler to no_irq_type. This will let you know if we
> did something wrong with the IRQ management.
> 
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
> ---
>  xen/arch/arm/gic.c        |   12 ++++++++++++
>  xen/arch/arm/irq.c        |    8 ++++++++
>  xen/arch/arm/vgic.c       |   10 ++++++++++
>  xen/include/asm-arm/gic.h |    3 +++
>  4 files changed, 33 insertions(+)
> 
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 11e53af..42fc3bc 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -928,6 +928,18 @@ int gicv_setup(struct domain *d)
>  
>  }
>  
> +/* The guest may not have EOIed the IRQ.
> + * Be sure to reset correctly the IRQ.
> + */
> +void gic_reset_guest_irq(struct irq_desc *desc)
> +{
> +    ASSERT(spin_is_locked(&desc->lock));
> +    ASSERT(desc->status & IRQ_GUEST);
> +
> +    if ( desc->status & IRQ_INPROGRESS )
> +        GICC[GICC_DIR] = desc->irq;
> +}

You should call gic_update_one_lr first, then check IRQ_INPROGRESS.
You should also call gic_remove_from_queues, remove the irq from the
inflight queue and clear the GIC_IRQ_GUEST_* status bits.


>  static void maintenance_interrupt(int irq, void *dev_id, struct 
> cpu_user_regs *regs)
>  {
>      /* 
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 4e51fee..e44a90f 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -274,7 +274,15 @@ void release_irq(unsigned int irq, const void *dev_id)
>      if ( !desc->action )
>      {
>          desc->handler->shutdown(desc);
> +
> +        if ( desc->status & IRQ_GUEST )
> +        {
> +            gic_reset_guest_irq(desc);
> +            desc->status &= ~IRQ_INPROGRESS;
> +        }
> +
>          desc->status &= ~IRQ_GUEST;
> +        desc->handler = &no_irq_type;
>      }
>  
>      spin_unlock_irqrestore(&desc->lock,flags);
> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
> index cb8df3a..e451324 100644
> --- a/xen/arch/arm/vgic.c
> +++ b/xen/arch/arm/vgic.c
> @@ -112,6 +112,16 @@ int domain_vgic_init(struct domain *d)
>  
>  void domain_vgic_free(struct domain *d)
>  {
> +    int i;
> +
> +    for ( i = NR_LOCAL_IRQS; i < d->arch.vgic.nr_lines; i++ )
> +    {
> +        struct irq_desc *desc = d->arch.vgic.pending_irqs[i].desc;
> +
> +        if ( desc )
> +            release_irq(desc->irq, d);
> +    }
> +
>      xfree(d->arch.vgic.shared_irqs);
>      xfree(d->arch.vgic.pending_irqs);
>  }
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index 6e7375c..841d845 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -228,6 +228,9 @@ int gic_irq_xlate(const u32 *intspec, unsigned int 
> intsize,
>                    unsigned int *out_hwirq, unsigned int *out_type);
>  void gic_clear_lrs(struct vcpu *v);
>  
> +/* Reset an IRQ passthrough to a guest */
> +void gic_reset_guest_irq(struct irq_desc *desc);
> +
>  #endif /* __ASSEMBLY__ */
>  #endif
>  
> -- 
> 1.7.10.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@xxxxxxxxxxxxx
> http://lists.xen.org/xen-devel
> 

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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