ia64/xen-unstable

changeset 7245:4083eb31def0

Change how event channels are allocated and used by the control
tools. /dev/xen/evtchn is now used by daemons to connect to
remote domains: the advantage is that the local ports are garbage
collected automatically if the daemon dies. xen no longer
constructs end-to-end event-channel port pairs -- it allocates an
unbound port in new domU and writes that port to xenstore. It is
then picked up by teh appropriate daemon which does interdomain bind
via /dev/xen/evtchn.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Oct 06 16:07:52 2005 +0100 (2005-10-06)
parents cd228621e1fd
children 76a7a7aa27e4
files linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c linux-2.6-xen-sparse/include/asm-xen/evtchn.h linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h tools/console/daemon/io.c tools/debugger/pdb/pdb_xen.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c tools/python/xen/lowlevel/xc/xc.c tools/python/xen/xend/XendCheckpoint.py tools/python/xen/xend/XendDomainInfo.py tools/python/xen/xend/image.py tools/xenstore/xenstored_domain.c xen/common/event_channel.c
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Thu Oct 06 15:12:31 2005 +0100
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Thu Oct 06 16:07:52 2005 +0100
     1.3 @@ -44,9 +44,9 @@
     1.4  #include <linux/poll.h>
     1.5  #include <linux/irq.h>
     1.6  #include <linux/init.h>
     1.7 -#define XEN_EVTCHN_MASK_OPS
     1.8 +#include <linux/gfp.h>
     1.9  #include <asm-xen/evtchn.h>
    1.10 -#include <linux/gfp.h>
    1.11 +#include <asm-xen/linux-public/evtchn.h>
    1.12  
    1.13  struct per_user_data {
    1.14  	/* Notification ring, accessed via /dev/xen/evtchn. */
    1.15 @@ -78,7 +78,8 @@ void evtchn_device_upcall(int port)
    1.16  			u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port;
    1.17  			if (u->ring_cons == u->ring_prod++) {
    1.18  				wake_up_interruptible(&u->evtchn_wait);
    1.19 -				kill_fasync(&u->evtchn_async_queue, SIGIO, POLL_IN);
    1.20 +				kill_fasync(&u->evtchn_async_queue,
    1.21 +					    SIGIO, POLL_IN);
    1.22  			}
    1.23  		} else {
    1.24  			u->ring_overflow = 1;
    1.25 @@ -208,38 +209,100 @@ static ssize_t evtchn_write(struct file 
    1.26  static int evtchn_ioctl(struct inode *inode, struct file *file,
    1.27                          unsigned int cmd, unsigned long arg)
    1.28  {
    1.29 -	int rc = 0;
    1.30 +	int rc;
    1.31  	struct per_user_data *u = file->private_data;
    1.32 +	evtchn_op_t op = { 0 };
    1.33  
    1.34  	spin_lock_irq(&port_user_lock);
    1.35      
    1.36  	switch (cmd) {
    1.37 -	case EVTCHN_RESET:
    1.38 +	case IOCTL_EVTCHN_BIND_VIRQ: {
    1.39 +		struct ioctl_evtchn_bind_virq bind;
    1.40 +
    1.41 +		rc = -EFAULT;
    1.42 +		if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
    1.43 +			break;
    1.44 +
    1.45 +		op.cmd              = EVTCHNOP_bind_virq;
    1.46 +		op.u.bind_virq.virq = bind.virq;
    1.47 +		op.u.bind_virq.vcpu = 0;
    1.48 +		rc = HYPERVISOR_event_channel_op(&op);
    1.49 +		if (rc != 0)
    1.50 +			break;
    1.51 +
    1.52 +		rc = op.u.bind_virq.port;
    1.53 +		port_user[rc] = u;
    1.54 +		unmask_evtchn(rc);
    1.55 +		break;
    1.56 +	}
    1.57 +
    1.58 +	case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
    1.59 +		struct ioctl_evtchn_bind_interdomain bind;
    1.60 +
    1.61 +		rc = -EFAULT;
    1.62 +		if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
    1.63 +			break;
    1.64 +
    1.65 +		op.cmd                      = EVTCHNOP_bind_interdomain;
    1.66 +		op.u.bind_interdomain.dom1  = DOMID_SELF;
    1.67 +		op.u.bind_interdomain.dom2  = bind.remote_domain;
    1.68 +		op.u.bind_interdomain.port1 = 0;
    1.69 +		op.u.bind_interdomain.port2 = bind.remote_port;
    1.70 +		rc = HYPERVISOR_event_channel_op(&op);
    1.71 +		if (rc != 0)
    1.72 +			break;
    1.73 +
    1.74 +		rc = op.u.bind_interdomain.port1;
    1.75 +		port_user[rc] = u;
    1.76 +		unmask_evtchn(rc);
    1.77 +		break;
    1.78 +	}
    1.79 +
    1.80 +	case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
    1.81 +		struct ioctl_evtchn_bind_unbound_port bind;
    1.82 +
    1.83 +		rc = -EFAULT;
    1.84 +		if (copy_from_user(&bind, (void *)arg, sizeof(bind)))
    1.85 +			break;
    1.86 +
    1.87 +		op.cmd                        = EVTCHNOP_alloc_unbound;
    1.88 +		op.u.alloc_unbound.dom        = DOMID_SELF;
    1.89 +		op.u.alloc_unbound.remote_dom = bind.remote_domain;
    1.90 +		rc = HYPERVISOR_event_channel_op(&op);
    1.91 +		if (rc != 0)
    1.92 +			break;
    1.93 +
    1.94 +		rc = op.u.alloc_unbound.port;
    1.95 +		port_user[rc] = u;
    1.96 +		unmask_evtchn(rc);
    1.97 +		break;
    1.98 +	}
    1.99 +
   1.100 +	case IOCTL_EVTCHN_UNBIND: {
   1.101 +		struct ioctl_evtchn_unbind unbind;
   1.102 +
   1.103 +		rc = -EFAULT;
   1.104 +		if (copy_from_user(&unbind, (void *)arg, sizeof(unbind)))
   1.105 +			break;
   1.106 +
   1.107 +		if (unbind.port >= NR_EVENT_CHANNELS) {
   1.108 +			rc = -EINVAL;
   1.109 +		} else if (port_user[unbind.port] != u) {
   1.110 +			rc = -ENOTCONN;
   1.111 +		} else {
   1.112 +			port_user[unbind.port] = NULL;
   1.113 +			mask_evtchn(unbind.port);
   1.114 +			rc = 0;
   1.115 +		}
   1.116 +		break;
   1.117 +	}
   1.118 +
   1.119 +	case IOCTL_EVTCHN_RESET: {
   1.120  		/* Initialise the ring to empty. Clear errors. */
   1.121  		u->ring_cons = u->ring_prod = u->ring_overflow = 0;
   1.122 +		rc = 0;
   1.123  		break;
   1.124 -
   1.125 -	case EVTCHN_BIND:
   1.126 -		if (arg >= NR_EVENT_CHANNELS) {
   1.127 -			rc = -EINVAL;
   1.128 -		} else if (port_user[arg] != NULL) {
   1.129 -			rc = -EISCONN;
   1.130 -		} else {
   1.131 -			port_user[arg] = u;
   1.132 -			unmask_evtchn(arg);
   1.133 -		}
   1.134 -		break;
   1.135 -
   1.136 -	case EVTCHN_UNBIND:
   1.137 -		if (arg >= NR_EVENT_CHANNELS) {
   1.138 -			rc = -EINVAL;
   1.139 -		} else if (port_user[arg] != u) {
   1.140 -			rc = -ENOTCONN;
   1.141 -		} else {
   1.142 -			port_user[arg] = NULL;
   1.143 -			mask_evtchn(arg);
   1.144 -		}
   1.145 -		break;
   1.146 +	}
   1.147  
   1.148  	default:
   1.149  		rc = -ENOSYS;
   1.150 @@ -295,6 +358,7 @@ static int evtchn_release(struct inode *
   1.151  {
   1.152  	int i;
   1.153  	struct per_user_data *u = filp->private_data;
   1.154 +	evtchn_op_t op = { 0 };
   1.155  
   1.156  	spin_lock_irq(&port_user_lock);
   1.157  
   1.158 @@ -302,11 +366,16 @@ static int evtchn_release(struct inode *
   1.159  
   1.160  	for (i = 0; i < NR_EVENT_CHANNELS; i++)
   1.161  	{
   1.162 -		if (port_user[i] == u)
   1.163 -		{
   1.164 -			port_user[i] = NULL;
   1.165 -			mask_evtchn(i);
   1.166 -		}
   1.167 +		if (port_user[i] != u)
   1.168 +			continue;
   1.169 +
   1.170 +		port_user[i] = NULL;
   1.171 +		mask_evtchn(i);
   1.172 +
   1.173 +		op.cmd          = EVTCHNOP_close;
   1.174 +		op.u.close.dom  = DOMID_SELF;
   1.175 +		op.u.close.port = i;
   1.176 +		BUG_ON(HYPERVISOR_event_channel_op(&op));
   1.177  	}
   1.178  
   1.179  	spin_unlock_irq(&port_user_lock);
     2.1 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Thu Oct 06 15:12:31 2005 +0100
     2.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h	Thu Oct 06 16:07:52 2005 +0100
     2.3 @@ -129,21 +129,6 @@ static inline void notify_remote_via_evt
     2.4  	(void)HYPERVISOR_event_channel_op(&op);
     2.5  }
     2.6  
     2.7 -/*
     2.8 - * CHARACTER-DEVICE DEFINITIONS
     2.9 - */
    2.10 -
    2.11 -/* /dev/xen/evtchn resides at device number major=10, minor=201 */
    2.12 -#define EVTCHN_MINOR 201
    2.13 -
    2.14 -/* /dev/xen/evtchn ioctls: */
    2.15 -/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
    2.16 -#define EVTCHN_RESET  _IO('E', 1)
    2.17 -/* EVTCHN_BIND: Bind to teh specified event-channel port. */
    2.18 -#define EVTCHN_BIND   _IO('E', 2)
    2.19 -/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
    2.20 -#define EVTCHN_UNBIND _IO('E', 3)
    2.21 -
    2.22  #endif /* __ASM_EVTCHN_H__ */
    2.23  
    2.24  /*
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h	Thu Oct 06 16:07:52 2005 +0100
     3.3 @@ -0,0 +1,89 @@
     3.4 +/******************************************************************************
     3.5 + * evtchn.h
     3.6 + * 
     3.7 + * Interface to /dev/xen/evtchn.
     3.8 + * 
     3.9 + * Copyright (c) 2003-2005, K A Fraser
    3.10 + * 
    3.11 + * This file may be distributed separately from the Linux kernel, or
    3.12 + * incorporated into other software packages, subject to the following license:
    3.13 + * 
    3.14 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    3.15 + * of this source file (the "Software"), to deal in the Software without
    3.16 + * restriction, including without limitation the rights to use, copy, modify,
    3.17 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
    3.18 + * and to permit persons to whom the Software is furnished to do so, subject to
    3.19 + * the following conditions:
    3.20 + * 
    3.21 + * The above copyright notice and this permission notice shall be included in
    3.22 + * all copies or substantial portions of the Software.
    3.23 + * 
    3.24 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    3.25 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    3.26 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    3.27 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    3.28 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    3.29 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    3.30 + * IN THE SOFTWARE.
    3.31 + */
    3.32 +
    3.33 +#ifndef __LINUX_PUBLIC_EVTCHN_H__
    3.34 +#define __LINUX_PUBLIC_EVTCHN_H__
    3.35 +
    3.36 +/* /dev/xen/evtchn resides at device number major=10, minor=201 */
    3.37 +#define EVTCHN_MINOR 201
    3.38 +
    3.39 +/*
    3.40 + * Bind a fresh port to VIRQ @virq.
    3.41 + * Return allocated port.
    3.42 + */
    3.43 +#define IOCTL_EVTCHN_BIND_VIRQ				\
    3.44 +	_IOC(_IOC_NONE, 'E', 0, sizeof(struct ioctl_evtchn_bind_virq))
    3.45 +struct ioctl_evtchn_bind_virq {
    3.46 +	unsigned int virq;
    3.47 +};
    3.48 +
    3.49 +/*
    3.50 + * Bind a fresh port to remote <@remote_domain, @remote_port>.
    3.51 + * Return allocated port.
    3.52 + */
    3.53 +#define IOCTL_EVTCHN_BIND_INTERDOMAIN			\
    3.54 +	_IOC(_IOC_NONE, 'E', 1, sizeof(struct ioctl_evtchn_bind_interdomain))
    3.55 +struct ioctl_evtchn_bind_interdomain {
    3.56 +	unsigned int remote_domain, remote_port;
    3.57 +};
    3.58 +
    3.59 +/*
    3.60 + * Allocate a fresh port for binding to @remote_domain.
    3.61 + * Return allocated port.
    3.62 + */
    3.63 +#define IOCTL_EVTCHN_BIND_UNBOUND_PORT			\
    3.64 +	_IOC(_IOC_NONE, 'E', 2, sizeof(struct ioctl_evtchn_bind_unbound_port))
    3.65 +struct ioctl_evtchn_bind_unbound_port {
    3.66 +	unsigned int remote_domain;
    3.67 +};
    3.68 +
    3.69 +/*
    3.70 + * Unbind previously allocated @port.
    3.71 + */
    3.72 +#define IOCTL_EVTCHN_UNBIND				\
    3.73 +	_IOC(_IOC_NONE, 'E', 3, sizeof(struct ioctl_evtchn_unbind))
    3.74 +struct ioctl_evtchn_unbind {
    3.75 +	unsigned int port;
    3.76 +};
    3.77 +
    3.78 +/* Clear and reinitialise the event buffer. Clear error condition. */
    3.79 +#define IOCTL_EVTCHN_RESET				\
    3.80 +	_IOC(_IOC_NONE, 'E', 4, 0)
    3.81 +
    3.82 +#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
    3.83 +
    3.84 +/*
    3.85 + * Local variables:
    3.86 + *  c-file-style: "linux"
    3.87 + *  indent-tabs-mode: t
    3.88 + *  c-indent-level: 8
    3.89 + *  c-basic-offset: 8
    3.90 + *  tab-width: 8
    3.91 + * End:
    3.92 + */
     4.1 --- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Thu Oct 06 15:12:31 2005 +0100
     4.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h	Thu Oct 06 16:07:52 2005 +0100
     4.3 @@ -3,7 +3,7 @@
     4.4   * 
     4.5   * Interface to /proc/xen/privcmd.
     4.6   * 
     4.7 - * Copyright (c) 2003-2004, K A Fraser
     4.8 + * Copyright (c) 2003-2005, K A Fraser
     4.9   * 
    4.10   * This file may be distributed separately from the Linux kernel, or
    4.11   * incorporated into other software packages, subject to the following license:
    4.12 @@ -27,39 +27,39 @@
    4.13   * IN THE SOFTWARE.
    4.14   */
    4.15  
    4.16 -#ifndef __PRIVCMD_H__
    4.17 -#define __PRIVCMD_H__
    4.18 +#ifndef __LINUX_PUBLIC_PRIVCMD_H__
    4.19 +#define __LINUX_PUBLIC_PRIVCMD_H__
    4.20  
    4.21  typedef struct privcmd_hypercall
    4.22  {
    4.23 -    unsigned long op;
    4.24 -    unsigned long arg[5];
    4.25 +	unsigned long op;
    4.26 +	unsigned long arg[5];
    4.27  } privcmd_hypercall_t;
    4.28  
    4.29  typedef struct privcmd_mmap_entry {
    4.30 -    unsigned long va;
    4.31 -    unsigned long mfn;
    4.32 -    unsigned long npages;
    4.33 +	unsigned long va;
    4.34 +	unsigned long mfn;
    4.35 +	unsigned long npages;
    4.36  } privcmd_mmap_entry_t; 
    4.37  
    4.38  typedef struct privcmd_mmap {
    4.39 -    int num;
    4.40 -    domid_t dom; /* target domain */
    4.41 -    privcmd_mmap_entry_t *entry;
    4.42 +	int num;
    4.43 +	domid_t dom; /* target domain */
    4.44 +	privcmd_mmap_entry_t *entry;
    4.45  } privcmd_mmap_t; 
    4.46  
    4.47  typedef struct privcmd_mmapbatch {
    4.48 -    int num;     /* number of pages to populate */
    4.49 -    domid_t dom; /* target domain */
    4.50 -    unsigned long addr;  /* virtual address */
    4.51 -    unsigned long *arr; /* array of mfns - top nibble set on err */
    4.52 +	int num;     /* number of pages to populate */
    4.53 +	domid_t dom; /* target domain */
    4.54 +	unsigned long addr;  /* virtual address */
    4.55 +	unsigned long *arr; /* array of mfns - top nibble set on err */
    4.56  } privcmd_mmapbatch_t; 
    4.57  
    4.58  typedef struct privcmd_blkmsg
    4.59  {
    4.60 -    unsigned long op;
    4.61 -    void         *buf;
    4.62 -    int           buf_size;
    4.63 +	unsigned long op;
    4.64 +	void         *buf;
    4.65 +	int           buf_size;
    4.66  } privcmd_blkmsg_t;
    4.67  
    4.68  /*
    4.69 @@ -67,16 +67,26 @@ typedef struct privcmd_blkmsg
    4.70   * @arg: &privcmd_hypercall_t
    4.71   * Return: Value returned from execution of the specified hypercall.
    4.72   */
    4.73 -#define IOCTL_PRIVCMD_HYPERCALL         \
    4.74 -    _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
    4.75 +#define IOCTL_PRIVCMD_HYPERCALL					\
    4.76 +	_IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
    4.77  
    4.78 -#define IOCTL_PRIVCMD_MMAP             \
    4.79 -    _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
    4.80 -#define IOCTL_PRIVCMD_MMAPBATCH             \
    4.81 -    _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
    4.82 -#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN \
    4.83 -    _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
    4.84 -#define IOCTL_PRIVCMD_INITDOMAIN_STORE \
    4.85 -    _IOC(_IOC_READ, 'P', 5, 0)
    4.86 +#define IOCTL_PRIVCMD_MMAP					\
    4.87 +	_IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
    4.88 +#define IOCTL_PRIVCMD_MMAPBATCH					\
    4.89 +	_IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
    4.90 +#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN			\
    4.91 +	_IOC(_IOC_READ, 'P', 4, sizeof(unsigned long))
    4.92 +#define IOCTL_PRIVCMD_INITDOMAIN_STORE				\
    4.93 +	_IOC(_IOC_READ, 'P', 5, 0)
    4.94  
    4.95 -#endif /* __PRIVCMD_H__ */
    4.96 +#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
    4.97 +
    4.98 +/*
    4.99 + * Local variables:
   4.100 + *  c-file-style: "linux"
   4.101 + *  indent-tabs-mode: t
   4.102 + *  c-indent-level: 8
   4.103 + *  c-basic-offset: 8
   4.104 + *  tab-width: 8
   4.105 + * End:
   4.106 + */
     5.1 --- a/tools/console/daemon/io.c	Thu Oct 06 15:12:31 2005 +0100
     5.2 +++ b/tools/console/daemon/io.c	Thu Oct 06 16:07:52 2005 +0100
     5.3 @@ -1,4 +1,4 @@
     5.4 -/*\
     5.5 +/*
     5.6   *  Copyright (C) International Business Machines  Corp., 2005
     5.7   *  Author(s): Anthony Liguori <aliguori@us.ibm.com>
     5.8   *
     5.9 @@ -16,14 +16,15 @@
    5.10   *  You should have received a copy of the GNU General Public License
    5.11   *  along with this program; if not, write to the Free Software
    5.12   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    5.13 -\*/
    5.14 + */
    5.15  
    5.16  #define _GNU_SOURCE
    5.17  
    5.18  #include "utils.h"
    5.19  #include "io.h"
    5.20 -#include "xenctrl.h"
    5.21 -#include "xs.h"
    5.22 +#include <xenctrl.h>
    5.23 +#include <xs.h>
    5.24 +#include <xen/linux/evtchn.h>
    5.25  
    5.26  #include <malloc.h>
    5.27  #include <stdlib.h>
    5.28 @@ -225,16 +226,14 @@ int xs_gather(struct xs_handle *xs, cons
    5.29  	return ret;
    5.30  }
    5.31  
    5.32 -#define EVENTCHN_BIND		_IO('E', 2)
    5.33 -#define EVENTCHN_UNBIND 	_IO('E', 3)
    5.34 -
    5.35  static int domain_create_ring(struct domain *dom)
    5.36  {
    5.37 -	int err, local_port, ring_ref;
    5.38 +	int err, remote_port, ring_ref, rc;
    5.39 +	struct ioctl_evtchn_bind_interdomain bind;
    5.40  
    5.41  	err = xs_gather(xs, dom->conspath,
    5.42  			"ring-ref", "%u", &ring_ref,
    5.43 -			"port", "%i", &local_port,
    5.44 +			"port", "%i", &remote_port,
    5.45  			NULL);
    5.46  	if (err)
    5.47  		goto out;
    5.48 @@ -252,26 +251,28 @@ static int domain_create_ring(struct dom
    5.49  		dom->ring_ref = ring_ref;
    5.50  	}
    5.51  
    5.52 -	if (local_port != dom->local_port) {
    5.53 -		dom->local_port = -1;
    5.54 -		if (dom->evtchn_fd != -1)
    5.55 -			close(dom->evtchn_fd);
    5.56 -		/* Opening evtchn independently for each console is a bit
    5.57 -		 * wastefule, but that's how the code is structured... */
    5.58 -		dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
    5.59 -		if (dom->evtchn_fd == -1) {
    5.60 -			err = errno;
    5.61 -			goto out;
    5.62 -		}
    5.63 +	dom->local_port = -1;
    5.64 +	if (dom->evtchn_fd != -1)
    5.65 +		close(dom->evtchn_fd);
    5.66 +
    5.67 +	/* Opening evtchn independently for each console is a bit
    5.68 +	 * wasteful, but that's how the code is structured... */
    5.69 +	dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
    5.70 +	if (dom->evtchn_fd == -1) {
    5.71 +		err = errno;
    5.72 +		goto out;
    5.73 +	}
    5.74   
    5.75 -		if (ioctl(dom->evtchn_fd, EVENTCHN_BIND, local_port) == -1) {
    5.76 -			err = errno;
    5.77 -			close(dom->evtchn_fd);
    5.78 -			dom->evtchn_fd = -1;
    5.79 -			goto out;
    5.80 -		}
    5.81 -		dom->local_port = local_port;
    5.82 +	bind.remote_domain = dom->domid;
    5.83 +	bind.remote_port   = remote_port;
    5.84 +	rc = ioctl(dom->evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
    5.85 +	if (rc == -1) {
    5.86 +		err = errno;
    5.87 +		close(dom->evtchn_fd);
    5.88 +		dom->evtchn_fd = -1;
    5.89 +		goto out;
    5.90  	}
    5.91 +	dom->local_port = rc;
    5.92  
    5.93   out:
    5.94  	return err;
     6.1 --- a/tools/debugger/pdb/pdb_xen.c	Thu Oct 06 15:12:31 2005 +0100
     6.2 +++ b/tools/debugger/pdb/pdb_xen.c	Thu Oct 06 16:07:52 2005 +0100
     6.3 @@ -43,11 +43,7 @@ pdb_close (int xc_handle)
     6.4  
     6.5  
     6.6  #include <sys/ioctl.h>
     6.7 -
     6.8 -/* /dev/xen/evtchn ioctls */
     6.9 -#define EVTCHN_RESET  _IO('E', 1)                   /* clear & reinit buffer */
    6.10 -#define EVTCHN_BIND   _IO('E', 2)                   /* bind to event channel */
    6.11 -#define EVTCHN_UNBIND _IO('E', 3)               /* unbind from event channel */
    6.12 +#include <xen/linux/evtchn.h>
    6.13  
    6.14  int
    6.15  xen_evtchn_bind (int evtchn_fd, int idx)
     7.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Thu Oct 06 15:12:31 2005 +0100
     7.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Thu Oct 06 16:07:52 2005 +0100
     7.3 @@ -49,11 +49,14 @@
     7.4  
     7.5  #include <xenctrl.h>
     7.6  #include <xen/io/ioreq.h>
     7.7 +#include <xen/linux/evtchn.h>
     7.8  
     7.9  #include "cpu.h"
    7.10  #include "exec-all.h"
    7.11  #include "vl.h"
    7.12  
    7.13 +extern int domid;
    7.14 +
    7.15  void *shared_vram;
    7.16  
    7.17  shared_iopage_t *shared_page = NULL;
    7.18 @@ -119,7 +122,7 @@ target_ulong cpu_get_phys_page_debug(CPU
    7.19  //the evtchn fd for polling
    7.20  int evtchn_fd = -1;
    7.21  //the evtchn port for polling the notification, should be inputed as bochs's parameter
    7.22 -u16 ioreq_port = 0;
    7.23 +u16 ioreq_remote_port, ioreq_local_port;
    7.24  
    7.25  //some functions to handle the io req packet
    7.26  void
    7.27 @@ -156,9 +159,9 @@ ioreq_t* cpu_get_ioreq(void)
    7.28  	int rc;
    7.29  	u16 buf[2];
    7.30  	rc = read(evtchn_fd, buf, 2);
    7.31 -	if (rc == 2 && buf[0] == ioreq_port){//got only one matched 16bit port index
    7.32 +	if (rc == 2 && buf[0] == ioreq_local_port){//got only one matched 16bit port index
    7.33  		// unmask the wanted port again
    7.34 -		write(evtchn_fd, &ioreq_port, 2);
    7.35 +		write(evtchn_fd, &ioreq_local_port, 2);
    7.36  
    7.37  		//get the io packet from shared memory
    7.38  		return __cpu_get_ioreq();
    7.39 @@ -417,7 +420,6 @@ do_interrupt(CPUState *env, int vector)
    7.40  void
    7.41  destroy_vmx_domain(void)
    7.42  {
    7.43 -    extern int domid;
    7.44      extern FILE* logfile;
    7.45      char destroy_cmd[20];
    7.46      sprintf(destroy_cmd, "xm destroy %d", domid);
    7.47 @@ -485,9 +487,9 @@ int main_loop(void)
    7.48  #endif
    7.49  		if (env->send_event) {
    7.50  			int ret;
    7.51 -			ret = xc_evtchn_send(xc_handle, ioreq_port);
    7.52 +			ret = xc_evtchn_send(xc_handle, ioreq_local_port);
    7.53  			if (ret == -1) {
    7.54 -				fprintf(logfile, "evtchn_send failed on port: %d\n", ioreq_port);
    7.55 +				fprintf(logfile, "evtchn_send failed on port: %d\n", ioreq_local_port);
    7.56  			}
    7.57  		}
    7.58  	}
    7.59 @@ -499,7 +501,6 @@ static void
    7.60  qemu_vmx_reset(void *unused)
    7.61  {
    7.62      char cmd[255];
    7.63 -    extern int domid;
    7.64  
    7.65      /* pause domain first, to avoid repeated reboot request*/ 
    7.66      xc_domain_pause (xc_handle, domid);
    7.67 @@ -512,6 +513,8 @@ CPUState *
    7.68  cpu_init()
    7.69  {
    7.70  	CPUX86State *env;
    7.71 +	struct ioctl_evtchn_bind_interdomain bind;
    7.72 +	int rc;
    7.73        
    7.74          cpu_exec_init();
    7.75          qemu_register_reset(qemu_vmx_reset, NULL);
    7.76 @@ -532,12 +535,14 @@ cpu_init()
    7.77  		return NULL;
    7.78  	}
    7.79  
    7.80 -	fprintf(logfile, "listening to port: %d\n", ioreq_port);
    7.81 -	/*unmask the wanted port -- bind*/
    7.82 -	if (ioctl(evtchn_fd, ('E'<<8)|2, ioreq_port) == -1) {
    7.83 +	bind.remote_domain = domid;
    7.84 +	bind.remote_port   = ioreq_remote_port;
    7.85 +	rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
    7.86 +	if (rc == -1) {
    7.87  		perror("ioctl");
    7.88  		return NULL;
    7.89  	}
    7.90 +	ioreq_local_port = rc;
    7.91  
    7.92  	return env;
    7.93  }
     8.1 --- a/tools/ioemu/vl.c	Thu Oct 06 15:12:31 2005 +0100
     8.2 +++ b/tools/ioemu/vl.c	Thu Oct 06 16:07:52 2005 +0100
     8.3 @@ -2806,9 +2806,9 @@ int main(int argc, char **argv)
     8.4  
     8.5              case QEMU_OPTION_p:
     8.6                  {
     8.7 -                  extern short ioreq_port;
     8.8 -                  ioreq_port = atoi(optarg);
     8.9 -                  printf("port: %d\n", ioreq_port);
    8.10 +                  extern short ioreq_remote_port;
    8.11 +                  ioreq_remote_port = atoi(optarg);
    8.12 +                  printf("port: %d\n", ioreq_remote_port);
    8.13                  }
    8.14                  break;
    8.15              case QEMU_OPTION_l:
     9.1 --- a/tools/python/xen/lowlevel/xc/xc.c	Thu Oct 06 15:12:31 2005 +0100
     9.2 +++ b/tools/python/xen/lowlevel/xc/xc.c	Thu Oct 06 16:07:52 2005 +0100
     9.3 @@ -435,10 +435,10 @@ static PyObject *pyxc_evtchn_alloc_unbou
     9.4      u32 dom = DOMID_SELF, remote_dom;
     9.5      int port = 0;
     9.6  
     9.7 -    static char *kwd_list[] = { "remote_dom", "dom", "port", NULL };
     9.8 +    static char *kwd_list[] = { "remote_dom", "dom", NULL };
     9.9  
    9.10 -    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list,
    9.11 -                                      &remote_dom, &dom, &port) )
    9.12 +    if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list,
    9.13 +                                      &remote_dom, &dom) )
    9.14          return NULL;
    9.15  
    9.16      if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 )
    10.1 --- a/tools/python/xen/xend/XendCheckpoint.py	Thu Oct 06 15:12:31 2005 +0100
    10.2 +++ b/tools/python/xen/xend/XendCheckpoint.py	Thu Oct 06 16:07:52 2005 +0100
    10.3 @@ -126,8 +126,8 @@ def restore(xd, fd):
    10.4              raise XendError(
    10.5                  "not a valid guest state file: pfn count out of range")
    10.6  
    10.7 -        store_evtchn = dominfo.store_channel.port2
    10.8 -        console_evtchn = dominfo.console_channel.port2
    10.9 +        store_evtchn = dominfo.store_channel
   10.10 +        console_evtchn = dominfo.console_channel
   10.11  
   10.12          cmd = [PATH_XC_RESTORE, str(xc.handle()), str(fd),
   10.13                 str(dominfo.getDomid()), str(nr_pfns),
   10.14 @@ -146,7 +146,7 @@ def restore(xd, fd):
   10.15                            dominfo.getDomainPath())
   10.16                  IntroduceDomain(dominfo.getDomid(),
   10.17                                  store_mfn,
   10.18 -                                dominfo.store_channel.port1,
   10.19 +                                dominfo.store_channel,
   10.20                                  dominfo.getDomainPath())
   10.21              else:
   10.22                  m = re.match(r"^(console-mfn) (\d+)$", line)
    11.1 --- a/tools/python/xen/xend/XendDomainInfo.py	Thu Oct 06 15:12:31 2005 +0100
    11.2 +++ b/tools/python/xen/xend/XendDomainInfo.py	Thu Oct 06 16:07:52 2005 +0100
    11.3 @@ -32,8 +32,6 @@ import errno
    11.4  import xen.lowlevel.xc
    11.5  from xen.util.blkif import blkdev_uname_to_file
    11.6  
    11.7 -from xen.xend.server import channel
    11.8 -
    11.9  from xen.xend import image
   11.10  from xen.xend import scheduler
   11.11  from xen.xend import sxp
   11.12 @@ -785,32 +783,6 @@ class XendDomainInfo:
   11.13                            self.domid, self.info['name'])
   11.14  
   11.15  
   11.16 -    def closeChannel(self, chan, entry):
   11.17 -        """Close the given channel, if set, and remove the given entry in the
   11.18 -        store.  Nothrow guarantee."""
   11.19 -        
   11.20 -        if chan:
   11.21 -            chan.close()
   11.22 -        try:
   11.23 -            self.removeDom(entry)
   11.24 -        except:
   11.25 -            log.exception('Removing entry %s failed', entry)
   11.26 -        
   11.27 -
   11.28 -    def closeStoreChannel(self):
   11.29 -        """Close the store channel, if any.  Nothrow guarantee."""
   11.30 -
   11.31 -        self.closeChannel(self.store_channel, "store/port")
   11.32 -        self.store_channel = None
   11.33 -
   11.34 -
   11.35 -    def closeConsoleChannel(self):
   11.36 -        """Close the console channel, if any.  Nothrow guarantee."""
   11.37 -
   11.38 -        self.closeChannel(self.console_channel, "console/port")
   11.39 -        self.console_channel = None
   11.40 -
   11.41 -
   11.42      ## public:
   11.43  
   11.44      def setConsoleRef(self, ref):
   11.45 @@ -960,12 +932,8 @@ class XendDomainInfo:
   11.46              sxpr.append(['up_time', str(up_time) ])
   11.47              sxpr.append(['start_time', str(self.info['start_time']) ])
   11.48  
   11.49 -        if self.store_channel:
   11.50 -            sxpr.append(self.store_channel.sxpr())
   11.51          if self.store_mfn:
   11.52              sxpr.append(['store_mfn', self.store_mfn])
   11.53 -        if self.console_channel:
   11.54 -            sxpr.append(['console_channel', self.console_channel.sxpr()])
   11.55          if self.console_mfn:
   11.56              sxpr.append(['console_mfn', self.console_mfn])
   11.57  
   11.58 @@ -1073,7 +1041,7 @@ class XendDomainInfo:
   11.59          self.create_channel()
   11.60          self.image.createImage()
   11.61          IntroduceDomain(self.domid, self.store_mfn,
   11.62 -                        self.store_channel.port1, self.dompath)
   11.63 +                        self.store_channel, self.dompath)
   11.64  
   11.65  
   11.66      ## public:
   11.67 @@ -1083,8 +1051,6 @@ class XendDomainInfo:
   11.68          guarantee."""
   11.69  
   11.70          self.release_devices()
   11.71 -        self.closeStoreChannel()
   11.72 -        self.closeConsoleChannel()
   11.73  
   11.74          if self.image:
   11.75              try:
   11.76 @@ -1164,35 +1130,22 @@ class XendDomainInfo:
   11.77          
   11.78          @param path under which port is stored in db
   11.79          """
   11.80 -        port = 0
   11.81          if path:
   11.82              try:
   11.83 -                port = int(self.readDom(path))
   11.84 +                return int(self.readDom(path))
   11.85              except:
   11.86                  # The port is not yet set, i.e. the channel has not yet been
   11.87                  # created.
   11.88                  pass
   11.89  
   11.90 -        # Stale port information from above causes an Invalid Argument to be
   11.91 -        # thrown by the eventChannel call below.  To recover, we throw away
   11.92 -        # port if it turns out to be bad, and just create a new channel.
   11.93 -        # If creating a new channel with two new ports fails, then something
   11.94 -        # else is going wrong, so we bail.
   11.95 -        while True:
   11.96 -            try:
   11.97 -                ret = channel.eventChannel(0, self.domid, port1 = port,
   11.98 -                                           port2 = 0)
   11.99 -                break
  11.100 -            except:
  11.101 -                log.exception("Exception in eventChannel(0, %d, %d, %d)",
  11.102 -                              self.domid, port, 0)
  11.103 -                if port == 0:
  11.104 -                    raise
  11.105 -                else:
  11.106 -                    port = 0
  11.107 -                    log.error("Recovering from above exception.")
  11.108 -        self.storeDom(path, ret.port1)
  11.109 -        return ret
  11.110 +        try:
  11.111 +            port = xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0)
  11.112 +        except:
  11.113 +            log.exception("Exception in alloc_unbound(%d)", self.domid)
  11.114 +            raise
  11.115 +
  11.116 +        self.storeDom(path, port)
  11.117 +        return port
  11.118  
  11.119      def create_channel(self):
  11.120          """Create the channels to the domain.
  11.121 @@ -1419,11 +1372,11 @@ class XendDomainInfo:
  11.122  
  11.123  
  11.124      def initStoreConnection(self):
  11.125 -        ref = xc.init_store(self.store_channel.port2)
  11.126 +        ref = xc.init_store(self.store_channel)
  11.127          if ref and ref >= 0:
  11.128              self.setStoreRef(ref)
  11.129              try:
  11.130 -                IntroduceDomain(self.domid, ref, self.store_channel.port1,
  11.131 +                IntroduceDomain(self.domid, ref, self.store_channel,
  11.132                                  self.dompath)
  11.133              except RuntimeError, ex:
  11.134                  if ex.args[0] == errno.EISCONN:
    12.1 --- a/tools/python/xen/xend/image.py	Thu Oct 06 15:12:31 2005 +0100
    12.2 +++ b/tools/python/xen/xend/image.py	Thu Oct 06 16:07:52 2005 +0100
    12.3 @@ -25,8 +25,6 @@ from xen.xend import sxp
    12.4  from xen.xend.XendError import VmError
    12.5  from xen.xend.XendLogging import log
    12.6  
    12.7 -from xen.xend.server import channel
    12.8 -
    12.9  
   12.10  xc = xen.lowlevel.xc.new()
   12.11  
   12.12 @@ -168,11 +166,11 @@ class LinuxImageHandler(ImageHandler):
   12.13  
   12.14      def buildDomain(self):
   12.15          if self.vm.store_channel:
   12.16 -            store_evtchn = self.vm.store_channel.port2
   12.17 +            store_evtchn = self.vm.store_channel
   12.18          else:
   12.19              store_evtchn = 0
   12.20          if self.vm.console_channel:
   12.21 -            console_evtchn = self.vm.console_channel.port2
   12.22 +            console_evtchn = self.vm.console_channel
   12.23          else:
   12.24              console_evtchn = 0
   12.25  
   12.26 @@ -228,16 +226,17 @@ class VmxImageHandler(ImageHandler):
   12.27  
   12.28      def buildDomain(self):
   12.29          # Create an event channel
   12.30 -        self.device_channel = channel.eventChannel(0, self.vm.getDomid())
   12.31 -        log.info("VMX device model port: %d", self.device_channel.port2)
   12.32 +        self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
   12.33 +                                                      remote_dom=0)
   12.34 +        log.info("VMX device model port: %d", self.device_channel)
   12.35          if self.vm.store_channel:
   12.36 -            store_evtchn = self.vm.store_channel.port2
   12.37 +            store_evtchn = self.vm.store_channel
   12.38          else:
   12.39              store_evtchn = 0
   12.40  
   12.41          log.debug("dom            = %d", self.vm.getDomid())
   12.42          log.debug("image          = %s", self.kernel)
   12.43 -        log.debug("control_evtchn = %d", self.device_channel.port2)
   12.44 +        log.debug("control_evtchn = %d", self.device_channel)
   12.45          log.debug("store_evtchn   = %d", store_evtchn)
   12.46          log.debug("memsize        = %d", self.vm.getMemoryTarget() / 1024)
   12.47          log.debug("flags          = %d", self.flags)
   12.48 @@ -245,7 +244,7 @@ class VmxImageHandler(ImageHandler):
   12.49  
   12.50          ret = xc.vmx_build(dom            = self.vm.getDomid(),
   12.51                             image          = self.kernel,
   12.52 -                           control_evtchn = self.device_channel.port2,
   12.53 +                           control_evtchn = self.device_channel,
   12.54                             store_evtchn   = store_evtchn,
   12.55                             memsize        = self.vm.getMemoryTarget() / 1024,
   12.56                             flags          = self.flags,
   12.57 @@ -334,7 +333,7 @@ class VmxImageHandler(ImageHandler):
   12.58          if len(vnc):
   12.59              args = args + vnc
   12.60          args = args + ([ "-d",  "%d" % self.vm.getDomid(),
   12.61 -                  "-p", "%d" % self.device_channel.port1,
   12.62 +                  "-p", "%d" % self.device_channel,
   12.63                    "-m", "%s" % (self.vm.getMemoryTarget() / 1024)])
   12.64          args = args + self.dmargs
   12.65          env = dict(os.environ)
   12.66 @@ -358,8 +357,6 @@ class VmxImageHandler(ImageHandler):
   12.67          return vncconnect
   12.68  
   12.69      def destroy(self):
   12.70 -        if self.device_channel:
   12.71 -            self.device_channel.close()
   12.72          import signal
   12.73          if not self.pid:
   12.74              return
    13.1 --- a/tools/python/xen/xend/server/channel.py	Thu Oct 06 15:12:31 2005 +0100
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,76 +0,0 @@
    13.4 -#============================================================================
    13.5 -# This library is free software; you can redistribute it and/or
    13.6 -# modify it under the terms of version 2.1 of the GNU Lesser General Public
    13.7 -# License as published by the Free Software Foundation.
    13.8 -#
    13.9 -# This library is distributed in the hope that it will be useful,
   13.10 -# but WITHOUT ANY WARRANTY; without even the implied warranty of
   13.11 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13.12 -# Lesser General Public License for more details.
   13.13 -#
   13.14 -# You should have received a copy of the GNU Lesser General Public
   13.15 -# License along with this library; if not, write to the Free Software
   13.16 -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   13.17 -#============================================================================
   13.18 -# Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
   13.19 -# Copyright (C) 2005 XenSource Ltd
   13.20 -#============================================================================
   13.21 -
   13.22 -import xen.lowlevel.xc
   13.23 -
   13.24 -from xen.xend.XendLogging import log
   13.25 -
   13.26 -
   13.27 -xc = xen.lowlevel.xc.new()
   13.28 -
   13.29 -
   13.30 -class EventChannel:
   13.31 -    """An event channel between domains.
   13.32 -    """
   13.33 -
   13.34 -    def __init__(self, dom1, dom2, port1, port2):
   13.35 -        self.dom1 = dom1
   13.36 -        self.dom2 = dom2
   13.37 -        self.port1 = port1
   13.38 -        self.port2 = port2
   13.39 -
   13.40 -
   13.41 -    def close(self):
   13.42 -        """Close the event channel.  Nothrow guarantee.
   13.43 -        """
   13.44 -        def evtchn_close(dom, port):
   13.45 -            try:
   13.46 -                xc.evtchn_close(dom=dom, port=port)
   13.47 -            except Exception:
   13.48 -                log.exception("Exception closing event channel %d, %d.", dom,
   13.49 -                              port)
   13.50 -            
   13.51 -        evtchn_close(self.dom1, self.port1)
   13.52 -        evtchn_close(self.dom2, self.port2)
   13.53 -
   13.54 -
   13.55 -    def sxpr(self):
   13.56 -        return ['event-channel',
   13.57 -                ['dom1',  self.dom1  ],
   13.58 -                ['port1', self.port1 ],
   13.59 -                ['dom2',  self.dom2  ],
   13.60 -                ['port2', self.port2 ]
   13.61 -                ]
   13.62 -
   13.63 -
   13.64 -    def __repr__(self):
   13.65 -        return ("<EventChannel dom1:%d:%d dom2:%d:%d>"
   13.66 -                % (self.dom1, self.port1, self.dom2, self.port2))
   13.67 -
   13.68 -
   13.69 -def eventChannel(dom1, dom2, port1 = 0, port2 = 0):
   13.70 -    """Create an event channel between domains.
   13.71 -        
   13.72 -    @return EventChannel (None on error)
   13.73 -    """
   13.74 -    v = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2,
   13.75 -                                   port1=port1, port2=port2)
   13.76 -    if v and v.get('port1'):
   13.77 -        return EventChannel(dom1, dom2, v['port1'], v['port2'])
   13.78 -    else:
   13.79 -        return None
    14.1 --- a/tools/xenstore/xenstored_domain.c	Thu Oct 06 15:12:31 2005 +0100
    14.2 +++ b/tools/xenstore/xenstored_domain.c	Thu Oct 06 16:07:52 2005 +0100
    14.3 @@ -36,6 +36,8 @@
    14.4  #include "xenstored_watch.h"
    14.5  #include "xenstored_test.h"
    14.6  
    14.7 +#include <xen/linux/evtchn.h>
    14.8 +
    14.9  static int *xc_handle;
   14.10  static int eventchn_fd;
   14.11  static int virq_port;
   14.12 @@ -77,9 +79,6 @@ struct ringbuf_head
   14.13  	char buf[0];
   14.14  } __attribute__((packed));
   14.15  
   14.16 -#define EVENTCHN_BIND		_IO('E', 2)
   14.17 -#define EVENTCHN_UNBIND 	_IO('E', 3)
   14.18 -
   14.19  /* FIXME: Mark connection as broken (close it?) when this happens. */
   14.20  static bool check_buffer(const struct ringbuf_head *h)
   14.21  {
   14.22 @@ -207,14 +206,17 @@ static int readchn(struct connection *co
   14.23  static int destroy_domain(void *_domain)
   14.24  {
   14.25  	struct domain *domain = _domain;
   14.26 +	struct ioctl_evtchn_unbind unbind;
   14.27  
   14.28  	list_del(&domain->list);
   14.29  
   14.30 -	if (domain->port &&
   14.31 -	    (ioctl(eventchn_fd, EVENTCHN_UNBIND, domain->port) != 0))
   14.32 -		eprintf("> Unbinding port %i failed!\n", domain->port);
   14.33 +	if (domain->port) {
   14.34 +		unbind.port = domain->port;
   14.35 +		if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1)
   14.36 +			eprintf("> Unbinding port %i failed!\n", domain->port);
   14.37 +	}
   14.38  
   14.39 -	if(domain->page)
   14.40 +	if (domain->page)
   14.41  		munmap(domain->page, getpagesize());
   14.42  
   14.43  	return 0;
   14.44 @@ -278,6 +280,9 @@ static struct domain *new_domain(void *c
   14.45  				 const char *path)
   14.46  {
   14.47  	struct domain *domain;
   14.48 +	struct ioctl_evtchn_bind_interdomain bind;
   14.49 +	int rc;
   14.50 +
   14.51  	domain = talloc(context, struct domain);
   14.52  	domain->port = 0;
   14.53  	domain->shutdown = 0;
   14.54 @@ -298,10 +303,13 @@ static struct domain *new_domain(void *c
   14.55  	domain->output = domain->page + getpagesize()/2;
   14.56  
   14.57  	/* Tell kernel we're interested in this event. */
   14.58 -	if (ioctl(eventchn_fd, EVENTCHN_BIND, port) != 0)
   14.59 +	bind.remote_domain = domid;
   14.60 +	bind.remote_port   = port;
   14.61 +	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
   14.62 +	if (rc == -1)
   14.63  		return NULL;
   14.64  
   14.65 -	domain->port = port;
   14.66 +	domain->port = rc;
   14.67  	domain->conn = new_connection(writechn, readchn);
   14.68  	domain->conn->domain = domain;
   14.69  	return domain;
   14.70 @@ -445,6 +453,8 @@ void restore_existing_connections(void)
   14.71  int domain_init(void)
   14.72  {
   14.73  	struct stat st;
   14.74 +	struct ioctl_evtchn_bind_virq bind;
   14.75 +	int rc;
   14.76  
   14.77  	/* The size of the ringbuffer: half a page minus head structure. */
   14.78  	ringbuf_datasize = getpagesize() / 2 - sizeof(struct ringbuf_head);
   14.79 @@ -482,11 +492,11 @@ int domain_init(void)
   14.80  	if (eventchn_fd < 0)
   14.81  		barf_perror("Failed to open evtchn device");
   14.82  
   14.83 -	if (xc_evtchn_bind_virq(*xc_handle, VIRQ_DOM_EXC, &virq_port))
   14.84 -		barf_perror("Failed to bind to domain exception virq");
   14.85 -
   14.86 -	if (ioctl(eventchn_fd, EVENTCHN_BIND, virq_port) != 0)
   14.87 +	bind.virq = VIRQ_DOM_EXC;
   14.88 +	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
   14.89 +	if (rc == -1)
   14.90  		barf_perror("Failed to bind to domain exception virq port");
   14.91 +	virq_port = rc;
   14.92  
   14.93  	return eventchn_fd;
   14.94  }
    15.1 --- a/xen/common/event_channel.c	Thu Oct 06 15:12:31 2005 +0100
    15.2 +++ b/xen/common/event_channel.c	Thu Oct 06 16:07:52 2005 +0100
    15.3 @@ -36,7 +36,13 @@
    15.4  #define evtchn_from_port(d,p) \
    15.5      (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)])
    15.6  
    15.7 -#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
    15.8 +#define ERROR_EXIT(_errno)                                          \
    15.9 +    do {                                                            \
   15.10 +        DPRINTK("EVTCHNOP failure: domain %d, error %d, line %d\n", \
   15.11 +                current->domain->domain_id, (_errno), __LINE__);    \
   15.12 +        rc = (_errno);                                              \
   15.13 +        goto out;                                                   \
   15.14 +    } while ( 0 )
   15.15  
   15.16  static int get_free_port(struct domain *d)
   15.17  {