|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |