@@ -600,7 +600,6 @@ static long evtchn_bind_pirq(evtchn_bind
int evtchn_close(struct domain *d1, int port1, bool guest)
{
struct domain *d2 = NULL;
- struct vcpu *v;
struct evtchn *chn1, *chn2;
int port2;
long rc = 0;
@@ -651,17 +650,19 @@ int evtchn_close(struct domain *d1, int
break;
}
- case ECS_VIRQ:
- for_each_vcpu ( d1, v )
- {
- unsigned long flags;
+ case ECS_VIRQ: {
+ struct vcpu *v;
+ unsigned long flags;
+
+ v = d1->vcpu[virq_is_global(chn1->u.virq) ? 0 : chn1->notify_vcpu_id];
+
+ write_lock_irqsave(&v->virq_lock, flags);
+ ASSERT(read_atomic(&v->virq_to_evtchn[chn1->u.virq]) == port1);
+ write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
+ write_unlock_irqrestore(&v->virq_lock, flags);
- write_lock_irqsave(&v->virq_lock, flags);
- if ( read_atomic(&v->virq_to_evtchn[chn1->u.virq]) == port1 )
- write_atomic(&v->virq_to_evtchn[chn1->u.virq], 0);
- write_unlock_irqrestore(&v->virq_lock, flags);
- }
break;
+ }
case ECS_IPI:
break;
Global vIRQ-s have their event channel association tracked on vCPU 0. Per-vCPU vIRQ-s can't have their notify_vcpu_id changed. Hence it is well-known which vCPU's virq_to_evtchn[] needs updating. Signed-off-by: Jan Beulich <jbeulich@suse.com> --- v4: New.