[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [XenARM] [PATCH] arm: support fewer LRs register than virtual irqs
On Tue, 14 Feb 2012, Jenny Smith wrote: > On Tue, Feb 14, 2012 at 1:07 PM, Stefano Stabellini > <stefano.stabellini@xxxxxxxxxxxxx> wrote: > > If the vgic needs to inject a virtual irq into the guest, but no free > > LR registers are available, add the irq to a list and return. > > Whenever an LR register becomes available we add the queued irq to it > > and remove it from the list. > > We use the gic lock to protect the list and the bitmask. > > > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> > > --- > > Âxen/arch/arm/gic.c      |  46 > > +++++++++++++++++++++++++++++++++++++---- > > Âxen/include/asm-arm/domain.h |  Â1 + > > Â2 files changed, 42 insertions(+), 5 deletions(-) > > > > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c > > index adc10bb..97c223c 100644 > > --- a/xen/arch/arm/gic.c > > +++ b/xen/arch/arm/gic.c > > @@ -25,6 +25,7 @@ > > Â#include <xen/sched.h> > > Â#include <xen/errno.h> > > Â#include <xen/softirq.h> > > +#include <xen/list.h> > > Â#include <asm/p2m.h> > > Â#include <asm/domain.h> > > > > @@ -45,6 +46,8 @@ static struct { > >   unsigned int lines; > >   unsigned int cpus; > >   spinlock_t lock; > > +  Âuint64_t lr_mask; > > +  Âstruct list_head lr_pending; > > Â} gic; > > > > Âirq_desc_t irq_desc[NR_IRQS]; > > @@ -247,6 +250,8 @@ static void __cpuinit gic_hyp_init(void) > > > >   GICH[GICH_HCR] = GICH_HCR_EN; > >   GICH[GICH_MISR] = GICH_MISR_EOI; > > +  Âgic.lr_mask = 0ULL; > > +  ÂINIT_LIST_HEAD(&gic.lr_pending); > > Â} > > > > Â/* Set up the GIC */ > > @@ -345,16 +350,35 @@ int __init setup_irq(unsigned int irq, struct > > irqaction *new) > >   return rc; > > Â} > > > > -void gic_set_guest_irq(unsigned int virtual_irq, > > +static inline void gic_set_lr(int lr, unsigned int virtual_irq, > >     unsigned int state, unsigned int priority) > > Â{ > > -  ÂBUG_ON(virtual_irq > nr_lrs); > > -  ÂGICH[GICH_LR + virtual_irq] = state | > > +  ÂBUG_ON(lr > nr_lrs); > > +  ÂGICH[GICH_LR + lr] = state | > >     GICH_LR_MAINTENANCE_IRQ | > >     ((priority >> 3) << GICH_LR_PRIORITY_SHIFT) | > >     ((virtual_irq & GICH_LR_VIRTUAL_MASK) << GICH_LR_VIRTUAL_SHIFT); > > Â} > > > > +void gic_set_guest_irq(unsigned int virtual_irq, > > +    Âunsigned int state, unsigned int priority) > > +{ > > +  Âint i; > > + > > +  Âspin_lock(&gic.lock); > > +  Âfor (i = 0; i < nr_lrs; i++) { > > +    Âif (!test_and_set_bit(i, &gic.lr_mask)) > > +    Â{ > > +      Âgic_set_lr(i, virtual_irq, state, priority); > > +      Âspin_unlock(&gic.lock); > > +      Âreturn; > > +    Â} > > +  Â} > > +  Âlist_add_tail(&irq_to_pending(current, virtual_irq)->lr_link, > > &gic.lr_pending); > > +  Âspin_unlock(&gic.lock); > > +  Âreturn; > > +} > > + > > Âvoid gic_inject_irq_start(void) > > Â{ > >   uint32_t hcr; > > @@ -435,13 +459,26 @@ static void maintenance_interrupt(int irq, void > > *dev_id, struct cpu_user_regs *r > >   uint32_t lr; > >   uint64_t eisr = GICH[GICH_EISR0] | (((uint64_t) GICH[GICH_EISR1]) << > > 32); > > > > -  Âfor ( i = 0; i < 64; i++ ) { > > +  Âfor ( i = 0; i < nr_lrs; i++ ) { > >     if ( eisr & ((uint64_t)1 << i) ) { > >       struct pending_irq *p; > > > > +      Âspin_lock(&gic.lock); > >       lr = GICH[GICH_LR + i]; > >       virq = lr & GICH_LR_VIRTUAL_MASK; > >       GICH[GICH_LR + i] = 0; > > +      Âclear_bit(i, &gic.lr_mask); > > + > > +      Âif ( !list_empty(gic.lr_pending.next) ) { > > +        Âp = list_entry(gic.lr_pending.next, typeof(*p), lr_link); > > +        Âgic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority); > > +        Âlist_del(&p->lr_link); > > +        ÂINIT_LIST_HEAD(&p->lr_link); > > +        Âset_bit(i, &gic.lr_mask); > > +      Â} else { > > +        Âgic_inject_irq_stop(); > > +      Â} > > +      Âspin_unlock(&gic.lock); > > > >       spin_lock(¤t->arch.vgic.lock); > >       p = irq_to_pending(current, virq); > > @@ -449,7 +486,6 @@ static void maintenance_interrupt(int irq, void > > *dev_id, struct cpu_user_regs *r > >         p->desc->status &= ~IRQ_INPROGRESS; > >         GICC[GICC_DIR] = virq; > >       } > > -      Âgic_inject_irq_stop(); > >       list_del(&p->link); > >       INIT_LIST_HEAD(&p->link); > >       cpu_raise_softirq(current->processor, VGIC_SOFTIRQ); > > diff --git a/xen/include/asm-arm/domain.h b/xen/include/asm-arm/domain.h > > index 3372d14..75095ff 100644 > > --- a/xen/include/asm-arm/domain.h > > +++ b/xen/include/asm-arm/domain.h > > @@ -21,6 +21,7 @@ struct pending_irq > >   struct irq_desc *desc; /* only set it the irq corresponds to a physical > > irq */ > >   uint8_t priority; > >   struct list_head link; > > +  Âstruct list_head lr_link; > > Â}; > > > > Âstruct arch_domain > > -- > > 1.7.8.3 > > > > The patch fixes the BUG() call from gic_set_guest_irq() but now I'm > getting another guest data abort error. > I used the arm-tools-2 branch -> the GIC code looks slightly > different? Which branch should I be using? I would ignore the tools branch for the moment, that is only useful to upstream tool patches at the moment. Just switch to xen-unstable that has all the patches that you need to boot xen and linux on the Cortex-A15 emulator. _______________________________________________ Xen-arm mailing list Xen-arm@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/mailman/listinfo/xen-arm
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |