# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID c3d9b7013b1442bcc8890da3b60e8e19688ac1a0
# Parent 6f71824a45c19e860a3655dd8e76a83e047c84d2
EVTCHNOP_alloc_unbound can allocate a port in an arbitrary
domain (only if the caller is sufficiently privileged).
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r 6f71824a45c1 -r c3d9b7013b14
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 5
17:06:42 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Wed Oct 5
18:14:13 2005
@@ -485,7 +485,7 @@
static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
{
blkif_sring_t *sring;
- evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+ evtchn_op_t op;
int err;
info->ring_ref = GRANT_INVALID_REF;
@@ -508,7 +508,9 @@
}
info->ring_ref = err;
- op.u.alloc_unbound.dom = info->backend_id;
+ op.cmd = EVTCHNOP_alloc_unbound;
+ op.u.alloc_unbound.dom = DOMID_SELF;
+ op.u.alloc_unbound.remote_dom = info->backend_id;
err = HYPERVISOR_event_channel_op(&op);
if (err) {
gnttab_end_foreign_access(info->ring_ref, 0);
@@ -518,7 +520,9 @@
xenbus_dev_error(dev, err, "allocating event channel");
return err;
}
+
blkif_connect(info, op.u.alloc_unbound.port);
+
return 0;
}
diff -r 6f71824a45c1 -r c3d9b7013b14
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Oct 5
17:06:42 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Wed Oct 5
18:14:13 2005
@@ -972,7 +972,7 @@
static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
{
- evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+ evtchn_op_t op;
int err;
info->tx_ring_ref = GRANT_INVALID_REF;
@@ -1010,13 +1010,17 @@
}
info->rx_ring_ref = err;
- op.u.alloc_unbound.dom = info->backend_id;
+ op.cmd = EVTCHNOP_alloc_unbound;
+ op.u.alloc_unbound.dom = DOMID_SELF;
+ op.u.alloc_unbound.remote_dom = info->backend_id;
err = HYPERVISOR_event_channel_op(&op);
if (err) {
xenbus_dev_error(dev, err, "allocating event channel");
goto out;
}
+
connect_device(info, op.u.alloc_unbound.port);
+
return 0;
out:
diff -r 6f71824a45c1 -r c3d9b7013b14
linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Wed Oct 5
17:06:42 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c Wed Oct 5
18:14:13 2005
@@ -244,8 +244,7 @@
{
tpmif_tx_interface_t *sring;
struct tpm_private *tp = &my_private;
-
- evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
+ evtchn_op_t op;
int err;
sring = (void *)__get_free_page(GFP_KERNEL);
@@ -269,7 +268,9 @@
}
info->ring_ref = err;
- op.u.alloc_unbound.dom = backend_id;
+ op.cmd = EVTCHNOP_alloc_unbound;
+ op.u.alloc_unbound.dom = DOMID_SELF;
+ op.u.alloc_unbound.remote_dom = backend_id;
err = HYPERVISOR_event_channel_op(&op);
if (err) {
gnttab_end_foreign_access(info->ring_ref, 0);
@@ -278,7 +279,9 @@
xenbus_dev_error(dev, err, "allocating event channel");
return err;
}
+
tpmif_connect(op.u.alloc_unbound.port, backend_id);
+
return 0;
}
diff -r 6f71824a45c1 -r c3d9b7013b14 tools/libxc/xc_evtchn.c
--- a/tools/libxc/xc_evtchn.c Wed Oct 5 17:06:42 2005
+++ b/tools/libxc/xc_evtchn.c Wed Oct 5 18:14:13 2005
@@ -33,6 +33,7 @@
int xc_evtchn_alloc_unbound(int xc_handle,
+ u32 remote_dom,
u32 dom,
int *port)
{
@@ -40,6 +41,7 @@
int rc;
op.cmd = EVTCHNOP_alloc_unbound;
+ op.u.alloc_unbound.remote_dom = (domid_t)remote_dom;
op.u.alloc_unbound.dom = (domid_t)dom;
op.u.alloc_unbound.port = (port != NULL) ? *port : 0;
diff -r 6f71824a45c1 -r c3d9b7013b14 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Wed Oct 5 17:06:42 2005
+++ b/tools/libxc/xenctrl.h Wed Oct 5 18:14:13 2005
@@ -306,13 +306,15 @@
* well-known port within a domain to receive events on.
*
* @parm xc_handle a handle to an open hypervisor interface
- * @parm dom the ID of the domain. This maybe DOMID_SELF
+ * @parm remote_dom the ID of the domain who will later bind
+ * @parm dom the ID of the local domain (the 'allocatee')
* @parm port a pointer to a port. This is an in/out parameter. If *port is
* 0, then a new port will be assigned, if port is > 0 then that
* port is allocated if the port is unallocated.
* @return 0 on success, -1 on failure
*/
int xc_evtchn_alloc_unbound(int xc_handle,
+ u32 remote_dom,
u32 dom,
int *port);
diff -r 6f71824a45c1 -r c3d9b7013b14 tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Wed Oct 5 17:06:42 2005
+++ b/tools/python/xen/lowlevel/xc/xc.c Wed Oct 5 18:14:13 2005
@@ -432,16 +432,16 @@
{
XcObject *xc = (XcObject *)self;
- u32 dom;
+ u32 dom = DOMID_SELF, remote_dom;
int port = 0;
- static char *kwd_list[] = { "dom", "port", NULL };
-
- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
- &dom, &port) )
- return NULL;
-
- if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
+ static char *kwd_list[] = { "remote_dom", "dom", "port", NULL };
+
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
+ &remote_dom, &dom, &port) )
+ return NULL;
+
+ if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 )
return PyErr_SetFromErrno(xc_error);
return PyInt_FromLong(port);
diff -r 6f71824a45c1 -r c3d9b7013b14 xen/common/event_channel.c
--- a/xen/common/event_channel.c Wed Oct 5 17:06:42 2005
+++ b/xen/common/event_channel.c Wed Oct 5 18:14:13 2005
@@ -63,9 +63,18 @@
static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
{
struct evtchn *chn;
- struct domain *d = current->domain;
+ struct domain *d;
int port = alloc->port;
+ domid_t dom = alloc->dom;
long rc = 0;
+
+ 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;
spin_lock(&d->evtchn_lock);
@@ -84,11 +93,11 @@
{
case ECS_FREE:
chn->state = ECS_UNBOUND;
- chn->u.unbound.remote_domid = alloc->dom;
+ chn->u.unbound.remote_domid = alloc->remote_dom;
break;
case ECS_UNBOUND:
- if ( chn->u.unbound.remote_domid != alloc->dom )
+ if ( chn->u.unbound.remote_domid != alloc->remote_dom )
ERROR_EXIT(-EINVAL);
break;
@@ -99,7 +108,10 @@
out:
spin_unlock(&d->evtchn_lock);
+ put_domain(d);
+
alloc->port = port;
+
return rc;
}
diff -r 6f71824a45c1 -r c3d9b7013b14 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h Wed Oct 5 17:06:42 2005
+++ b/xen/include/public/event_channel.h Wed Oct 5 18:14:13 2005
@@ -10,14 +10,16 @@
#define __XEN_PUBLIC_EVENT_CHANNEL_H__
/*
- * EVTCHNOP_alloc_unbound: Prepare a local port for binding to <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 <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.
+ * NOTES:
+ * 1. If the caller is unprivileged then <dom> must be DOMID_SELF.
*/
#define EVTCHNOP_alloc_unbound 6
typedef struct evtchn_alloc_unbound {
/* IN parameters */
- domid_t dom;
+ domid_t dom, remote_dom;
/* IN/OUT parameters */
u32 port;
} evtchn_alloc_unbound_t;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|