This commit is contained in:
emellor@ewan committed 2005-10-07 11:01:23 +01:00
commit c1a792dbf3
12 files changed
+139 -275

No files matched your search

@@ -219,7 +219,6 @@ void unbind_virq_from_irq(int virq)
spin_lock(&irq_mapping_update_lock);
if (--irq_bindcount[irq] == 0) {
op.u.close.dom = DOMID_SELF;
op.u.close.port = evtchn;
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
@@ -283,7 +282,6 @@ void unbind_ipi_from_irq(int ipi)
spin_lock(&irq_mapping_update_lock);
if (--irq_bindcount[irq] == 0) {
op.u.close.dom = DOMID_SELF;
op.u.close.port = evtchn;
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
@@ -326,7 +324,6 @@ void unbind_evtchn_from_irq(unsigned int irq)
spin_lock(&irq_mapping_update_lock);
if ((--irq_bindcount[irq] == 0) && (evtchn != -1)) {
op.u.close.dom = DOMID_SELF;
op.u.close.port = evtchn;
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
@@ -513,7 +510,10 @@ static inline void pirq_query_unmask(int pirq)
static unsigned int startup_pirq(unsigned int irq)
{
evtchn_op_t op = { .cmd = EVTCHNOP_bind_pirq };
int evtchn;
int evtchn = irq_to_evtchn[irq];
if (VALID_EVTCHN(evtchn))
goto out;
op.u.bind_pirq.pirq = irq;
/* NB. We are happy to share unless we are probing. */
@@ -532,6 +532,7 @@ static unsigned int startup_pirq(unsigned int irq)
evtchn_to_irq[evtchn] = irq;
irq_to_evtchn[irq] = evtchn;
out:
unmask_evtchn(evtchn);
pirq_unmask_notify(irq_to_pirq(irq));
@@ -548,7 +549,6 @@ static void shutdown_pirq(unsigned int irq)
mask_evtchn(evtchn);
op.u.close.dom = DOMID_SELF;
op.u.close.port = evtchn;
BUG_ON(HYPERVISOR_event_channel_op(&op) != 0);
@@ -71,10 +71,8 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
int err;
evtchn_op_t op = {
.cmd = EVTCHNOP_bind_interdomain,
.u.bind_interdomain.dom1 = DOMID_SELF,
.u.bind_interdomain.dom2 = blkif->domid,
.u.bind_interdomain.port1 = 0,
.u.bind_interdomain.port2 = evtchn };
.u.bind_interdomain.remote_dom = blkif->domid,
.u.bind_interdomain.remote_port = evtchn };
if ( (blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL )
return -ENOMEM;
@@ -92,7 +90,7 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
return err;
}
blkif->evtchn = op.u.bind_interdomain.port1;
blkif->evtchn = op.u.bind_interdomain.local_port;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
SHARED_RING_INIT(sring);
@@ -71,10 +71,8 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
int err;
evtchn_op_t op = {
.cmd = EVTCHNOP_bind_interdomain,
.u.bind_interdomain.dom1 = DOMID_SELF,
.u.bind_interdomain.dom2 = blkif->domid,
.u.bind_interdomain.port1 = 0,
.u.bind_interdomain.port2 = evtchn };
.u.bind_interdomain.remote_dom = blkif->domid,
.u.bind_interdomain.remote_port = evtchn };
if ((blkif->blk_ring_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -92,7 +90,7 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
return err;
}
blkif->evtchn = op.u.bind_interdomain.port1;
blkif->evtchn = op.u.bind_interdomain.local_port;
sring = (blkif_sring_t *)blkif->blk_ring_area->addr;
SHARED_RING_INIT(sring);
@@ -223,7 +223,7 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
break;
op.cmd = EVTCHNOP_bind_virq;
op.cmd = EVTCHNOP_bind_virq;
op.u.bind_virq.virq = bind.virq;
op.u.bind_virq.vcpu = 0;
rc = HYPERVISOR_event_channel_op(&op);
@@ -243,16 +243,14 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
break;
op.cmd = EVTCHNOP_bind_interdomain;
op.u.bind_interdomain.dom1 = DOMID_SELF;
op.u.bind_interdomain.dom2 = bind.remote_domain;
op.u.bind_interdomain.port1 = 0;
op.u.bind_interdomain.port2 = bind.remote_port;
op.cmd = EVTCHNOP_bind_interdomain;
op.u.bind_interdomain.remote_dom = bind.remote_domain;
op.u.bind_interdomain.remote_port = bind.remote_port;
rc = HYPERVISOR_event_channel_op(&op);
if (rc != 0)
break;
rc = op.u.bind_interdomain.port1;
rc = op.u.bind_interdomain.local_port;
port_user[rc] = u;
unmask_evtchn(rc);
break;
@@ -265,7 +263,7 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
break;
op.cmd = EVTCHNOP_alloc_unbound;
op.cmd = EVTCHNOP_alloc_unbound;
op.u.alloc_unbound.dom = DOMID_SELF;
op.u.alloc_unbound.remote_dom = bind.remote_domain;
rc = HYPERVISOR_event_channel_op(&op);
@@ -292,6 +290,11 @@ static int evtchn_ioctl(struct inode *inode, struct file *file,
} else {
port_user[unbind.port] = NULL;
mask_evtchn(unbind.port);
op.cmd = EVTCHNOP_close;
op.u.close.port = unbind.port;
BUG_ON(HYPERVISOR_event_channel_op(&op));
rc = 0;
}
break;
@@ -390,8 +393,7 @@ static int evtchn_release(struct inode *inode, struct file *filp)
port_user[i] = NULL;
mask_evtchn(i);
op.cmd = EVTCHNOP_close;
op.u.close.dom = DOMID_SELF;
op.cmd = EVTCHNOP_close;
op.u.close.port = i;
BUG_ON(HYPERVISOR_event_channel_op(&op));
}
@@ -180,10 +180,8 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
int err;
evtchn_op_t op = {
.cmd = EVTCHNOP_bind_interdomain,
.u.bind_interdomain.dom1 = DOMID_SELF,
.u.bind_interdomain.dom2 = netif->domid,
.u.bind_interdomain.port1 = 0,
.u.bind_interdomain.port2 = evtchn };
.u.bind_interdomain.remote_dom = netif->domid,
.u.bind_interdomain.remote_port = evtchn };
netif->comms_area = alloc_vm_area(2*PAGE_SIZE);
if (netif->comms_area == NULL)
@@ -202,7 +200,7 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
return err;
}
netif->evtchn = op.u.bind_interdomain.port1;
netif->evtchn = op.u.bind_interdomain.local_port;
netif->irq = bind_evtchn_to_irqhandler(
netif->evtchn, netif_be_int, 0, netif->dev->name, netif);
@@ -120,10 +120,8 @@ tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
int err;
evtchn_op_t op = {
.cmd = EVTCHNOP_bind_interdomain,
.u.bind_interdomain.dom1 = DOMID_SELF,
.u.bind_interdomain.dom2 = tpmif->domid,
.u.bind_interdomain.port1 = 0,
.u.bind_interdomain.port2 = evtchn };
.u.bind_interdomain.remote_dom = tpmif->domid,
.u.bind_interdomain.remote_port = evtchn };
if ((tpmif->tx_area = alloc_vm_area(PAGE_SIZE)) == NULL)
return -ENOMEM;
@@ -141,7 +139,7 @@ tpmif_map(tpmif_t *tpmif, unsigned long shared_page, unsigned int evtchn)
return err;
}
tpmif->evtchn = op.u.bind_interdomain.port1;
tpmif->evtchn = op.u.bind_interdomain.local_port;
tpmif->tx = (tpmif_tx_interface_t *)tpmif->tx_area->addr;
@@ -123,9 +123,9 @@ static inline void clear_evtchn(int port)
static inline void notify_remote_via_evtchn(int port)
{
evtchn_op_t op = {
.cmd = EVTCHNOP_send,
.u.send.local_port = port };
evtchn_op_t op;
op.cmd = EVTCHNOP_send,
op.u.send.port = port;
(void)HYPERVISOR_event_channel_op(&op);
}
+1 -1
View File
@@ -2806,7 +2806,7 @@ int main(int argc, char **argv)
case QEMU_OPTION_p:
{
extern short ioreq_remote_port;
extern u16 ioreq_remote_port;
ioreq_remote_port = atoi(optarg);
printf("port: %d\n", ioreq_remote_port);
}
+7 -6
View File
@@ -432,13 +432,13 @@ static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self,
{
XcObject *xc = (XcObject *)self;
u32 dom = DOMID_SELF, remote_dom;
u32 dom, remote_dom;
int port;
static char *kwd_list[] = { "remote_dom", "dom", NULL };
static char *kwd_list[] = { "dom", "remote_dom", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
&remote_dom, &dom) )
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
&dom, &remote_dom) )
return NULL;
if ( (port = xc_evtchn_alloc_unbound(xc->xc_handle, dom, remote_dom)) < 0 )
@@ -943,8 +943,9 @@ static PyMethodDef pyxc_methods[] = {
{ "evtchn_alloc_unbound",
(PyCFunction)pyxc_evtchn_alloc_unbound,
METH_VARARGS | METH_KEYWORDS, "\n"
"Allocate an unbound local port that will await a remote connection.\n"
" dom [int]: Remote domain to accept connections from.\n\n"
"Allocate an unbound port that will await a remote connection.\n"
" dom [int]: Domain whose port space to allocate from.\n"
" remote_dom [int]: Remote domain to accept connections from.\n\n"
"Returns: [int] Unbound event-channel port.\n" },
{ "evtchn_status",
+1
View File
@@ -197,6 +197,7 @@ def recreate(xeninfo):
log.info("Recreating domain %d with new UUID %s.", domid, uuid)
vm = XendDomainInfo(uuid, xeninfo, domid, True)
vm.removeDom()
vm.storeVmDetails()
vm.storeDomDetails()
+80 -193
View File
@@ -70,7 +70,7 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
{
struct evtchn *chn;
struct domain *d;
int port = alloc->port;
int port;
domid_t dom = alloc->dom;
long rc = 0;
@@ -84,176 +84,80 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
spin_lock(&d->evtchn_lock);
/* Obtain, or ensure that we already have, a valid <port>. */
if ( port == 0 )
{
if ( (port = get_free_port(d)) < 0 )
ERROR_EXIT(port);
}
else if ( !port_is_valid(d, port) )
ERROR_EXIT(-EINVAL);
if ( (port = get_free_port(d)) < 0 )
ERROR_EXIT(port);
chn = evtchn_from_port(d, port);
/* Validate channel's current state. */
switch ( chn->state )
{
case ECS_FREE:
chn->state = ECS_UNBOUND;
chn->u.unbound.remote_domid = alloc->remote_dom;
break;
chn->state = ECS_UNBOUND;
chn->u.unbound.remote_domid = alloc->remote_dom;
case ECS_UNBOUND:
if ( chn->u.unbound.remote_domid != alloc->remote_dom )
ERROR_EXIT(-EINVAL);
break;
default:
ERROR_EXIT(-EINVAL);
}
alloc->port = port;
out:
spin_unlock(&d->evtchn_lock);
put_domain(d);
alloc->port = port;
return rc;
}
static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
{
struct evtchn *chn1, *chn2;
struct domain *d1, *d2;
int port1 = bind->port1, port2 = bind->port2;
domid_t dom1 = bind->dom1, dom2 = bind->dom2;
struct evtchn *lchn, *rchn;
struct domain *ld = current->domain, *rd;
int lport, rport = bind->remote_port;
long rc = 0;
if ( !IS_PRIV(current->domain) && (dom1 != DOMID_SELF) )
return -EPERM;
if ( dom1 == DOMID_SELF )
dom1 = current->domain->domain_id;
if ( dom2 == DOMID_SELF )
dom2 = current->domain->domain_id;
if ( ((d1 = find_domain_by_id(dom1)) == NULL) ||
((d2 = find_domain_by_id(dom2)) == NULL) )
{
if ( d1 != NULL )
put_domain(d1);
if ( (rd = find_domain_by_id(bind->remote_dom)) == NULL )
return -ESRCH;
}
/* Avoid deadlock by first acquiring lock of domain with smaller id. */
if ( d1 < d2 )
if ( ld < rd )
{
spin_lock(&d1->evtchn_lock);
spin_lock(&d2->evtchn_lock);
spin_lock(&ld->evtchn_lock);
spin_lock(&rd->evtchn_lock);
}
else
{
if ( d1 != d2 )
spin_lock(&d2->evtchn_lock);
spin_lock(&d1->evtchn_lock);
if ( ld != rd )
spin_lock(&rd->evtchn_lock);
spin_lock(&ld->evtchn_lock);
}
/* Obtain, or ensure that we already have, a valid <port1>. */
if ( port1 == 0 )
{
if ( (port1 = get_free_port(d1)) < 0 )
ERROR_EXIT(port1);
}
else if ( !port_is_valid(d1, port1) )
if ( (lport = get_free_port(ld)) < 0 )
ERROR_EXIT(lport);
lchn = evtchn_from_port(ld, lport);
if ( !port_is_valid(rd, rport) )
ERROR_EXIT(-EINVAL);
chn1 = evtchn_from_port(d1, port1);
/* Obtain, or ensure that we already have, a valid <port2>. */
if ( port2 == 0 )
{
/* Make port1 non-free while we allocate port2 (in case dom1==dom2). */
u16 state = chn1->state;
chn1->state = ECS_INTERDOMAIN;
port2 = get_free_port(d2);
chn1->state = state;
if ( port2 < 0 )
ERROR_EXIT(port2);
}
else if ( !port_is_valid(d2, port2) )
rchn = evtchn_from_port(rd, rport);
if ( (rchn->state != ECS_UNBOUND) ||
(rchn->u.unbound.remote_domid != ld->domain_id) )
ERROR_EXIT(-EINVAL);
chn2 = evtchn_from_port(d2, port2);
/* Validate <dom1,port1>'s current state. */
switch ( chn1->state )
{
case ECS_FREE:
break;
case ECS_UNBOUND:
if ( chn1->u.unbound.remote_domid != dom2 )
ERROR_EXIT(-EINVAL);
break;
case ECS_INTERDOMAIN:
if ( chn1->u.interdomain.remote_dom != d2 )
ERROR_EXIT(-EINVAL);
if ( (chn1->u.interdomain.remote_port != port2) && (bind->port2 != 0) )
ERROR_EXIT(-EINVAL);
port2 = chn1->u.interdomain.remote_port;
goto out;
default:
ERROR_EXIT(-EINVAL);
}
/* Validate <dom2,port2>'s current state. */
switch ( chn2->state )
{
case ECS_FREE:
if ( !IS_PRIV(current->domain) && (dom2 != DOMID_SELF) )
ERROR_EXIT(-EPERM);
break;
case ECS_UNBOUND:
if ( chn2->u.unbound.remote_domid != dom1 )
ERROR_EXIT(-EINVAL);
break;
case ECS_INTERDOMAIN:
if ( chn2->u.interdomain.remote_dom != d1 )
ERROR_EXIT(-EINVAL);
if ( (chn2->u.interdomain.remote_port != port1) && (bind->port1 != 0) )
ERROR_EXIT(-EINVAL);
port1 = chn2->u.interdomain.remote_port;
goto out;
default:
ERROR_EXIT(-EINVAL);
}
lchn->u.interdomain.remote_dom = rd;
lchn->u.interdomain.remote_port = (u16)rport;
lchn->state = ECS_INTERDOMAIN;
rchn->u.interdomain.remote_dom = ld;
rchn->u.interdomain.remote_port = (u16)lport;
rchn->state = ECS_INTERDOMAIN;
/*
* Everything checked out okay -- bind <dom1,port1> to <dom2,port2>.
* We may have lost notifications on the remote unbound port. Fix that up
* here by conservatively always setting a notification on the local port.
*/
evtchn_set_pending(ld->vcpu[lchn->notify_vcpu_id], lport);
chn1->u.interdomain.remote_dom = d2;
chn1->u.interdomain.remote_port = (u16)port2;
chn1->state = ECS_INTERDOMAIN;
chn2->u.interdomain.remote_dom = d1;
chn2->u.interdomain.remote_port = (u16)port1;
chn2->state = ECS_INTERDOMAIN;
bind->local_port = lport;
out:
spin_unlock(&d1->evtchn_lock);
if ( d1 != d2 )
spin_unlock(&d2->evtchn_lock);
spin_unlock(&ld->evtchn_lock);
if ( ld != rd )
spin_unlock(&rd->evtchn_lock);
put_domain(d1);
put_domain(d2);
bind->port1 = port1;
bind->port2 = port2;
put_domain(rd);
return rc;
}
@@ -264,39 +168,34 @@ static long evtchn_bind_virq(evtchn_bind_virq_t *bind)
struct evtchn *chn;
struct vcpu *v;
struct domain *d = current->domain;
int port, virq = bind->virq;
int port, virq = bind->virq, vcpu = bind->vcpu;
long rc = 0;
if ( virq >= ARRAY_SIZE(v->virq_to_evtchn) )
return -EINVAL;
if ( (v = d->vcpu[bind->vcpu]) == NULL )
if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || ((v = d->vcpu[vcpu]) == NULL) )
return -ENOENT;
spin_lock(&d->evtchn_lock);
/*
* Port 0 is the fallback port for VIRQs that haven't been explicitly
* bound yet.
*/
if ( ((port = v->virq_to_evtchn[virq]) != 0) ||
((port = get_free_port(d)) < 0) )
goto out;
if ( v->virq_to_evtchn[virq] != 0 )
ERROR_EXIT(-EEXIST);
if ( (port = get_free_port(d)) < 0 )
ERROR_EXIT(port);
chn = evtchn_from_port(d, port);
chn->state = ECS_VIRQ;
chn->notify_vcpu_id = v->vcpu_id;
chn->notify_vcpu_id = vcpu;
chn->u.virq = virq;
v->virq_to_evtchn[virq] = port;
v->virq_to_evtchn[virq] = bind->port = port;
out:
spin_unlock(&d->evtchn_lock);
if ( port < 0 )
return port;
bind->port = port;
return 0;
return rc;
}
@@ -304,27 +203,27 @@ static long evtchn_bind_ipi(evtchn_bind_ipi_t *bind)
{
struct evtchn *chn;
struct domain *d = current->domain;
int port;
int port, vcpu = bind->vcpu;
long rc = 0;
if ( d->vcpu[bind->vcpu] == NULL )
if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu] == NULL) )
return -ENOENT;
spin_lock(&d->evtchn_lock);
if ( (port = get_free_port(d)) >= 0 )
{
chn = evtchn_from_port(d, port);
chn->state = ECS_IPI;
chn->notify_vcpu_id = bind->vcpu;
}
if ( (port = get_free_port(d)) < 0 )
ERROR_EXIT(port);
spin_unlock(&d->evtchn_lock);
if ( port < 0 )
return port;
chn = evtchn_from_port(d, port);
chn->state = ECS_IPI;
chn->notify_vcpu_id = vcpu;
bind->port = port;
return 0;
out:
spin_unlock(&d->evtchn_lock);
return rc;
}
@@ -332,16 +231,19 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
{
struct evtchn *chn;
struct domain *d = current->domain;
int port, rc, pirq = bind->pirq;
int port, pirq = bind->pirq;
long rc;
if ( pirq >= ARRAY_SIZE(d->pirq_to_evtchn) )
return -EINVAL;
spin_lock(&d->evtchn_lock);
if ( ((rc = port = d->pirq_to_evtchn[pirq]) != 0) ||
((rc = port = get_free_port(d)) < 0) )
goto out;
if ( d->pirq_to_evtchn[pirq] != 0 )
ERROR_EXIT(-EEXIST);
if ( (port = get_free_port(d)) < 0 )
ERROR_EXIT(port);
chn = evtchn_from_port(d, port);
@@ -357,14 +259,12 @@ static long evtchn_bind_pirq(evtchn_bind_pirq_t *bind)
chn->state = ECS_PIRQ;
chn->u.pirq = pirq;
bind->port = port;
out:
spin_unlock(&d->evtchn_lock);
if ( rc < 0 )
return rc;
bind->port = port;
return 0;
return rc;
}
@@ -478,22 +378,7 @@ static long __evtchn_close(struct domain *d1, int port1)
static long evtchn_close(evtchn_close_t *close)
{
struct domain *d;
long rc;
domid_t dom = close->dom;
if ( dom == DOMID_SELF )
dom = current->domain->domain_id;
else if ( !IS_PRIV(current->domain) )
return -EPERM;
if ( (d = find_domain_by_id(dom)) == NULL )
return -ESRCH;
rc = __evtchn_close(d, close->port);
put_domain(d);
return rc;
return __evtchn_close(current->domain, close->port);
}
@@ -523,6 +408,9 @@ long evtchn_send(int lport)
case ECS_IPI:
evtchn_set_pending(ld->vcpu[lchn->notify_vcpu_id], lport);
break;
case ECS_UNBOUND:
/* silently drop the notification */
break;
default:
ret = -EINVAL;
}
@@ -611,9 +499,8 @@ static long evtchn_bind_vcpu(evtchn_bind_vcpu_t *bind)
struct evtchn *chn;
long rc = 0;
if ( (vcpu >= MAX_VIRT_CPUS) || (d->vcpu[vcpu] == NULL) ) {
return -EINVAL;
}
if ( (vcpu >= ARRAY_SIZE(d->vcpu)) || (d->vcpu[vcpu] == NULL) )
return -ENOENT;
spin_lock(&d->evtchn_lock);
@@ -689,7 +576,7 @@ long do_event_channel_op(evtchn_op_t *uop)
break;
case EVTCHNOP_send:
rc = evtchn_send(op.u.send.local_port);
rc = evtchn_send(op.u.send.port);
break;
case EVTCHNOP_status:
+18 -37
View File
@@ -10,9 +10,9 @@
#define __XEN_PUBLIC_EVENT_CHANNEL_H__
/*
* EVTCHNOP_alloc_unbound: Allocate a port in <dom> for later binding to
* <remote_dom>. <port> may be wildcarded by setting to zero, in which case a
* fresh port will be allocated, and the field filled in on return.
* EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
* accepting interdomain bindings from domain <remote_dom>. A fresh port
* is allocated in <dom> and returned as <port>.
* NOTES:
* 1. If the caller is unprivileged then <dom> must be DOMID_SELF.
*/
@@ -20,36 +20,24 @@
typedef struct evtchn_alloc_unbound {
/* IN parameters */
domid_t dom, remote_dom;
/* IN/OUT parameters */
/* OUT parameters */
u32 port;
} evtchn_alloc_unbound_t;
/*
* EVTCHNOP_bind_interdomain: Construct an interdomain event channel between
* <dom1> and <dom2>. Either <port1> or <port2> may be wildcarded by setting to
* zero. On successful return both <port1> and <port2> are filled in and
* <dom1,port1> is fully bound to <dom2,port2>.
*
* NOTES:
* 1. A wildcarded port is allocated from the relevant domain's free list
* (i.e., some port that was previously EVTCHNSTAT_closed). However, if the
* remote port pair is already fully bound then a port is not allocated,
* and instead the existing local port is returned to the caller.
* 2. If the caller is unprivileged then <dom1> must be DOMID_SELF.
* 3. If the caller is unprivileged and <dom2,port2> is EVTCHNSTAT_closed
* then <dom2> must be DOMID_SELF.
* 4. If either port is already bound then it must be bound to the other
* specified domain and port (if not wildcarded).
* 5. If either port is awaiting binding (EVTCHNSTAT_unbound) then it must
* be awaiting binding to the other domain, and the other port pair must
* be closed or unbound.
* the calling domain and <remote_dom>. <remote_dom,remote_port> must identify
* a port that is unbound and marked as accepting bindings from the calling
* domain. A fresh port is allocated in the calling domain and returned as
* <local_port>.
*/
#define EVTCHNOP_bind_interdomain 0
typedef struct evtchn_bind_interdomain {
/* IN parameters. */
domid_t dom1, dom2;
/* IN/OUT parameters. */
u32 port1, port2;
domid_t remote_dom;
u32 remote_port;
/* OUT parameters. */
u32 local_port;
} evtchn_bind_interdomain_t;
/*
@@ -99,31 +87,24 @@ typedef struct evtchn_bind_ipi {
} evtchn_bind_ipi_t;
/*
* EVTCHNOP_close: Close the communication channel which has an endpoint at
* <dom, port>. If the channel is interdomain then the remote end is placed in
* the unbound state (EVTCHNSTAT_unbound), awaiting a new connection.
* NOTES:
* 1. <dom> may be specified as DOMID_SELF.
* 2. Only a sufficiently-privileged domain may close an event channel
* for which <dom> is not DOMID_SELF.
* EVTCHNOP_close: Close a local event channel <port>. If the channel is
* interdomain then the remote end is placed in the unbound state
* (EVTCHNSTAT_unbound), awaiting a new connection.
*/
#define EVTCHNOP_close 3
typedef struct evtchn_close {
/* IN parameters. */
domid_t dom;
u32 port;
/* No OUT parameters. */
u32 port;
} evtchn_close_t;
/*
* EVTCHNOP_send: Send an event to the remote end of the channel whose local
* endpoint is <DOMID_SELF, local_port>.
* endpoint is <port>.
*/
#define EVTCHNOP_send 4
typedef struct evtchn_send {
/* IN parameters. */
u32 local_port;
/* No OUT parameters. */
u32 port;
} evtchn_send_t;
/*
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.