[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Big simplification of the Xen event-channel interface.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 37bea65ed6ca2faff4bf5f1b281b6cdc9df3522d # Parent 48df3efaf61c2cf98dc87ab1b70bd505f0096a6a Big simplification of the Xen event-channel interface. EVTCHNOP_bind_interdomain in particular is much simpler. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 48df3efaf61c -r 37bea65ed6ca linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Thu Oct 6 23:21:00 2005 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c Fri Oct 7 09:57:13 2005 @@ -219,7 +219,6 @@ 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 @@ 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 @@ 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 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 @@ 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 @@ mask_evtchn(evtchn); - op.u.close.dom = DOMID_SELF; op.u.close.port = evtchn; BUG_ON(HYPERVISOR_event_channel_op(&op) != 0); diff -r 48df3efaf61c -r 37bea65ed6ca linux-2.6-xen-sparse/drivers/xen/blkback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Thu Oct 6 23:21:00 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/interface.c Fri Oct 7 09:57:13 2005 @@ -71,10 +71,8 @@ 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 @@ 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); diff -r 48df3efaf61c -r 37bea65ed6ca linux-2.6-xen-sparse/drivers/xen/blktap/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Thu Oct 6 23:21:00 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/interface.c Fri Oct 7 09:57:13 2005 @@ -71,10 +71,8 @@ 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 @@ 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); diff -r 48df3efaf61c -r 37bea65ed6ca linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Thu Oct 6 23:21:00 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Fri Oct 7 09:57:13 2005 @@ -223,7 +223,7 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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)); } diff -r 48df3efaf61c -r 37bea65ed6ca linux-2.6-xen-sparse/drivers/xen/netback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Thu Oct 6 23:21:00 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Fri Oct 7 09:57:13 2005 @@ -180,10 +180,8 @@ 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 @@ 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); diff -r 48df3efaf61c -r 37bea65ed6ca linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Thu Oct 6 23:21:00 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/interface.c Fri Oct 7 09:57:13 2005 @@ -120,10 +120,8 @@ 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 @@ 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; diff -r 48df3efaf61c -r 37bea65ed6ca linux-2.6-xen-sparse/include/asm-xen/evtchn.h --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Thu Oct 6 23:21:00 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h Fri Oct 7 09:57:13 2005 @@ -123,9 +123,9 @@ 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); } diff -r 48df3efaf61c -r 37bea65ed6ca tools/ioemu/vl.c --- a/tools/ioemu/vl.c Thu Oct 6 23:21:00 2005 +++ b/tools/ioemu/vl.c Fri Oct 7 09:57:13 2005 @@ -2806,7 +2806,7 @@ 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); } diff -r 48df3efaf61c -r 37bea65ed6ca tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu Oct 6 23:21:00 2005 +++ b/tools/python/xen/lowlevel/xc/xc.c Fri Oct 7 09:57:13 2005 @@ -432,13 +432,13 @@ { XcObject *xc = (XcObject *)self; - u32 dom = DOMID_SELF, remote_dom; + u32 dom, remote_dom; int port; - static char *kwd_list[] = { "remote_dom", "dom", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, - &remote_dom, &dom) ) + static char *kwd_list[] = { "dom", "remote_dom", NULL }; + + 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 @@ { "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", diff -r 48df3efaf61c -r 37bea65ed6ca tools/python/xen/xend/XendDomainInfo.py --- a/tools/python/xen/xend/XendDomainInfo.py Thu Oct 6 23:21:00 2005 +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Oct 7 09:57:13 2005 @@ -197,6 +197,7 @@ log.info("Recreating domain %d with new UUID %s.", domid, uuid) vm = XendDomainInfo(uuid, xeninfo, domid, True) + vm.removeDom() vm.storeVmDetails() vm.storeDomDetails() diff -r 48df3efaf61c -r 37bea65ed6ca xen/common/event_channel.c --- a/xen/common/event_channel.c Thu Oct 6 23:21:00 2005 +++ b/xen/common/event_channel.c Fri Oct 7 09:57:13 2005 @@ -70,7 +70,7 @@ { struct evtchn *chn; struct domain *d; - int port = alloc->port; + int port; domid_t dom = alloc->dom; long rc = 0; @@ -84,176 +84,80 @@ 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) ) + if ( (port = get_free_port(d)) < 0 ) + ERROR_EXIT(port); + chn = evtchn_from_port(d, port); + + chn->state = ECS_UNBOUND; + chn->u.unbound.remote_domid = alloc->remote_dom; + + alloc->port = port; + + out: + spin_unlock(&d->evtchn_lock); + + put_domain(d); + + return rc; +} + + +static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) +{ + struct evtchn *lchn, *rchn; + struct domain *ld = current->domain, *rd; + int lport, rport = bind->remote_port; + long rc = 0; + + if ( (rd = find_domain_by_id(bind->remote_dom)) == NULL ) + return -ESRCH; + + /* Avoid deadlock by first acquiring lock of domain with smaller id. */ + if ( ld < rd ) + { + spin_lock(&ld->evtchn_lock); + spin_lock(&rd->evtchn_lock); + } + else + { + if ( ld != rd ) + spin_lock(&rd->evtchn_lock); + spin_lock(&ld->evtchn_lock); + } + + 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); - 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; - - case ECS_UNBOUND: - if ( chn->u.unbound.remote_domid != alloc->remote_dom ) - ERROR_EXIT(-EINVAL); - break; - - default: + rchn = evtchn_from_port(rd, rport); + if ( (rchn->state != ECS_UNBOUND) || + (rchn->u.unbound.remote_domid != ld->domain_id) ) ERROR_EXIT(-EINVAL); - } - - 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; - 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); - return -ESRCH; - } - - /* Avoid deadlock by first acquiring lock of domain with smaller id. */ - if ( d1 < d2 ) - { - spin_lock(&d1->evtchn_lock); - spin_lock(&d2->evtchn_lock); - } - else - { - if ( d1 != d2 ) - spin_lock(&d2->evtchn_lock); - spin_lock(&d1->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) ) - 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) ) - 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. */ - - chn1->u.interdomain.remote_dom = d2; - chn1->u.interdomain.remote_port = (u16)port2; - chn1->state = ECS_INTERDOMAIN; + evtchn_set_pending(ld->vcpu[lchn->notify_vcpu_id], lport); + + bind->local_port = lport; + + out: + spin_unlock(&ld->evtchn_lock); + if ( ld != rd ) + spin_unlock(&rd->evtchn_lock); - chn2->u.interdomain.remote_dom = d1; - chn2->u.interdomain.remote_port = (u16)port1; - chn2->state = ECS_INTERDOMAIN; - - out: - spin_unlock(&d1->evtchn_lock); - if ( d1 != d2 ) - spin_unlock(&d2->evtchn_lock); - - put_domain(d1); - put_domain(d2); - - bind->port1 = port1; - bind->port2 = port2; + put_domain(rd); return rc; } @@ -264,39 +168,34 @@ 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 @@ { struct evtchn *chn; struct domain *d = current->domain; - int port; - - if ( d->vcpu[bind->vcpu] == NULL ) + int port, vcpu = bind->vcpu; + long rc = 0; + + 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); + + chn = evtchn_from_port(d, port); + chn->state = ECS_IPI; + chn->notify_vcpu_id = vcpu; + + bind->port = port; + + out: spin_unlock(&d->evtchn_lock); - if ( port < 0 ) - return port; - - bind->port = port; - return 0; + return rc; } @@ -332,16 +231,19 @@ { 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 @@ 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(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 @@ 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 @@ 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 @@ break; case EVTCHNOP_send: - rc = evtchn_send(op.u.send.local_port); + rc = evtchn_send(op.u.send.port); break; case EVTCHNOP_status: diff -r 48df3efaf61c -r 37bea65ed6ca xen/include/public/event_channel.h --- a/xen/include/public/event_channel.h Thu Oct 6 23:21:00 2005 +++ b/xen/include/public/event_channel.h Fri Oct 7 09:57:13 2005 @@ -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 @@ } 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; /* _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |