alloc.dom = d->domain_id;
alloc.remote_dom = hardware_domain->domain_id;
- rc = evtchn_alloc_unbound(&alloc);
+ rc = evtchn_alloc_unbound(&alloc, 0);
if ( rc )
{
printk("Failed allocating event channel for domain\n");
return rc ?: port;
}
-int evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
+/*
+ * If port is zero get the next free port and allocate. If port is non-zero
+ * allocate the specified port.
+ */
+int evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc, evtchn_port_t port)
{
struct evtchn *chn;
struct domain *d;
- int port, rc;
+ int rc;
domid_t dom = alloc->dom;
d = rcu_lock_domain_by_any_id(dom);
write_lock(&d->event_lock);
- if ( (port = get_free_port(d)) < 0 )
- ERROR_EXIT_DOM(port, d);
+ port = rc = evtchn_get_port(d, port);
+ if ( rc < 0 )
+ ERROR_EXIT(rc);
+ rc = 0;
+
chn = evtchn_from_port(d, port);
rc = xsm_evtchn_unbound(XSM_TARGET, d, chn, alloc->remote_dom);
struct evtchn_alloc_unbound alloc_unbound;
if ( copy_from_guest(&alloc_unbound, arg, 1) != 0 )
return -EFAULT;
- rc = evtchn_alloc_unbound(&alloc_unbound);
+ rc = evtchn_alloc_unbound(&alloc_unbound, 0);
if ( !rc && __copy_to_guest(arg, &alloc_unbound, 1) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
int evtchn_allocate_port(struct domain *d, unsigned int port);
/* Allocate a new event channel */
-int __must_check evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc);
+int __must_check evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc,
+ evtchn_port_t port);
/* Unmask a local event-channel port. */
int evtchn_unmask(unsigned int port);