# HG changeset patch # User Keir Fraser # Date 1222349872 -3600 # Node ID e1507b441be45d6d1cac25a196b53beff857a083 # Parent ddf62f69611127319e3c756b9fbc82e29f59ef36 x86: Clean up and fix 18539:31f09a5e24cf8 Signed-off-by: Keir Fraser Index: xen-3.3.1-testing/xen/arch/ia64/xen/irq.c =================================================================== --- xen-3.3.1-testing.orig/xen/arch/ia64/xen/irq.c +++ xen-3.3.1-testing/xen/arch/ia64/xen/irq.c @@ -459,12 +459,12 @@ int pirq_guest_bind(struct vcpu *v, int return rc; } -int pirq_guest_unbind(struct domain *d, int irq) +void pirq_guest_unbind(struct domain *d, int irq) { irq_desc_t *desc = &irq_desc[irq]; irq_guest_action_t *action; unsigned long flags; - int i, rc = 0; + int i; spin_lock_irqsave(&desc->lock, flags); @@ -472,11 +472,7 @@ int pirq_guest_unbind(struct domain *d, for ( i = 0; (i < action->nr_guests) && (action->guest[i] != d); i++ ) continue; - if ( i == action->nr_guests ) - { - rc = -EINVAL; - goto out; - } + BUG_ON(i == action->nr_guests); memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1); action->nr_guests--; @@ -496,9 +492,7 @@ int pirq_guest_unbind(struct domain *d, desc->handler->shutdown(irq); } - out: spin_unlock_irqrestore(&desc->lock, flags); - return rc; } void Index: xen-3.3.1-testing/xen/arch/x86/irq.c =================================================================== --- xen-3.3.1-testing.orig/xen/arch/x86/irq.c +++ xen-3.3.1-testing/xen/arch/x86/irq.c @@ -510,12 +510,12 @@ int pirq_guest_bind(struct vcpu *v, int irq_guest_action_t *action, *newaction = NULL; int rc = 0; cpumask_t cpumask = CPU_MASK_NONE; - unsigned long flags; WARN_ON(!spin_is_locked(&v->domain->evtchn_lock)); + BUG_ON(!local_irq_is_enabled()); retry: - desc = domain_spin_lock_irq_desc(v->domain, irq, &flags); + desc = domain_spin_lock_irq_desc(v->domain, irq, NULL); if ( desc == NULL ) return -EINVAL; @@ -535,7 +535,7 @@ int pirq_guest_bind(struct vcpu *v, int if ( newaction == NULL ) { - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irq(&desc->lock); if ( (newaction = xmalloc(irq_guest_action_t)) != NULL ) goto retry; gdprintk(XENLOG_INFO, @@ -581,7 +581,7 @@ int pirq_guest_bind(struct vcpu *v, int */ ASSERT(action->ack_type == ACKTYPE_EOI); ASSERT(desc->status & IRQ_DISABLED); - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irq(&desc->lock); cpu_relax(); goto retry; } @@ -597,45 +597,26 @@ int pirq_guest_bind(struct vcpu *v, int action->guest[action->nr_guests++] = v->domain; unlock_out: - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irq(&desc->lock); out: - if ( newaction != NULL ) - xfree(newaction); return rc; } -int pirq_guest_unbind(struct domain *d, int irq) +static void __pirq_guest_unbind(struct domain *d, int irq, irq_desc_t *desc) { - int vector; - irq_desc_t *desc; + unsigned int vector; irq_guest_action_t *action; cpumask_t cpu_eoi_map; - int i, rc = 0; - - WARN_ON(!spin_is_locked(&d->evtchn_lock)); + int i; - desc = domain_spin_lock_irq_desc(d, irq, &flags); - if ( unlikely(desc == NULL) ) - { - if ( !msi_enable || (vector = -domain_irq_to_vector(d, irq)) == 0 ) - return -EINVAL; - BUG_ON(vector <= 0); - desc = &irq_desc[vector]; - spin_lock_irqsave(&desc->lock, flags); - d->arch.pirq_vector[irq] = d->arch.vector_pirq[vector] = 0; - goto out; - } + BUG_ON(!(desc->status & IRQ_GUEST)); action = (irq_guest_action_t *)desc->action; vector = desc - irq_desc; for ( i = 0; (i < action->nr_guests) && (action->guest[i] != d); i++ ) continue; - if ( i == action->nr_guests ) - { - rc = -EINVAL; - goto out; - } + BUG_ON(i == action->nr_guests); memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1); action->nr_guests--; @@ -653,7 +634,7 @@ int pirq_guest_unbind(struct domain *d, (action->nr_guests != 0) ) { cpu_eoi_map = action->cpu_eoi_map; - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irq(&desc->lock); on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 0); spin_lock_irq(&desc->lock); } @@ -669,7 +650,7 @@ int pirq_guest_unbind(struct domain *d, if ( action->nr_guests != 0 ) { action = NULL; - goto out; + return; } BUG_ON(action->in_flight != 0); @@ -690,7 +671,7 @@ int pirq_guest_unbind(struct domain *d, if ( !cpus_empty(cpu_eoi_map) ) { BUG_ON(action->ack_type != ACKTYPE_EOI); - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irq(&desc->lock); on_selected_cpus(cpu_eoi_map, set_eoi_ready, desc, 1, 1); spin_lock_irq(&desc->lock); } @@ -702,10 +683,63 @@ int pirq_guest_unbind(struct domain *d, desc->status &= ~IRQ_INPROGRESS; kill_timer(&irq_guest_eoi_timer[vector]); desc->handler->shutdown(vector); +} + +void pirq_guest_unbind(struct domain *d, int irq) +{ + irq_desc_t *desc; + int vector; + + WARN_ON(!spin_is_locked(&d->evtchn_lock)); + + BUG_ON(!local_irq_is_enabled()); + desc = domain_spin_lock_irq_desc(d, irq, NULL); + + if ( desc == NULL ) + { + if ( !msi_enable ) + return; + vector = -domain_irq_to_vector(d, irq); + BUG_ON(vector <= 0); + desc = &irq_desc[vector]; + spin_lock_irq(&desc->lock); + d->arch.pirq_vector[irq] = d->arch.vector_pirq[vector] = 0; + } + else + { + __pirq_guest_unbind(d, irq, desc); + } + + spin_unlock_irq(&desc->lock); +} + +int pirq_guest_force_unbind(struct domain *d, int irq) +{ + irq_desc_t *desc; + irq_guest_action_t *action; + int i, bound = 0; + + WARN_ON(!spin_is_locked(&d->evtchn_lock)); + + BUG_ON(!local_irq_is_enabled()); + desc = domain_spin_lock_irq_desc(d, irq, NULL); + BUG_ON(desc == NULL); + + if ( !(desc->status & IRQ_GUEST) ) + goto out; + + action = (irq_guest_action_t *)desc->action; + for ( i = 0; (i < action->nr_guests) && (action->guest[i] != d); i++ ) + continue; + if ( i == action->nr_guests ) + goto out; + + bound = 1; + __pirq_guest_unbind(d, irq, desc); out: - spin_unlock_irqrestore(&desc->lock, flags); - return rc; + spin_unlock_irq(&desc->lock); + return bound; } extern void dump_ioapic_irq_info(void); Index: xen-3.3.1-testing/xen/arch/x86/physdev.c =================================================================== --- xen-3.3.1-testing.orig/xen/arch/x86/physdev.c +++ xen-3.3.1-testing/xen/arch/x86/physdev.c @@ -147,7 +147,7 @@ static int unmap_domain_pirq(struct doma { unsigned long flags; irq_desc_t *desc; - bool_t forced_unbind = (pirq_guest_unbind(d, pirq) == 0); + bool_t forced_unbind = pirq_guest_force_unbind(d, pirq); if ( forced_unbind ) dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n", Index: xen-3.3.1-testing/xen/common/event_channel.c =================================================================== --- xen-3.3.1-testing.orig/xen/common/event_channel.c +++ xen-3.3.1-testing/xen/common/event_channel.c @@ -376,8 +376,7 @@ static long __evtchn_close(struct domain break; case ECS_PIRQ: - if ( pirq_guest_unbind(d1, chn1->u.pirq) != 0 ) - BUG(); + pirq_guest_unbind(d1, chn1->u.pirq); d1->pirq_to_evtchn[chn1->u.pirq] = 0; break; Index: xen-3.3.1-testing/xen/include/asm-x86/irq.h =================================================================== --- xen-3.3.1-testing.orig/xen/include/asm-x86/irq.h +++ xen-3.3.1-testing/xen/include/asm-x86/irq.h @@ -55,4 +55,6 @@ int pirq_shared(struct domain *d , int i #define domain_irq_to_vector(d, irq) (msi_enable ? (d)->arch.pirq_vector[irq] : irq_to_vector(irq)) #define domain_vector_to_irq(d, vec) (msi_enable ? (d)->arch.vector_pirq[vec] : vector_to_irq(vec)) +int pirq_guest_force_unbind(struct domain *d, int irq); + #endif /* _ASM_HW_IRQ_H */ Index: xen-3.3.1-testing/xen/include/xen/irq.h =================================================================== --- xen-3.3.1-testing.orig/xen/include/xen/irq.h +++ xen-3.3.1-testing/xen/include/xen/irq.h @@ -77,7 +77,7 @@ struct vcpu; extern int pirq_guest_eoi(struct domain *d, int irq); extern int pirq_guest_unmask(struct domain *d); extern int pirq_guest_bind(struct vcpu *v, int irq, int will_share); -extern int pirq_guest_unbind(struct domain *d, int irq); +extern void pirq_guest_unbind(struct domain *d, int irq); static inline void set_native_irq_info(int irq, cpumask_t mask) {