diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index a80a0d1..a868b89 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -159,36 +159,51 @@ static int get_free_port(struct domain *d) static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) { - struct evtchn *chn; struct domain *d; - int port; - domid_t dom = alloc->dom; long rc; - rc = rcu_lock_target_domain_by_id(dom, &d); + rc = rcu_lock_target_domain_by_id(alloc->dom, &d); if ( rc ) return rc; + rc = evtchn_alloc_unbound_domain(d, &alloc->port, alloc->remote_dom); + if ( rc ) + ERROR_EXIT_DOM((int)rc, d); + + out: + rcu_unlock_domain(d); + + return rc; +} + +int evtchn_alloc_unbound_domain(struct domain *d, evtchn_port_t *port, + domid_t remote_domid) +{ + struct evtchn *chn; + int rc; + int free_port; + spin_lock(&d->event_lock); - if ( (port = get_free_port(d)) < 0 ) - ERROR_EXIT_DOM(port, d); - chn = evtchn_from_port(d, port); + rc = free_port = get_free_port(d); + if ( free_port < 0 ) + goto out; - rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom); + chn = evtchn_from_port(d, free_port); + rc = xsm_evtchn_unbound(d, chn, remote_domid); if ( rc ) goto out; chn->state = ECS_UNBOUND; - if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF ) + if ( (chn->u.unbound.remote_domid = remote_domid) == DOMID_SELF ) chn->u.unbound.remote_domid = current->domain->domain_id; - alloc->port = port; + *port = free_port; + /* Everything is fine, returns 0 */ + rc = 0; out: spin_unlock(&d->event_lock); - rcu_unlock_domain(d); - return rc; } diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 71c3e92..1a0c832 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -69,6 +69,9 @@ int guest_enabled_event(struct vcpu *v, uint32_t virq); /* Notify remote end of a Xen-attached event channel.*/ void notify_via_xen_event_channel(struct domain *ld, int lport); +int evtchn_alloc_unbound_domain(struct domain *d, evtchn_port_t *port, + domid_t remote_domid); + /* Internal event channel object accessors */ #define bucket_from_port(d,p) \ ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET])