|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH v2 06/21] xen/arm: Allow virq != irq
On Thu, 31 Jul 2014, Julien Grall wrote:
> Actually Xen is assuming that the virtual IRQ will always be equal the IRQ.
>
> Modify, route_guest_irq to take the virtual IRQ in parameter and let Xen
> assigned a different IRQ number. Also store the vIRQ in the desc action to
> retrieve easily the IRQ target when we need to inject the interrupt.
>
> As DOM0 will get most the device, the vIRQ is equal to the IRQ.
>
> Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
>
> ---
> Changes in v2:
> - Patch added
> ---
> xen/arch/arm/domain_build.c | 2 +-
> xen/arch/arm/gic.c | 5 +++--
> xen/arch/arm/irq.c | 47
> +++++++++++++++++++++++++++++++------------
> xen/include/asm-arm/gic.h | 3 ++-
> xen/include/asm-arm/irq.h | 4 ++--
> 5 files changed, 42 insertions(+), 19 deletions(-)
>
> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
> index 47d114f..0dfe223 100644
> --- a/xen/arch/arm/domain_build.c
> +++ b/xen/arch/arm/domain_build.c
> @@ -1009,7 +1009,7 @@ static int handle_device(struct domain *d, struct
> dt_device_node *dev)
>
> if ( available )
> {
> - res = route_irq_to_guest(d, irq, dt_node_name(dev));
> + res = route_irq_to_guest(d, irq, irq, dt_node_name(dev));
> if ( res )
> {
> printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
> index 6611ba0..8ef8764 100644
> --- a/xen/arch/arm/gic.c
> +++ b/xen/arch/arm/gic.c
> @@ -126,7 +126,8 @@ void gic_route_irq_to_xen(struct irq_desc *desc, const
> cpumask_t *cpu_mask,
> /* Program the GIC to route an interrupt to a guest
> * - desc.lock must be held
> */
> -void gic_route_irq_to_guest(struct domain *d, struct irq_desc *desc,
> +void gic_route_irq_to_guest(struct domain *d, unsigned int virq,
> + struct irq_desc *desc,
> const cpumask_t *cpu_mask, unsigned int priority)
> {
> struct pending_irq *p;
> @@ -139,7 +140,7 @@ void gic_route_irq_to_guest(struct domain *d, struct
> irq_desc *desc,
>
> /* Use vcpu0 to retrieve the pending_irq struct. Given that we only
> * route SPIs to guests, it doesn't make any difference. */
> - p = irq_to_pending(d->vcpu[0], desc->irq);
> + p = irq_to_pending(d->vcpu[0], virq);
> p->desc = desc;
> }
>
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 25ecf1d..830832c 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -31,6 +31,13 @@
> static unsigned int local_irqs_type[NR_LOCAL_IRQS];
> static DEFINE_SPINLOCK(local_irqs_type_lock);
>
> +/* Describe an IRQ assigned to a guest */
> +struct irq_guest
> +{
> + struct domain *d;
> + unsigned int virq;
> +};
> +
> static void ack_none(struct irq_desc *irq)
> {
> printk("unexpected IRQ trap at irq %02x\n", irq->irq);
> @@ -122,18 +129,20 @@ void __cpuinit init_secondary_IRQ(void)
> BUG_ON(init_local_irq_data() < 0);
> }
>
> -static inline struct domain *irq_get_domain(struct irq_desc *desc)
> +static inline struct irq_guest *irq_get_guest_info(struct irq_desc *desc)
> {
> ASSERT(spin_is_locked(&desc->lock));
> -
> - if ( !test_bit(_IRQ_GUEST, &desc->status) )
> - return dom_xen;
> -
> + ASSERT(test_bit(_IRQ_GUEST, &desc->status));
> ASSERT(desc->action != NULL);
>
> return desc->action->dev_id;
> }
>
> +static inline struct domain *irq_get_domain(struct irq_desc *desc)
> +{
> + return irq_get_guest_info(desc)->d;
> +}
> +
> void irq_set_affinity(struct irq_desc *desc, const cpumask_t *cpu_mask)
> {
> if ( desc != NULL )
> @@ -197,7 +206,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq,
> int is_fiq)
>
> if ( test_bit(_IRQ_GUEST, &desc->status) )
> {
> - struct domain *d = irq_get_domain(desc);
> + struct irq_guest *info = irq_get_guest_info(desc);
>
> desc->handler->end(desc);
>
> @@ -206,7 +215,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq,
> int is_fiq)
>
> /* the irq cannot be a PPI, we only support delivery of SPIs to
> * guests */
> - vgic_vcpu_inject_spi(d, irq);
> + vgic_vcpu_inject_spi(info->d, info->virq);
> goto out_no_end;
> }
>
> @@ -370,19 +379,30 @@ err:
> return rc;
> }
>
> -int route_irq_to_guest(struct domain *d, unsigned int irq,
> - const char * devname)
> +int route_irq_to_guest(struct domain *d, unsigned int virq,
> + unsigned int irq, const char * devname)
> {
> struct irqaction *action;
> - struct irq_desc *desc = irq_to_desc(irq);
> + struct irq_guest *info;
> + struct irq_desc *desc;
> unsigned long flags;
> int retval = 0;
>
> action = xmalloc(struct irqaction);
> - if (!action)
> + if ( !action )
> + return -ENOMEM;
> +
> + info = xmalloc(struct irq_guest);
> + if ( !info )
> + {
> + xfree(action);
> return -ENOMEM;
> + }
Rather than xmalloc'ing another struct and storing the pointer in
dev_id, maybe we could simply expand struct arch_irq_desc?
> + info->d = d;
> + info->virq = virq;
>
> - action->dev_id = d;
> + action->dev_id = info;
> action->name = devname;
> action->free_on_release = 1;
>
> @@ -413,7 +433,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq,
> if ( retval )
> goto out;
>
> - gic_route_irq_to_guest(d, desc, cpumask_of(smp_processor_id()),
> + gic_route_irq_to_guest(d, virq, desc, cpumask_of(smp_processor_id()),
> GIC_PRI_IRQ);
> spin_unlock_irqrestore(&desc->lock, flags);
> return 0;
> @@ -421,6 +441,7 @@ int route_irq_to_guest(struct domain *d, unsigned int irq,
> out:
> spin_unlock_irqrestore(&desc->lock, flags);
> xfree(action);
> + xfree(info);
>
> return retval;
> }
> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
> index a0c07bf..89816cd 100644
> --- a/xen/include/asm-arm/gic.h
> +++ b/xen/include/asm-arm/gic.h
> @@ -196,7 +196,8 @@ extern enum gic_version gic_hw_version(void);
> /* Program the GIC to route an interrupt */
> extern void gic_route_irq_to_xen(struct irq_desc *desc, const cpumask_t
> *cpu_mask,
> unsigned int priority);
> -extern void gic_route_irq_to_guest(struct domain *, struct irq_desc *desc,
> +extern void gic_route_irq_to_guest(struct domain *, unsigned int virq,
> + struct irq_desc *desc,
> const cpumask_t *cpu_mask,
> unsigned int priority);
>
> diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
> index e877334..9bc3492 100644
> --- a/xen/include/asm-arm/irq.h
> +++ b/xen/include/asm-arm/irq.h
> @@ -40,8 +40,8 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq,
> int is_fiq);
> void init_IRQ(void);
> void init_secondary_IRQ(void);
>
> -int route_irq_to_guest(struct domain *d, unsigned int irq,
> - const char *devname);
> +int route_irq_to_guest(struct domain *d, unsigned int virq,
> + unsigned int irq, const char *devname);
> void arch_move_irqs(struct vcpu *v);
>
> /* Set IRQ type for an SPI */
> --
> 1.7.10.4
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |