[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 3/5] xen/arm: disable the event optimization in the gic
On Fri, 2012-06-22 at 17:09 +0100, Stefano Stabellini wrote: > Currently we have an optimization in the GIC driver that allows us not > to request maintenance interrupts for Xen events. The basic idea is that > every time we are about to inject a new interrupt or event into a guest, > we check whether we can remove some old event irqs from one or more LRs. > We can do this because we know when a guest finishes processing event > notifications: it sets the evtchn_upcall_pending bit to 0. > > However it is unsafe: the guest resets evtchn_upcall_pending before > EOI'ing the event irq, therefore a small window of time exists when Xen > could jump in and remove the event irq from the LR register before the > guest has EOI'ed it. > > This is not a good practice according to the GIC manual. > Remove the optimization for now. > > Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> > --- > xen/arch/arm/gic.c | 42 ------------------------------------------ > 1 files changed, 0 insertions(+), 42 deletions(-) > > diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c > index 8190f84..c6cee4b 100644 > --- a/xen/arch/arm/gic.c > +++ b/xen/arch/arm/gic.c > @@ -37,7 +37,6 @@ > + (GIC_CR_OFFSET & 0xfff))) > #define GICH ((volatile uint32_t *) (FIXMAP_ADDR(FIXMAP_GICH) \ > + (GIC_HR_OFFSET & 0xfff))) > -static void events_maintenance(struct vcpu *v); > static void gic_restore_pending_irqs(struct vcpu *v); > > /* Global state */ > @@ -48,7 +47,6 @@ static struct { > unsigned int lines; > unsigned int cpus; > spinlock_t lock; > - uint64_t event_mask; > uint64_t lr_mask; > } gic; > > @@ -62,7 +60,6 @@ void gic_save_state(struct vcpu *v) > for ( i=0; i<nr_lrs; i++) > v->arch.gic_lr[i] = GICH[GICH_LR + i]; > v->arch.lr_mask = gic.lr_mask; > - v->arch.event_mask = gic.event_mask; > /* Disable until next VCPU scheduled */ > GICH[GICH_HCR] = 0; > isb(); > @@ -76,7 +73,6 @@ void gic_restore_state(struct vcpu *v) > return; > > gic.lr_mask = v->arch.lr_mask; > - gic.event_mask = v->arch.event_mask; > for ( i=0; i<nr_lrs; i++) > GICH[GICH_LR + i] = v->arch.gic_lr[i]; > GICH[GICH_HCR] = GICH_HCR_EN; > @@ -318,7 +314,6 @@ int __init gic_init(void) > gic_hyp_init(); > > gic.lr_mask = 0ULL; > - gic.event_mask = 0ULL; > > spin_unlock(&gic.lock); > > @@ -421,9 +416,6 @@ static inline void gic_set_lr(int lr, unsigned int > virtual_irq, > > BUG_ON(lr > nr_lrs); > > - if (virtual_irq == VGIC_IRQ_EVTCHN_CALLBACK && nr_lrs > 1) > - maintenance_int = 0; > - > GICH[GICH_LR + lr] = state | > maintenance_int | > ((priority >> 3) << GICH_LR_PRIORITY_SHIFT) | > @@ -436,11 +428,6 @@ void gic_set_guest_irq(struct vcpu *v, unsigned int > virtual_irq, > int i; > struct pending_irq *iter, *n; > > - if ( v->is_running ) > - { > - events_maintenance(v); > - } > - > spin_lock_irq(&gic.lock); > > if ( v->is_running && list_empty(&v->arch.vgic.lr_pending) ) > @@ -448,8 +435,6 @@ void gic_set_guest_irq(struct vcpu *v, unsigned int > virtual_irq, > i = find_first_zero_bit(&gic.lr_mask, nr_lrs); > if (i < nr_lrs) { > set_bit(i, &gic.lr_mask); > - if ( virtual_irq == VGIC_IRQ_EVTCHN_CALLBACK ) > - set_bit(i, &gic.event_mask); > gic_set_lr(i, virtual_irq, state, priority); > goto out; > } > @@ -494,8 +479,6 @@ static void gic_restore_pending_irqs(struct vcpu *v) > gic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority); > list_del_init(&p->lr_queue); > set_bit(i, &gic.lr_mask); > - if ( p->irq == VGIC_IRQ_EVTCHN_CALLBACK ) > - set_bit(i, &gic.event_mask); > } > > } > @@ -584,27 +567,6 @@ void gicv_setup(struct domain *d) > GIC_BASE_ADDRESS + GIC_VR_OFFSET); > } > > -static void events_maintenance(struct vcpu *v) > -{ > - int i = 0; > - int already_pending = test_bit(0, > - (unsigned long *)&vcpu_info(v, evtchn_upcall_pending)); > - > - if (!already_pending && gic.event_mask != 0) { > - spin_lock_irq(&gic.lock); > - while ((i = find_next_bit((const long unsigned int *) > &gic.event_mask, > - 64, i)) < 64) { > - > - GICH[GICH_LR + i] = 0; > - clear_bit(i, &gic.lr_mask); > - clear_bit(i, &gic.event_mask); > - > - i++; > - } > - spin_unlock_irq(&gic.lock); > - } > -} > - > static void maintenance_interrupt(int irq, void *dev_id, struct > cpu_user_regs *regs) > { > int i = 0, virq; > @@ -612,8 +574,6 @@ static void maintenance_interrupt(int irq, void *dev_id, > struct cpu_user_regs *r > struct vcpu *v = current; > uint64_t eisr = GICH[GICH_EISR0] | (((uint64_t) GICH[GICH_EISR1]) << 32); > > - events_maintenance(v); > - > while ((i = find_next_bit((const long unsigned int *) &eisr, > 64, i)) < 64) { > struct pending_irq *p; > @@ -629,8 +589,6 @@ static void maintenance_interrupt(int irq, void *dev_id, > struct cpu_user_regs *r > gic_set_lr(i, p->irq, GICH_LR_PENDING, p->priority); > list_del_init(&p->lr_queue); > set_bit(i, &gic.lr_mask); > - if ( p->irq == VGIC_IRQ_EVTCHN_CALLBACK ) > - set_bit(i, &gic.event_mask); > } else { > gic_inject_irq_stop(); > } _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |