ia64/xen-unstable

changeset 7232:c3d9b7013b14

EVTCHNOP_alloc_unbound can allocate a port in an arbitrary
domain (only if the caller is sufficiently privileged).

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Wed Oct 05 19:14:13 2005 +0100 (2005-10-05)
parents 6f71824a45c1
children f98c8238e909
files linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c tools/libxc/xc_evtchn.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/xc/xc.c xen/common/event_channel.c xen/include/public/event_channel.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Wed Oct 05 18:06:42 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c	Wed Oct 05 19:14:13 2005 +0100
     1.3 @@ -485,7 +485,7 @@ static void watch_for_status(struct xenb
     1.4  static int setup_blkring(struct xenbus_device *dev, struct blkfront_info *info)
     1.5  {
     1.6  	blkif_sring_t *sring;
     1.7 -	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
     1.8 +	evtchn_op_t op;
     1.9  	int err;
    1.10  
    1.11  	info->ring_ref = GRANT_INVALID_REF;
    1.12 @@ -508,7 +508,9 @@ static int setup_blkring(struct xenbus_d
    1.13  	}
    1.14  	info->ring_ref = err;
    1.15  
    1.16 -	op.u.alloc_unbound.dom = info->backend_id;
    1.17 +	op.cmd = EVTCHNOP_alloc_unbound;
    1.18 +	op.u.alloc_unbound.dom = DOMID_SELF;
    1.19 +	op.u.alloc_unbound.remote_dom = info->backend_id;
    1.20  	err = HYPERVISOR_event_channel_op(&op);
    1.21  	if (err) {
    1.22  		gnttab_end_foreign_access(info->ring_ref, 0);
    1.23 @@ -518,7 +520,9 @@ static int setup_blkring(struct xenbus_d
    1.24  		xenbus_dev_error(dev, err, "allocating event channel");
    1.25  		return err;
    1.26  	}
    1.27 +
    1.28  	blkif_connect(info, op.u.alloc_unbound.port);
    1.29 +
    1.30  	return 0;
    1.31  }
    1.32  
     2.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Oct 05 18:06:42 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c	Wed Oct 05 19:14:13 2005 +0100
     2.3 @@ -972,7 +972,7 @@ static void watch_for_status(struct xenb
     2.4  
     2.5  static int setup_device(struct xenbus_device *dev, struct netfront_info *info)
     2.6  {
     2.7 -	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
     2.8 +	evtchn_op_t op;
     2.9  	int err;
    2.10  
    2.11  	info->tx_ring_ref = GRANT_INVALID_REF;
    2.12 @@ -1010,13 +1010,17 @@ static int setup_device(struct xenbus_de
    2.13  	}
    2.14  	info->rx_ring_ref = err;
    2.15  
    2.16 -	op.u.alloc_unbound.dom = info->backend_id;
    2.17 +	op.cmd = EVTCHNOP_alloc_unbound;
    2.18 +	op.u.alloc_unbound.dom = DOMID_SELF;
    2.19 +	op.u.alloc_unbound.remote_dom = info->backend_id;
    2.20  	err = HYPERVISOR_event_channel_op(&op);
    2.21  	if (err) {
    2.22  		xenbus_dev_error(dev, err, "allocating event channel");
    2.23  		goto out;
    2.24  	}
    2.25 +
    2.26  	connect_device(info, op.u.alloc_unbound.port);
    2.27 +
    2.28  	return 0;
    2.29  
    2.30   out:
     3.1 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Wed Oct 05 18:06:42 2005 +0100
     3.2 +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c	Wed Oct 05 19:14:13 2005 +0100
     3.3 @@ -244,8 +244,7 @@ static int setup_tpmring(struct xenbus_d
     3.4  {
     3.5  	tpmif_tx_interface_t *sring;
     3.6  	struct tpm_private *tp = &my_private;
     3.7 -
     3.8 -	evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
     3.9 +	evtchn_op_t op;
    3.10  	int err;
    3.11  
    3.12  	sring = (void *)__get_free_page(GFP_KERNEL);
    3.13 @@ -269,7 +268,9 @@ static int setup_tpmring(struct xenbus_d
    3.14  	}
    3.15  	info->ring_ref = err;
    3.16  
    3.17 -	op.u.alloc_unbound.dom = backend_id;
    3.18 +	op.cmd = EVTCHNOP_alloc_unbound;
    3.19 +	op.u.alloc_unbound.dom = DOMID_SELF;
    3.20 +	op.u.alloc_unbound.remote_dom = backend_id;
    3.21  	err = HYPERVISOR_event_channel_op(&op);
    3.22  	if (err) {
    3.23  		gnttab_end_foreign_access(info->ring_ref, 0);
    3.24 @@ -278,7 +279,9 @@ static int setup_tpmring(struct xenbus_d
    3.25  		xenbus_dev_error(dev, err, "allocating event channel");
    3.26  		return err;
    3.27  	}
    3.28 +
    3.29  	tpmif_connect(op.u.alloc_unbound.port, backend_id);
    3.30 +
    3.31  	return 0;
    3.32  }
    3.33  
     4.1 --- a/tools/libxc/xc_evtchn.c	Wed Oct 05 18:06:42 2005 +0100
     4.2 +++ b/tools/libxc/xc_evtchn.c	Wed Oct 05 19:14:13 2005 +0100
     4.3 @@ -33,6 +33,7 @@ static int do_evtchn_op(int xc_handle, e
     4.4  
     4.5  
     4.6  int xc_evtchn_alloc_unbound(int xc_handle,
     4.7 +                            u32 remote_dom,
     4.8                              u32 dom,
     4.9                              int *port)
    4.10  {
    4.11 @@ -40,6 +41,7 @@ int xc_evtchn_alloc_unbound(int xc_handl
    4.12      int         rc;
    4.13  
    4.14      op.cmd = EVTCHNOP_alloc_unbound;
    4.15 +    op.u.alloc_unbound.remote_dom = (domid_t)remote_dom;
    4.16      op.u.alloc_unbound.dom  = (domid_t)dom;
    4.17      op.u.alloc_unbound.port = (port != NULL) ? *port : 0;
    4.18  
     5.1 --- a/tools/libxc/xenctrl.h	Wed Oct 05 18:06:42 2005 +0100
     5.2 +++ b/tools/libxc/xenctrl.h	Wed Oct 05 19:14:13 2005 +0100
     5.3 @@ -306,13 +306,15 @@ typedef evtchn_status_t xc_evtchn_status
     5.4   * well-known port within a domain to receive events on.
     5.5   *
     5.6   * @parm xc_handle a handle to an open hypervisor interface
     5.7 - * @parm dom the ID of the domain.  This maybe DOMID_SELF
     5.8 + * @parm remote_dom the ID of the domain who will later bind
     5.9 + * @parm dom the ID of the local domain (the 'allocatee')
    5.10   * @parm port a pointer to a port.  This is an in/out parameter.  If *port is
    5.11   *            0, then a new port will be assigned, if port is > 0 then that
    5.12   *            port is allocated if the port is unallocated.
    5.13   * @return 0 on success, -1 on failure
    5.14   */
    5.15  int xc_evtchn_alloc_unbound(int xc_handle,
    5.16 +                            u32 remote_dom,
    5.17                              u32 dom,
    5.18                              int *port);
    5.19  
     6.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Wed Oct 05 18:06:42 2005 +0100
     6.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Wed Oct 05 19:14:13 2005 +0100
     6.3 @@ -432,16 +432,16 @@ static PyObject *pyxc_evtchn_alloc_unbou
     6.4  {
     6.5      XcObject *xc = (XcObject *)self;
     6.6  
     6.7 -    u32 dom;
     6.8 +    u32 dom = DOMID_SELF, remote_dom;
     6.9      int port = 0;
    6.10  
    6.11 -    static char *kwd_list[] = { "dom", "port", NULL };
    6.12 +    static char *kwd_list[] = { "remote_dom", "dom", "port", NULL };
    6.13  
    6.14 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
    6.15 -                                      &dom, &port) )
    6.16 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
    6.17 +                                      &remote_dom, &dom, &port) )
    6.18          return NULL;
    6.19  
    6.20 -    if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
    6.21 +    if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 )
    6.22          return PyErr_SetFromErrno(xc_error);
    6.23  
    6.24      return PyInt_FromLong(port);
     7.1 --- a/xen/common/event_channel.c	Wed Oct 05 18:06:42 2005 +0100
     7.2 +++ b/xen/common/event_channel.c	Wed Oct 05 19:14:13 2005 +0100
     7.3 @@ -63,10 +63,19 @@ static int get_free_port(struct domain *
     7.4  static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
     7.5  {
     7.6      struct evtchn *chn;
     7.7 -    struct domain *d = current->domain;
     7.8 +    struct domain *d;
     7.9      int            port = alloc->port;
    7.10 +    domid_t        dom = alloc->dom;
    7.11      long           rc = 0;
    7.12  
    7.13 +    if ( dom == DOMID_SELF )
    7.14 +        dom = current->domain->domain_id;
    7.15 +    else if ( !IS_PRIV(current->domain) )
    7.16 +        return -EPERM;
    7.17 +
    7.18 +    if ( (d = find_domain_by_id(dom)) == NULL )
    7.19 +        return -ESRCH;
    7.20 +
    7.21      spin_lock(&d->evtchn_lock);
    7.22  
    7.23      /* Obtain, or ensure that we already have, a valid <port>. */
    7.24 @@ -84,11 +93,11 @@ static long evtchn_alloc_unbound(evtchn_
    7.25      {
    7.26      case ECS_FREE:
    7.27          chn->state = ECS_UNBOUND;
    7.28 -        chn->u.unbound.remote_domid = alloc->dom;
    7.29 +        chn->u.unbound.remote_domid = alloc->remote_dom;
    7.30          break;
    7.31  
    7.32      case ECS_UNBOUND:
    7.33 -        if ( chn->u.unbound.remote_domid != alloc->dom )
    7.34 +        if ( chn->u.unbound.remote_domid != alloc->remote_dom )
    7.35              ERROR_EXIT(-EINVAL);
    7.36          break;
    7.37  
    7.38 @@ -99,7 +108,10 @@ static long evtchn_alloc_unbound(evtchn_
    7.39   out:
    7.40      spin_unlock(&d->evtchn_lock);
    7.41  
    7.42 +    put_domain(d);
    7.43 +
    7.44      alloc->port = port;
    7.45 +
    7.46      return rc;
    7.47  }
    7.48  
     8.1 --- a/xen/include/public/event_channel.h	Wed Oct 05 18:06:42 2005 +0100
     8.2 +++ b/xen/include/public/event_channel.h	Wed Oct 05 19:14:13 2005 +0100
     8.3 @@ -10,14 +10,16 @@
     8.4  #define __XEN_PUBLIC_EVENT_CHANNEL_H__
     8.5  
     8.6  /*
     8.7 - * EVTCHNOP_alloc_unbound: Prepare a local port for binding to <dom>.
     8.8 - * <port> may be wildcarded by setting to zero, in which case a fresh port
     8.9 - * will be allocated, and the field filled in on return.
    8.10 + * EVTCHNOP_alloc_unbound: Allocate a port in <dom> for later binding to
    8.11 + * <remote_dom>. <port> may be wildcarded by setting to zero, in which case a
    8.12 + * fresh port will be allocated, and the field filled in on return.
    8.13 + * NOTES:
    8.14 + *  1. If the caller is unprivileged then <dom> must be DOMID_SELF.
    8.15   */
    8.16  #define EVTCHNOP_alloc_unbound    6
    8.17  typedef struct evtchn_alloc_unbound {
    8.18      /* IN parameters */
    8.19 -    domid_t dom;
    8.20 +    domid_t dom, remote_dom;
    8.21      /* IN/OUT parameters */
    8.22      u32     port;
    8.23  } evtchn_alloc_unbound_t;