ia64/xen-unstable

changeset 5325:66803c3fa4fd

bitkeeper revision 1.1674 (42a2cfb9WFgnh2K4Xr5ev3pSEASVbw)

Extend EVTCHNOP_alloc_unbound to allocate a specified port, if
non-zero value is passed in.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun Jun 05 10:11:05 2005 +0000 (2005-06-05)
parents fae40022928b
children fd6da43c07ab
files tools/libxc/xc_evtchn.c tools/python/xen/lowlevel/xc/xc.c xen/common/event_channel.c xen/include/public/event_channel.h
line diff
     1.1 --- a/tools/libxc/xc_evtchn.c	Sun Jun 05 09:59:47 2005 +0000
     1.2 +++ b/tools/libxc/xc_evtchn.c	Sun Jun 05 10:11:05 2005 +0000
     1.3 @@ -39,8 +39,9 @@ int xc_evtchn_alloc_unbound(int xc_handl
     1.4      int         rc;
     1.5  
     1.6      op.cmd = EVTCHNOP_alloc_unbound;
     1.7 -    op.u.alloc_unbound.dom = (domid_t)dom;
     1.8 -   
     1.9 +    op.u.alloc_unbound.dom  = (domid_t)dom;
    1.10 +    op.u.alloc_unbound.port = (port != NULL) ? *port : 0;
    1.11 +
    1.12      if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
    1.13      {
    1.14          if ( port != NULL )
     2.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Sun Jun 05 09:59:47 2005 +0000
     2.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Sun Jun 05 10:11:05 2005 +0000
     2.3 @@ -494,11 +494,12 @@ static PyObject *pyxc_evtchn_alloc_unbou
     2.4      XcObject *xc = (XcObject *)self;
     2.5  
     2.6      u32 dom;
     2.7 -    int port;
     2.8 +    int port = 0;
     2.9  
    2.10 -    static char *kwd_list[] = { "dom", NULL };
    2.11 +    static char *kwd_list[] = { "dom", "port", NULL };
    2.12  
    2.13 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &dom) )
    2.14 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
    2.15 +                                      &dom, &port) )
    2.16          return NULL;
    2.17  
    2.18      if ( xc_evtchn_alloc_unbound(xc->xc_handle, dom, &port) != 0 )
     3.1 --- a/xen/common/event_channel.c	Sun Jun 05 09:59:47 2005 +0000
     3.2 +++ b/xen/common/event_channel.c	Sun Jun 05 10:11:05 2005 +0000
     3.3 @@ -35,6 +35,8 @@
     3.4  #define evtchn_from_port(d,p) \
     3.5      (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
     3.6  
     3.7 +#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
     3.8 +
     3.9  static int get_free_port(struct domain *d)
    3.10  {
    3.11      struct evtchn *chn;
    3.12 @@ -61,30 +63,48 @@ static long evtchn_alloc_unbound(evtchn_
    3.13  {
    3.14      struct evtchn *chn;
    3.15      struct domain *d = current->domain;
    3.16 -    int            port;
    3.17 +    int            port = alloc->port;
    3.18 +    long           rc = 0;
    3.19  
    3.20      spin_lock(&d->evtchn_lock);
    3.21  
    3.22 -    if ( (port = get_free_port(d)) >= 0 )
    3.23 +    /* Obtain, or ensure that we already have, a valid <port>. */
    3.24 +    if ( port == 0 )
    3.25      {
    3.26 -        chn = evtchn_from_port(d, port);
    3.27 +        if ( (port = get_free_port(d)) < 0 )
    3.28 +            ERROR_EXIT(port);
    3.29 +    }
    3.30 +    else if ( !port_is_valid(d, port) )
    3.31 +        ERROR_EXIT(-EINVAL);
    3.32 +    chn = evtchn_from_port(d, port);
    3.33 +
    3.34 +    /* Validate channel's current state. */
    3.35 +    switch ( chn->state )
    3.36 +    {
    3.37 +    case ECS_FREE:
    3.38          chn->state = ECS_UNBOUND;
    3.39          chn->u.unbound.remote_domid = alloc->dom;
    3.40 +        break;
    3.41 +
    3.42 +    case ECS_UNBOUND:
    3.43 +        if ( chn->u.unbound.remote_domid != alloc->dom )
    3.44 +            ERROR_EXIT(-EINVAL);
    3.45 +        break;
    3.46 +
    3.47 +    default:
    3.48 +        ERROR_EXIT(-EINVAL);
    3.49      }
    3.50  
    3.51 + out:
    3.52      spin_unlock(&d->evtchn_lock);
    3.53  
    3.54 -    if ( port < 0 )
    3.55 -        return port;
    3.56 -
    3.57      alloc->port = port;
    3.58 -    return 0;
    3.59 +    return rc;
    3.60  }
    3.61  
    3.62  
    3.63  static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
    3.64  {
    3.65 -#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
    3.66      struct evtchn *chn1, *chn2;
    3.67      struct domain *d1, *d2;
    3.68      int            port1 = bind->port1, port2 = bind->port2;
    3.69 @@ -217,7 +237,6 @@ static long evtchn_bind_interdomain(evtc
    3.70      bind->port2 = port2;
    3.71  
    3.72      return rc;
    3.73 -#undef ERROR_EXIT
    3.74  }
    3.75  
    3.76  
     4.1 --- a/xen/include/public/event_channel.h	Sun Jun 05 09:59:47 2005 +0000
     4.2 +++ b/xen/include/public/event_channel.h	Sun Jun 05 10:11:05 2005 +0000
     4.3 @@ -10,15 +10,16 @@
     4.4  #define __XEN_PUBLIC_EVENT_CHANNEL_H__
     4.5  
     4.6  /*
     4.7 - * EVTCHNOP_alloc_unbound: Allocate a fresh local port and prepare
     4.8 - * it for binding to <dom>.
     4.9 + * EVTCHNOP_alloc_unbound: Prepare a local port for binding to <dom>.
    4.10 + * <port> may be wildcarded by setting to zero, in which case a fresh port
    4.11 + * will be allocated, and the field filled in on return.
    4.12   */
    4.13  #define EVTCHNOP_alloc_unbound    6
    4.14  typedef struct {
    4.15      /* IN parameters */
    4.16      domid_t dom;                      /*  0 */
    4.17      u16     __pad;
    4.18 -    /* OUT parameters */
    4.19 +    /* IN/OUT parameters */
    4.20      u32     port;                     /*  4 */
    4.21  } PACKED evtchn_alloc_unbound_t; /* 8 bytes */
    4.22