[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [XenARM] XEN tools for ARM with Virtualization Extensions - Patch #2
On 15 July 2013 19:39, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> wrote: > On Fri, 12 Jul 2013, Eric Trudeau wrote: >> Patch #2 begins here: >> -------------------------------------------- >> >> From 924441c3eddb1765cb4fb0e94f6b62177195837d Mon Sep 17 00:00:00 2001 >> From: Eric Trudeau <etrudeau@xxxxxxxxxxxx> >> Date: Fri, 12 Jul 2013 14:54:24 -0400 >> Subject: [PATCH] xen/arm: Add support for 1:1 IRQ mapping into guest domains >> on ARM >> >> ARM guests will now have the ability to access 1:1 mapped IRQs. >> >> The irqs list in the domain configuration file is used. A SPI irq >> number must include the offset of 32. For example, if the device >> tree irq number is 76 for a SPI, then the irqs field in the dom.cfg >> file would be: >> irqs = [ 108 ] >> >> Only level-triggered IRQs are supported at this time. >> >> When an IRQ is released on destruction of the guest, any in-progress >> handlers are given at least a 100 msec to complete. > > Overall it's pretty good patch, but I don't like the busy loop. I admit > that it's an improvement over what we have today but release_irq wasn't > actually called by anybody until now. > > >> Signed-off-by: Eric Trudeau <etrudeau@xxxxxxxxxxxx> >> --- >> xen/arch/arm/domain.c | 15 ++++++++++++++ >> xen/arch/arm/gic.c | 29 ++++++++++++++++++-------- >> xen/arch/arm/physdev.c | 56 >> ++++++++++++++++++++++++++++++++++++++++++++++++-- >> xen/arch/arm/vgic.c | 5 +---- >> 4 files changed, 91 insertions(+), 14 deletions(-) >> >> diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c >> index 4c434a1..f15ff06 100644 >> --- a/xen/arch/arm/domain.c >> +++ b/xen/arch/arm/domain.c >> @@ -31,6 +31,8 @@ >> #include <asm/gic.h> >> #include "vtimer.h" >> #include "vpl011.h" >> +#include <xen/iocap.h> >> +#include <xen/irq.h> >> >> DEFINE_PER_CPU(struct vcpu *, curr_vcpu); >> >> @@ -513,8 +515,21 @@ fail: >> return rc; >> } >> >> +static int release_domain_irqs(struct domain *d) >> +{ >> + int i; >> + for (i = 0; i <= d->nr_pirqs; i++) { >> + if (irq_access_permitted(d, i)) { >> + release_irq(i); >> + } >> + } >> + return 0; >> +} >> + >> + >> void arch_domain_destroy(struct domain *d) >> { >> + release_domain_irqs(d); >> p2m_teardown(d); >> domain_vgic_free(d); >> domain_uart0_free(d); >> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c >> index ccce565..ed15ec3 100644 >> --- a/xen/arch/arm/gic.c >> +++ b/xen/arch/arm/gic.c >> @@ -30,6 +30,7 @@ >> #include <xen/device_tree.h> >> #include <asm/p2m.h> >> #include <asm/domain.h> >> +#include <xen/delay.h> >> >> #include <asm/gic.h> >> >> @@ -510,11 +511,12 @@ void gic_route_spis(void) >> } >> } >> >> -void __init release_irq(unsigned int irq) >> +void release_irq(unsigned int irq) >> { >> struct irq_desc *desc; >> unsigned long flags; >> - struct irqaction *action; >> + struct irqaction *action; >> + int inprogresschecks; >> >> desc = irq_to_desc(irq); >> >> @@ -530,8 +532,15 @@ void __init release_irq(unsigned int irq) >> >> spin_unlock_irqrestore(&desc->lock,flags); >> >> - /* Wait to make sure it's not being used on another CPU */ >> - do { smp_mb(); } while ( desc->status & IRQ_INPROGRESS ); >> + /* Wait a little while to make sure it's not being used on another CPU >> + * But not indefinitely, because a guest may have crashed */ >> + for (inprogresschecks = 0; (inprogresschecks < 100); >> inprogresschecks++) { >> + smp_mb(); >> + if ( desc->status & IRQ_INPROGRESS ) >> + mdelay(1); >> + else >> + break; >> + } > > Can we use a timer based watchdog instead to avoid the busy loop? > Looping for 100ms means wasting a considerable amount of time. > > >> if (action && action->free_on_release) >> xfree(action); >> @@ -708,6 +717,12 @@ int gic_route_irq_to_guest(struct domain *d, const >> struct dt_irq *irq, >> spin_lock_irqsave(&desc->lock, flags); >> spin_lock(&gic.lock); >> >> + if ( desc->action != NULL ) >> + { >> + retval = -EBUSY; >> + goto out; >> + } >> >> desc->handler = &gic_guest_irq_type; >> desc->status |= IRQ_GUEST; >> >> @@ -716,12 +731,10 @@ int gic_route_irq_to_guest(struct domain *d, const >> struct dt_irq *irq, >> gic_set_irq_properties(irq->irq, level, 1u << smp_processor_id(), 0xa0); >> >> retval = __setup_irq(desc, irq->irq, action); >> - if (retval) { >> - xfree(action); >> - goto out; >> - } >> >> out: >> + if (retval) >> + xfree(action); >> spin_unlock(&gic.lock); >> spin_unlock_irqrestore(&desc->lock, flags); >> return retval; >> diff --git a/xen/arch/arm/physdev.c b/xen/arch/arm/physdev.c >> index 61b4a18..8d76d11 100644 >> --- a/xen/arch/arm/physdev.c >> +++ b/xen/arch/arm/physdev.c >> @@ -9,12 +9,64 @@ >> #include <xen/lib.h> >> #include <xen/errno.h> >> #include <asm/hypercall.h> >> +#include <public/physdev.h> >> +#include <xen/guest_access.h> >> +#include <xen/irq.h> >> +#include <xen/sched.h> >> +#include <asm/gic.h> >> +#include <xsm/xsm.h> >> >> >> int do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg) >> { >> - printk("%s %d cmd=%d: not implemented yet\n", __func__, __LINE__, cmd); >> - return -ENOSYS; >> + int ret; >> + >> + switch ( cmd ) >> + { >> + case PHYSDEVOP_map_pirq: { >> + physdev_map_pirq_t map; >> + struct dt_irq irq; >> + struct domain *d; >> + >> + ret = -EFAULT; >> + if ( copy_from_guest(&map, arg, 1) != 0 ) >> + break; >> + >> + d = rcu_lock_domain_by_any_id(map.domid); >> + if ( d == NULL ) { >> + ret = -ESRCH; >> + break; >> + } >> + >> + ret = xsm_map_domain_pirq(XSM_TARGET, d); >> + >> + if (!ret && (map.pirq >= gic_number_lines())) >> + ret = -EINVAL; >> + >> + if (!ret) { >> + irq.irq = map.pirq; >> + irq.type = DT_IRQ_TYPE_LEVEL_MASK; > > You should add a comment here to explain why you are hardcoding level, > even if it's just a temporary limitation. > > >> + ret = gic_route_irq_to_guest(d, &irq, "GuestIRQ"); >> + if (!ret) > > Code style (even though I admit that we are not following it to the > letter ourselves). See CODING_STYLE. > > >> + dprintk(XENLOG_G_INFO, "dom%d: gic_route_irq_to_guest >> mapped in IRQ %d\n", >> + d->domain_id, irq.irq); >> + } >> + >> + rcu_unlock_domain(d); >> + >> + if (!ret && __copy_to_guest(arg, &map, 1) ) > > Shouldn't you be copying back the irq number written by > gic_route_irq_to_guest in map.irq? That's fine because pirq is used to return the IRQ number into the guest. Here, as we have 1:1 mapping, the value is same. But in the future, a physical IRQ will be mapped to a different number into the guest -- Julien Grall _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |