direct-io.hg

changeset 10355:7fba181c8531

[TOOLS] Introduce xc_evtchn_*() interface for interacting with /dev/xen/evtchn.
No longer open the device as non-blocking: all reads immediately follow
a select() on the device indicating it's ready to read.

Signed-off-by: John Levon <john.levon@sun.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Jun 15 13:11:31 2006 +0100 (2006-06-15)
parents 3e221d43cf19
children 4f0bc5744557
files tools/console/daemon/io.c tools/console/daemon/utils.c tools/console/daemon/utils.h tools/ioemu/target-i386-dm/helper2.c tools/libxc/xc_linux.c tools/libxc/xenctrl.h tools/xenmon/xenbaked.c tools/xenstore/fake_libxc.c tools/xenstore/xenstored_core.c tools/xenstore/xenstored_domain.c
line diff
     1.1 --- a/tools/console/daemon/io.c	Thu Jun 15 11:52:23 2006 +0100
     1.2 +++ b/tools/console/daemon/io.c	Thu Jun 15 13:11:31 2006 +0100
     1.3 @@ -24,8 +24,8 @@
     1.4  #include "io.h"
     1.5  #include <xenctrl.h>
     1.6  #include <xs.h>
     1.7 -#include <xen/linux/evtchn.h>
     1.8  #include <xen/io/console.h>
     1.9 +#include <xenctrl.h>
    1.10  
    1.11  #include <malloc.h>
    1.12  #include <stdlib.h>
    1.13 @@ -36,7 +36,6 @@
    1.14  #include <unistd.h>
    1.15  #include <termios.h>
    1.16  #include <stdarg.h>
    1.17 -#include <sys/ioctl.h>
    1.18  #include <sys/mman.h>
    1.19  
    1.20  #define MAX(a, b) (((a) > (b)) ? (a) : (b))
    1.21 @@ -64,19 +63,12 @@ struct domain
    1.22  	char *conspath;
    1.23  	int ring_ref;
    1.24  	evtchn_port_t local_port;
    1.25 -	int evtchn_fd;
    1.26 +	int xce_handle;
    1.27  	struct xencons_interface *interface;
    1.28  };
    1.29  
    1.30  static struct domain *dom_head;
    1.31  
    1.32 -static void evtchn_notify(struct domain *dom)
    1.33 -{
    1.34 -	struct ioctl_evtchn_notify notify;
    1.35 -	notify.port = dom->local_port;
    1.36 -	(void)ioctl(dom->evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
    1.37 -}
    1.38 -
    1.39  static void buffer_append(struct domain *dom)
    1.40  {
    1.41  	struct buffer *buffer = &dom->buffer;
    1.42 @@ -106,7 +98,7 @@ static void buffer_append(struct domain 
    1.43  
    1.44  	mb();
    1.45  	intf->out_cons = cons;
    1.46 -	evtchn_notify(dom);
    1.47 +	xc_evtchn_notify(dom->xce_handle, dom->local_port);
    1.48  
    1.49  	if (buffer->max_capacity &&
    1.50  	    buffer->size > buffer->max_capacity) {
    1.51 @@ -234,7 +226,6 @@ int xs_gather(struct xs_handle *xs, cons
    1.52  static int domain_create_ring(struct domain *dom)
    1.53  {
    1.54  	int err, remote_port, ring_ref, rc;
    1.55 -	struct ioctl_evtchn_bind_interdomain bind;
    1.56  
    1.57  	err = xs_gather(xs, dom->conspath,
    1.58  			"ring-ref", "%u", &ring_ref,
    1.59 @@ -258,24 +249,24 @@ static int domain_create_ring(struct dom
    1.60  	}
    1.61  
    1.62  	dom->local_port = -1;
    1.63 -	if (dom->evtchn_fd != -1)
    1.64 -		close(dom->evtchn_fd);
    1.65 +	if (dom->xce_handle != -1)
    1.66 +		xc_evtchn_close(dom->xce_handle);
    1.67  
    1.68  	/* Opening evtchn independently for each console is a bit
    1.69  	 * wasteful, but that's how the code is structured... */
    1.70 -	dom->evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
    1.71 -	if (dom->evtchn_fd == -1) {
    1.72 +	dom->xce_handle = xc_evtchn_open();
    1.73 +	if (dom->xce_handle == -1) {
    1.74  		err = errno;
    1.75  		goto out;
    1.76  	}
    1.77   
    1.78 -	bind.remote_domain = dom->domid;
    1.79 -	bind.remote_port   = remote_port;
    1.80 -	rc = ioctl(dom->evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
    1.81 +	rc = xc_evtchn_bind_interdomain(dom->xce_handle,
    1.82 +		dom->domid, remote_port);
    1.83 +
    1.84  	if (rc == -1) {
    1.85  		err = errno;
    1.86 -		close(dom->evtchn_fd);
    1.87 -		dom->evtchn_fd = -1;
    1.88 +		xc_evtchn_close(dom->xce_handle);
    1.89 +		dom->xce_handle = -1;
    1.90  		goto out;
    1.91  	}
    1.92  	dom->local_port = rc;
    1.93 @@ -285,8 +276,8 @@ static int domain_create_ring(struct dom
    1.94  
    1.95  		if (dom->tty_fd == -1) {
    1.96  			err = errno;
    1.97 -			close(dom->evtchn_fd);
    1.98 -			dom->evtchn_fd = -1;
    1.99 +			xc_evtchn_close(dom->xce_handle);
   1.100 +			dom->xce_handle = -1;
   1.101  			dom->local_port = -1;
   1.102  			goto out;
   1.103  		}
   1.104 @@ -344,7 +335,7 @@ static struct domain *create_domain(int 
   1.105  	dom->ring_ref = -1;
   1.106  	dom->local_port = -1;
   1.107  	dom->interface = NULL;
   1.108 -	dom->evtchn_fd = -1;
   1.109 +	dom->xce_handle = -1;
   1.110  
   1.111  	if (!watch_domain(dom, true))
   1.112  		goto out;
   1.113 @@ -409,9 +400,9 @@ static void shutdown_domain(struct domai
   1.114  	if (d->interface != NULL)
   1.115  		munmap(d->interface, getpagesize());
   1.116  	d->interface = NULL;
   1.117 -	if (d->evtchn_fd != -1)
   1.118 -		close(d->evtchn_fd);
   1.119 -	d->evtchn_fd = -1;
   1.120 +	if (d->xce_handle != -1)
   1.121 +		xc_evtchn_close(d->xce_handle);
   1.122 +	d->xce_handle = -1;
   1.123  	cleanup_domain(d);
   1.124  }
   1.125  
   1.126 @@ -483,7 +474,7 @@ static void handle_tty_read(struct domai
   1.127  		}
   1.128  		wmb();
   1.129  		intf->in_prod = prod;
   1.130 -		evtchn_notify(dom);
   1.131 +		xc_evtchn_notify(dom->xce_handle, dom->local_port);
   1.132  	} else {
   1.133  		close(dom->tty_fd);
   1.134  		dom->tty_fd = -1;
   1.135 @@ -516,14 +507,14 @@ static void handle_tty_write(struct doma
   1.136  
   1.137  static void handle_ring_read(struct domain *dom)
   1.138  {
   1.139 -	evtchn_port_t v;
   1.140 +	evtchn_port_t port;
   1.141  
   1.142 -	if (!read_sync(dom->evtchn_fd, &v, sizeof(v)))
   1.143 +	if ((port = xc_evtchn_pending(dom->xce_handle)) == -1)
   1.144  		return;
   1.145  
   1.146  	buffer_append(dom);
   1.147  
   1.148 -	(void)write_sync(dom->evtchn_fd, &v, sizeof(v));
   1.149 +	(void)xc_evtchn_unmask(dom->xce_handle, port);
   1.150  }
   1.151  
   1.152  static void handle_xs(void)
   1.153 @@ -566,9 +557,10 @@ void handle_io(void)
   1.154  		max_fd = MAX(xs_fileno(xs), max_fd);
   1.155  
   1.156  		for (d = dom_head; d; d = d->next) {
   1.157 -			if (d->evtchn_fd != -1) {
   1.158 -				FD_SET(d->evtchn_fd, &readfds);
   1.159 -				max_fd = MAX(d->evtchn_fd, max_fd);
   1.160 +			if (d->xce_handle != -1) {
   1.161 +				int evtchn_fd = xc_evtchn_fd(d->xce_handle);
   1.162 +				FD_SET(evtchn_fd, &readfds);
   1.163 +				max_fd = MAX(evtchn_fd, max_fd);
   1.164  			}
   1.165  
   1.166  			if (d->tty_fd != -1) {
   1.167 @@ -588,8 +580,8 @@ void handle_io(void)
   1.168  
   1.169  		for (d = dom_head; d; d = n) {
   1.170  			n = d->next;
   1.171 -			if (d->evtchn_fd != -1 &&
   1.172 -			    FD_ISSET(d->evtchn_fd, &readfds))
   1.173 +			if (d->xce_handle != -1 &&
   1.174 +			    FD_ISSET(xc_evtchn_fd(d->xce_handle), &readfds))
   1.175  				handle_ring_read(d);
   1.176  
   1.177  			if (d->tty_fd != -1) {
     2.1 --- a/tools/console/daemon/utils.c	Thu Jun 15 11:52:23 2006 +0100
     2.2 +++ b/tools/console/daemon/utils.c	Thu Jun 15 13:11:31 2006 +0100
     2.3 @@ -39,32 +39,6 @@
     2.4  struct xs_handle *xs;
     2.5  int xc;
     2.6  
     2.7 -bool _read_write_sync(int fd, void *data, size_t size, bool do_read)
     2.8 -{
     2.9 -	size_t offset = 0;
    2.10 -	ssize_t len;
    2.11 -
    2.12 -	while (offset < size) {
    2.13 -		if (do_read) {
    2.14 -			len = read(fd, data + offset, size - offset);
    2.15 -		} else {
    2.16 -			len = write(fd, data + offset, size - offset);
    2.17 -		}
    2.18 -
    2.19 -		if (len < 1) {
    2.20 -			if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
    2.21 -				continue;
    2.22 -			} else {
    2.23 -				return false;
    2.24 -			}
    2.25 -		} else {
    2.26 -			offset += len;
    2.27 -		}
    2.28 -	}
    2.29 -
    2.30 -	return true;
    2.31 -}
    2.32 -
    2.33  static void child_exit(int sig)
    2.34  {
    2.35  	while (waitpid(-1, NULL, WNOHANG) > 0);
     3.1 --- a/tools/console/daemon/utils.h	Thu Jun 15 11:52:23 2006 +0100
     3.2 +++ b/tools/console/daemon/utils.h	Thu Jun 15 13:11:31 2006 +0100
     3.3 @@ -29,9 +29,6 @@
     3.4  
     3.5  void daemonize(const char *pidfile);
     3.6  bool xen_setup(void);
     3.7 -#define read_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, true)
     3.8 -#define write_sync(fd, buffer, size) _read_write_sync(fd, buffer, size, false)
     3.9 -bool _read_write_sync(int fd, void *data, size_t size, bool do_read);
    3.10  
    3.11  extern struct xs_handle *xs;
    3.12  extern int xc;
     4.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Thu Jun 15 11:52:23 2006 +0100
     4.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Thu Jun 15 13:11:31 2006 +0100
     4.3 @@ -47,11 +47,9 @@
     4.4  
     4.5  #include <limits.h>
     4.6  #include <fcntl.h>
     4.7 -#include <sys/ioctl.h>
     4.8  
     4.9  #include <xenctrl.h>
    4.10  #include <xen/hvm/ioreq.h>
    4.11 -#include <xen/linux/evtchn.h>
    4.12  
    4.13  #include "cpu.h"
    4.14  #include "exec-all.h"
    4.15 @@ -123,7 +121,7 @@ target_ulong cpu_get_phys_page_debug(CPU
    4.16  }
    4.17  
    4.18  //the evtchn fd for polling
    4.19 -int evtchn_fd = -1;
    4.20 +int xce_handle = -1;
    4.21  
    4.22  //which vcpu we are serving
    4.23  int send_vcpu = 0;
    4.24 @@ -170,11 +168,10 @@ static ioreq_t* __cpu_get_ioreq(int vcpu
    4.25  //retval--the number of ioreq packet
    4.26  static ioreq_t* cpu_get_ioreq(void)
    4.27  {
    4.28 -    int i, rc;
    4.29 +    int i;
    4.30      evtchn_port_t port;
    4.31  
    4.32 -    rc = read(evtchn_fd, &port, sizeof(port));
    4.33 -    if ( rc == sizeof(port) ) {
    4.34 +    if ( (port = xc_evtchn_pending(xce_handle)) != -1 ) {
    4.35          for ( i = 0; i < vcpus; i++ )
    4.36              if ( shared_page->vcpu_iodata[i].dm_eport == port )
    4.37                  break;
    4.38 @@ -184,8 +181,7 @@ static ioreq_t* cpu_get_ioreq(void)
    4.39              exit(1);
    4.40          }
    4.41  
    4.42 -        // unmask the wanted port again
    4.43 -        write(evtchn_fd, &port, sizeof(port));
    4.44 +	xc_evtchn_unmask(xce_handle, port);
    4.45  
    4.46          //get the io packet from shared memory
    4.47          send_vcpu = i;
    4.48 @@ -436,6 +432,7 @@ int main_loop(void)
    4.49      extern int shutdown_requested;
    4.50      CPUState *env = global_env;
    4.51      int retval;
    4.52 +    int evtchn_fd = xc_evtchn_fd(xce_handle);
    4.53      extern void main_loop_wait(int);
    4.54  
    4.55      /* Watch stdin (fd 0) to see when it has input. */
    4.56 @@ -475,11 +472,9 @@ int main_loop(void)
    4.57          main_loop_wait(0);
    4.58  
    4.59          if (env->send_event) {
    4.60 -            struct ioctl_evtchn_notify notify;
    4.61 -
    4.62              env->send_event = 0;
    4.63 -            notify.port = shared_page->vcpu_iodata[send_vcpu].dm_eport;
    4.64 -            (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
    4.65 +            (void)xc_evtchn_notify(xce_handle,
    4.66 +                 shared_page->vcpu_iodata[send_vcpu].dm_eport);
    4.67          }
    4.68      }
    4.69      destroy_hvm_domain();
    4.70 @@ -511,7 +506,6 @@ static void qemu_hvm_reset(void *unused)
    4.71  CPUState * cpu_init()
    4.72  {
    4.73      CPUX86State *env;
    4.74 -    struct ioctl_evtchn_bind_interdomain bind;
    4.75      int i, rc;
    4.76  
    4.77      cpu_exec_init();
    4.78 @@ -523,21 +517,19 @@ CPUState * cpu_init()
    4.79  
    4.80      cpu_single_env = env;
    4.81  
    4.82 -    if (evtchn_fd != -1)//the evtchn has been opened by another cpu object
    4.83 +    if (xce_handle != -1)//the evtchn has been opened by another cpu object
    4.84          return NULL;
    4.85  
    4.86 -    //use nonblock reading not polling, may change in future.
    4.87 -    evtchn_fd = open("/dev/xen/evtchn", O_RDWR|O_NONBLOCK);
    4.88 -    if (evtchn_fd == -1) {
    4.89 +    xce_handle = xc_evtchn_open();
    4.90 +    if (xce_handle == -1) {
    4.91          fprintf(logfile, "open evtchn device error %d\n", errno);
    4.92          return NULL;
    4.93      }
    4.94  
    4.95      /* FIXME: how about if we overflow the page here? */
    4.96 -    bind.remote_domain = domid;
    4.97      for ( i = 0; i < vcpus; i++ ) {
    4.98 -        bind.remote_port = shared_page->vcpu_iodata[i].vp_eport;
    4.99 -        rc = ioctl(evtchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
   4.100 +        rc = xc_evtchn_bind_interdomain(xce_handle, domid,
   4.101 +            shared_page->vcpu_iodata[i].vp_eport);
   4.102          if ( rc == -1 ) {
   4.103              fprintf(logfile, "bind interdomain ioctl error %d\n", errno);
   4.104              return NULL;
     5.1 --- a/tools/libxc/xc_linux.c	Thu Jun 15 11:52:23 2006 +0100
     5.2 +++ b/tools/libxc/xc_linux.c	Thu Jun 15 13:11:31 2006 +0100
     5.3 @@ -103,6 +103,124 @@ int do_xen_hypercall(int xc_handle, priv
     5.4                        (unsigned long)hypercall);
     5.5  }
     5.6  
     5.7 +#define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
     5.8 +#define EVTCHN_DEV_MAJOR 10
     5.9 +#define EVTCHN_DEV_MINOR 201
    5.10 +
    5.11 +int xc_evtchn_open(void)
    5.12 +{
    5.13 +    struct stat st;
    5.14 +    int fd;
    5.15 +
    5.16 +    /* Make sure any existing device file links to correct device. */
    5.17 +    if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
    5.18 +        (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
    5.19 +        (void)unlink(EVTCHN_DEV_NAME);
    5.20 +
    5.21 +reopen:
    5.22 +    if ( (fd = open(EVTCHN_DEV_NAME, O_RDWR)) == -1 )
    5.23 +    {
    5.24 +        if ( (errno == ENOENT) &&
    5.25 +            ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
    5.26 +            (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
    5.27 +            makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0) )
    5.28 +            goto reopen;
    5.29 +
    5.30 +        PERROR("Could not open event channel interface");
    5.31 +        return -1;
    5.32 +    }
    5.33 +
    5.34 +    return fd;
    5.35 +}
    5.36 +
    5.37 +int xc_evtchn_close(int xce_handle)
    5.38 +{
    5.39 +    return close(xce_handle);
    5.40 +}
    5.41 +
    5.42 +int xc_evtchn_fd(int xce_handle)
    5.43 +{
    5.44 +    return xce_handle;
    5.45 +}
    5.46 +
    5.47 +int xc_evtchn_notify(int xce_handle, evtchn_port_t port)
    5.48 +{
    5.49 +    struct ioctl_evtchn_notify notify;
    5.50 +
    5.51 +    notify.port = port;
    5.52 +
    5.53 +    return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, &notify);
    5.54 +}
    5.55 +
    5.56 +evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
    5.57 +    evtchn_port_t remote_port)
    5.58 +{
    5.59 +    struct ioctl_evtchn_bind_interdomain bind;
    5.60 +
    5.61 +    bind.remote_domain = domid;
    5.62 +    bind.remote_port = remote_port;
    5.63 +
    5.64 +    return ioctl(xce_handle, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
    5.65 +}
    5.66 +
    5.67 +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port)
    5.68 +{
    5.69 +    struct ioctl_evtchn_unbind unbind;
    5.70 +
    5.71 +    unbind.port = port;
    5.72 +
    5.73 +    return ioctl(xce_handle, IOCTL_EVTCHN_UNBIND, &unbind);
    5.74 +}
    5.75 +
    5.76 +evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq)
    5.77 +{
    5.78 +    struct ioctl_evtchn_bind_virq bind;
    5.79 +
    5.80 +    bind.virq = virq;
    5.81 +
    5.82 +    return ioctl(xce_handle, IOCTL_EVTCHN_BIND_VIRQ, &bind);
    5.83 +}
    5.84 +
    5.85 +static int dorw(int fd, char *data, size_t size, int do_write)
    5.86 +{
    5.87 +    size_t offset = 0;
    5.88 +    ssize_t len;
    5.89 +
    5.90 +    while ( offset < size )
    5.91 +    {
    5.92 +        if (do_write)
    5.93 +            len = write(fd, data + offset, size - offset);
    5.94 +        else
    5.95 +            len = read(fd, data + offset, size - offset);
    5.96 +
    5.97 +        if ( len == -1 )
    5.98 +        {
    5.99 +             if ( errno == EINTR )
   5.100 +                 continue;
   5.101 +             return -1;
   5.102 +        }
   5.103 +
   5.104 +        offset += len;
   5.105 +    }
   5.106 +
   5.107 +    return 0;
   5.108 +}
   5.109 +
   5.110 +evtchn_port_t xc_evtchn_pending(int xce_handle)
   5.111 +{
   5.112 +    evtchn_port_t port;
   5.113 +
   5.114 +    if ( dorw(xce_handle, (char *)&port, sizeof(port), 0) == -1 )
   5.115 +        return -1;
   5.116 +
   5.117 +    return port;
   5.118 +}
   5.119 +
   5.120 +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port)
   5.121 +{
   5.122 +    return dorw(xce_handle, (char *)&port, sizeof(port), 1);
   5.123 +}
   5.124 +
   5.125  /*
   5.126   * Local variables:
   5.127   * mode: C
     6.1 --- a/tools/libxc/xenctrl.h	Thu Jun 15 11:52:23 2006 +0100
     6.2 +++ b/tools/libxc/xenctrl.h	Thu Jun 15 13:11:31 2006 +0100
     6.3 @@ -604,4 +604,58 @@ int xc_finish_mmu_updates(int xc_handle,
     6.4  
     6.5  int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size);
     6.6  
     6.7 +/*
     6.8 + * Return a handle to the event channel driver, or -1 on failure, in which case
     6.9 + * errno will be set appropriately.
    6.10 + */
    6.11 +int xc_evtchn_open(void);
    6.12 +
    6.13 +/*
    6.14 + * Close a handle previously allocated with xc_evtchn_open().
    6.15 + */
    6.16 +int xc_evtchn_close(int xce_handle);
    6.17 +
    6.18 +/*
    6.19 + * Return an fd that can be select()ed on for further calls to
    6.20 + * xc_evtchn_pending().
    6.21 + */
    6.22 +int xc_evtchn_fd(int xce_handle);
    6.23 +
    6.24 +/*
    6.25 + * Notify the given event channel. Returns -1 on failure, in which case
    6.26 + * errno will be set appropriately.
    6.27 + */
    6.28 +int xc_evtchn_notify(int xce_handle, evtchn_port_t port);
    6.29 +
    6.30 +/*
    6.31 + * Returns a new event port bound to the remote port for the given domain ID,
    6.32 + * or -1 on failure, in which case errno will be set appropriately.
    6.33 + */
    6.34 +evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
    6.35 +    evtchn_port_t remote_port);
    6.36 +
    6.37 +/*
    6.38 + * Unbind the given event channel. Returns -1 on failure, in which case errno
    6.39 + * will be set appropriately.
    6.40 + */
    6.41 +int xc_evtchn_unbind(int xce_handle, evtchn_port_t port);
    6.42 +
    6.43 +/*
    6.44 + * Bind an event channel to the given VIRQ. Returns the event channel bound to
    6.45 + * the VIRQ, or -1 on failure, in which case errno will be set appropriately.
    6.46 + */
    6.47 +evtchn_port_t xc_evtchn_bind_virq(int xce_handle, unsigned int virq);
    6.48 +
    6.49 +/*
    6.50 + * Return the next event channel to become pending, or -1 on failure, in which
    6.51 + * case errno will be set appropriately.  
    6.52 + */
    6.53 +evtchn_port_t xc_evtchn_pending(int xce_handle);
    6.54 +
    6.55 +/*
    6.56 + * Unmask the given event channel. Returns -1 on failure, in which case errno
    6.57 + * will be set appropriately.
    6.58 + */
    6.59 +int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
    6.60 +
    6.61  #endif
     7.1 --- a/tools/xenmon/xenbaked.c	Thu Jun 15 11:52:23 2006 +0100
     7.2 +++ b/tools/xenmon/xenbaked.c	Thu Jun 15 13:11:31 2006 +0100
     7.3 @@ -33,9 +33,6 @@
     7.4  #include <stdlib.h>
     7.5  #include <stdio.h>
     7.6  #include <sys/mman.h>
     7.7 -#include <sys/stat.h>
     7.8 -#include <sys/types.h>
     7.9 -#include <sys/ioctl.h>
    7.10  #include <fcntl.h>
    7.11  #include <unistd.h>
    7.12  #include <errno.h>
    7.13 @@ -45,7 +42,6 @@
    7.14  #include <xen/xen.h>
    7.15  #include <string.h>
    7.16  #include <sys/select.h>
    7.17 -#include <xen/linux/evtchn.h>
    7.18  
    7.19  #define PERROR(_m, _a...)                                       \
    7.20  do {                                                            \
    7.21 @@ -256,51 +252,29 @@ void log_event(int event_id)
    7.22          stat_map[0].event_count++;	// other
    7.23  }
    7.24  
    7.25 -#define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
    7.26 -#define EVTCHN_DEV_MAJOR 10
    7.27 -#define EVTCHN_DEV_MINOR 201
    7.28 -
    7.29  int virq_port;
    7.30 -int eventchn_fd = -1;
    7.31 +int xce_handle = -1;
    7.32  
    7.33  /* Returns the event channel handle. */
    7.34  /* Stolen from xenstore code */
    7.35  int eventchn_init(void)
    7.36  {
    7.37 -  struct stat st;
    7.38 -  struct ioctl_evtchn_bind_virq bind;
    7.39    int rc;
    7.40    
    7.41    // to revert to old way:
    7.42    if (0)
    7.43      return -1;
    7.44    
    7.45 -  /* Make sure any existing device file links to correct device. */
    7.46 -  if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
    7.47 -      (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
    7.48 -    (void)unlink(EVTCHN_DEV_NAME);
    7.49 -  
    7.50 - reopen:
    7.51 -  eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
    7.52 -  if (eventchn_fd == -1) {
    7.53 -    if ((errno == ENOENT) &&
    7.54 -	((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
    7.55 -	(mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
    7.56 -	       makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0))
    7.57 -      goto reopen;
    7.58 -    return -errno;
    7.59 -  }
    7.60 -  
    7.61 -  if (eventchn_fd < 0)
    7.62 +  xce_handle = xc_evtchn_open();
    7.63 +
    7.64 +  if (xce_handle < 0)
    7.65      perror("Failed to open evtchn device");
    7.66    
    7.67 -  bind.virq = VIRQ_TBUF;
    7.68 -  rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
    7.69 -  if (rc == -1)
    7.70 +  if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_TBUF)) == -1)
    7.71      perror("Failed to bind to domain exception virq port");
    7.72    virq_port = rc;
    7.73    
    7.74 -  return eventchn_fd;
    7.75 +  return xce_handle;
    7.76  }
    7.77  
    7.78  void wait_for_event(void)
    7.79 @@ -309,27 +283,30 @@ void wait_for_event(void)
    7.80    fd_set inset;
    7.81    evtchn_port_t port;
    7.82    struct timeval tv;
    7.83 +  int evtchn_fd;
    7.84    
    7.85 -  if (eventchn_fd < 0) {
    7.86 +  if (xce_handle < 0) {
    7.87      nanosleep(&opts.poll_sleep, NULL);
    7.88      return;
    7.89    }
    7.90  
    7.91 +  evtchn_fd = xc_evtchn_fd(xce_handle);
    7.92 +
    7.93    FD_ZERO(&inset);
    7.94 -  FD_SET(eventchn_fd, &inset);
    7.95 +  FD_SET(evtchn_fd, &inset);
    7.96    tv.tv_sec = 1;
    7.97    tv.tv_usec = 0;
    7.98    // tv = millis_to_timespec(&opts.poll_sleep);
    7.99 -  ret = select(eventchn_fd+1, &inset, NULL, NULL, &tv);
   7.100 +  ret = select(evtchn_fd+1, &inset, NULL, NULL, &tv);
   7.101    
   7.102 -  if ( (ret == 1) && FD_ISSET(eventchn_fd, &inset)) {
   7.103 -    if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   7.104 +  if ( (ret == 1) && FD_ISSET(evtchn_fd, &inset)) {
   7.105 +    if ((port = xc_evtchn_pending(xce_handle)) == -1)
   7.106        perror("Failed to read from event fd");
   7.107      
   7.108      //    if (port == virq_port)
   7.109      //      printf("got the event I was looking for\r\n");
   7.110 -    
   7.111 -    if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   7.112 +
   7.113 +    if (xc_evtchn_unmask(xce_handle, port) == -1)
   7.114        perror("Failed to write to event fd");
   7.115    }
   7.116  }
     8.1 --- a/tools/xenstore/fake_libxc.c	Thu Jun 15 11:52:23 2006 +0100
     8.2 +++ b/tools/xenstore/fake_libxc.c	Thu Jun 15 13:11:31 2006 +0100
     8.3 @@ -37,7 +37,7 @@ static int xs_test_pid;
     8.4  static evtchn_port_t port;
     8.5  
     8.6  /* The event channel maps to a signal, shared page to an mmapped file. */
     8.7 -void evtchn_notify(int local_port)
     8.8 +void xc_evtchn_notify(int xce_handle, int local_port)
     8.9  {
    8.10  	assert(local_port == port);
    8.11  	if (kill(xs_test_pid, SIGUSR2) != 0)
    8.12 @@ -124,7 +124,7 @@ void fake_ack_event(void)
    8.13  	signal(SIGUSR2, send_to_fd);
    8.14  }
    8.15  
    8.16 -int fake_open_eventchn(void)
    8.17 +int xc_evtchn_open(void)
    8.18  {
    8.19  	int fds[2];
    8.20  
     9.1 --- a/tools/xenstore/xenstored_core.c	Thu Jun 15 11:52:23 2006 +0100
     9.2 +++ b/tools/xenstore/xenstored_core.c	Thu Jun 15 13:11:31 2006 +0100
     9.3 @@ -54,7 +54,7 @@
     9.4  #include "hashtable.h"
     9.5  
     9.6  
     9.7 -extern int eventchn_fd; /* in xenstored_domain.c */
     9.8 +extern int xce_handle; /* in xenstored_domain.c */
     9.9  
    9.10  static bool verbose = false;
    9.11  LIST_HEAD(connections);
    9.12 @@ -353,8 +353,11 @@ static int initialize_set(fd_set *inset,
    9.13  
    9.14  	set_fd(sock,               inset, &max);
    9.15  	set_fd(ro_sock,            inset, &max);
    9.16 -	set_fd(eventchn_fd,        inset, &max);
    9.17  	set_fd(reopen_log_pipe[0], inset, &max);
    9.18 +
    9.19 +	if (xce_handle != -1)
    9.20 +		set_fd(xc_evtchn_fd(xce_handle), inset, &max);
    9.21 +
    9.22  	list_for_each_entry(i, &connections, list) {
    9.23  		if (i->domain)
    9.24  			continue;
    9.25 @@ -1769,6 +1772,7 @@ int main(int argc, char *argv[])
    9.26  	bool outputpid = false;
    9.27  	bool no_domain_init = false;
    9.28  	const char *pidfile = NULL;
    9.29 +	int evtchn_fd = -1;
    9.30  
    9.31  	while ((opt = getopt_long(argc, argv, "DE:F:HNPS:T:RLVW:", options,
    9.32  				  NULL)) != -1) {
    9.33 @@ -1907,6 +1911,9 @@ int main(int argc, char *argv[])
    9.34  	signal(SIGUSR1, stop_failtest);
    9.35  #endif
    9.36  
    9.37 +	if (xce_handle != -1)
    9.38 +		evtchn_fd = xc_evtchn_fd(xce_handle);
    9.39 +
    9.40  	/* Get ready to listen to the tools. */
    9.41  	max = initialize_set(&inset, &outset, *sock, *ro_sock);
    9.42  
    9.43 @@ -1934,7 +1941,7 @@ int main(int argc, char *argv[])
    9.44  		if (FD_ISSET(*ro_sock, &inset))
    9.45  			accept_connection(*ro_sock, false);
    9.46  
    9.47 -		if (eventchn_fd > 0 && FD_ISSET(eventchn_fd, &inset))
    9.48 +		if (evtchn_fd != -1 && FD_ISSET(evtchn_fd, &inset))
    9.49  			handle_event();
    9.50  
    9.51  		list_for_each_entry(i, &connections, list) {
    10.1 --- a/tools/xenstore/xenstored_domain.c	Thu Jun 15 11:52:23 2006 +0100
    10.2 +++ b/tools/xenstore/xenstored_domain.c	Thu Jun 15 13:11:31 2006 +0100
    10.3 @@ -18,15 +18,10 @@
    10.4  */
    10.5  
    10.6  #include <stdio.h>
    10.7 -#include <linux/ioctl.h>
    10.8 -#include <sys/ioctl.h>
    10.9  #include <sys/mman.h>
   10.10  #include <unistd.h>
   10.11  #include <stdlib.h>
   10.12  #include <stdarg.h>
   10.13 -#include <sys/types.h>
   10.14 -#include <sys/stat.h>
   10.15 -#include <fcntl.h>
   10.16  
   10.17  //#define DEBUG
   10.18  #include "utils.h"
   10.19 @@ -37,12 +32,11 @@
   10.20  #include "xenstored_test.h"
   10.21  
   10.22  #include <xenctrl.h>
   10.23 -#include <xen/sys/evtchn.h>
   10.24  
   10.25  static int *xc_handle;
   10.26  static evtchn_port_t virq_port;
   10.27  
   10.28 -int eventchn_fd = -1; 
   10.29 +int xce_handle = -1; 
   10.30  
   10.31  struct domain
   10.32  {
   10.33 @@ -83,19 +77,6 @@ struct domain
   10.34  
   10.35  static LIST_HEAD(domains);
   10.36  
   10.37 -#ifndef TESTING
   10.38 -static void evtchn_notify(int port)
   10.39 -{
   10.40 -	int rc; 
   10.41 -
   10.42 -	struct ioctl_evtchn_notify notify;
   10.43 -	notify.port = port;
   10.44 -	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_NOTIFY, &notify);
   10.45 -}
   10.46 -#else
   10.47 -extern void evtchn_notify(int port);
   10.48 -#endif
   10.49 -
   10.50  /* FIXME: Mark connection as broken (close it?) when this happens. */
   10.51  static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod)
   10.52  {
   10.53 @@ -146,7 +127,7 @@ static int writechn(struct connection *c
   10.54  	mb();
   10.55  	intf->rsp_prod += len;
   10.56  
   10.57 -	evtchn_notify(conn->domain->port);
   10.58 +	xc_evtchn_notify(xce_handle, conn->domain->port);
   10.59  
   10.60  	return len;
   10.61  }
   10.62 @@ -176,7 +157,7 @@ static int readchn(struct connection *co
   10.63  	mb();
   10.64  	intf->req_cons += len;
   10.65  
   10.66 -	evtchn_notify(conn->domain->port);
   10.67 +	xc_evtchn_notify(xce_handle, conn->domain->port);
   10.68  
   10.69  	return len;
   10.70  }
   10.71 @@ -184,13 +165,11 @@ static int readchn(struct connection *co
   10.72  static int destroy_domain(void *_domain)
   10.73  {
   10.74  	struct domain *domain = _domain;
   10.75 -	struct ioctl_evtchn_unbind unbind;
   10.76  
   10.77  	list_del(&domain->list);
   10.78  
   10.79  	if (domain->port) {
   10.80 -		unbind.port = domain->port;
   10.81 -		if (ioctl(eventchn_fd, IOCTL_EVTCHN_UNBIND, &unbind) == -1)
   10.82 +		if (xc_evtchn_unbind(xce_handle, domain->port) == -1)
   10.83  			eprintf("> Unbinding port %i failed!\n", domain->port);
   10.84  	}
   10.85  
   10.86 @@ -231,14 +210,14 @@ void handle_event(void)
   10.87  {
   10.88  	evtchn_port_t port;
   10.89  
   10.90 -	if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   10.91 +	if ((port = xc_evtchn_pending(xce_handle)) == -1)
   10.92  		barf_perror("Failed to read from event fd");
   10.93  
   10.94  	if (port == virq_port)
   10.95  		domain_cleanup();
   10.96  
   10.97  #ifndef TESTING
   10.98 -	if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port))
   10.99 +	if (xc_evtchn_unmask(xce_handle, port) == -1)
  10.100  		barf_perror("Failed to write to event fd");
  10.101  #endif
  10.102  }
  10.103 @@ -269,7 +248,6 @@ static struct domain *new_domain(void *c
  10.104  				 int port)
  10.105  {
  10.106  	struct domain *domain;
  10.107 -	struct ioctl_evtchn_bind_interdomain bind;
  10.108  	int rc;
  10.109  
  10.110  
  10.111 @@ -283,9 +261,7 @@ static struct domain *new_domain(void *c
  10.112  	talloc_set_destructor(domain, destroy_domain);
  10.113  
  10.114  	/* Tell kernel we're interested in this event. */
  10.115 -	bind.remote_domain = domid;
  10.116 -	bind.remote_port   = port;
  10.117 -	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind);
  10.118 +	rc = xc_evtchn_bind_interdomain(xce_handle, domid, port);
  10.119  	if (rc == -1)
  10.120  	    return NULL;
  10.121  	domain->port = rc;
  10.122 @@ -490,23 +466,14 @@ static int dom0_init(void)
  10.123  
  10.124  	talloc_steal(dom0->conn, dom0); 
  10.125  
  10.126 -	evtchn_notify(dom0->port); 
  10.127 +	xc_evtchn_notify(xce_handle, dom0->port); 
  10.128  
  10.129  	return 0; 
  10.130  }
  10.131  
  10.132 -
  10.133 -
  10.134 -#define EVTCHN_DEV_NAME  "/dev/xen/evtchn"
  10.135 -#define EVTCHN_DEV_MAJOR 10
  10.136 -#define EVTCHN_DEV_MINOR 201
  10.137 -
  10.138 -
  10.139  /* Returns the event channel handle. */
  10.140  int domain_init(void)
  10.141  {
  10.142 -	struct stat st;
  10.143 -	struct ioctl_evtchn_bind_virq bind;
  10.144  	int rc;
  10.145  
  10.146  	xc_handle = talloc(talloc_autofree_context(), int);
  10.147 @@ -519,39 +486,19 @@ int domain_init(void)
  10.148  
  10.149  	talloc_set_destructor(xc_handle, close_xc_handle);
  10.150  
  10.151 -#ifdef TESTING
  10.152 -	eventchn_fd = fake_open_eventchn();
  10.153 -	(void)&st;
  10.154 -#else
  10.155 -	/* Make sure any existing device file links to correct device. */
  10.156 -	if ((lstat(EVTCHN_DEV_NAME, &st) != 0) || !S_ISCHR(st.st_mode) ||
  10.157 -	    (st.st_rdev != makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)))
  10.158 -		(void)unlink(EVTCHN_DEV_NAME);
  10.159 +	xce_handle = xc_evtchn_open();
  10.160  
  10.161 - reopen:
  10.162 -	eventchn_fd = open(EVTCHN_DEV_NAME, O_NONBLOCK|O_RDWR);
  10.163 -	if (eventchn_fd == -1) {
  10.164 -		if ((errno == ENOENT) &&
  10.165 -		    ((mkdir("/dev/xen", 0755) == 0) || (errno == EEXIST)) &&
  10.166 -		    (mknod(EVTCHN_DEV_NAME, S_IFCHR|0600,
  10.167 -			   makedev(EVTCHN_DEV_MAJOR, EVTCHN_DEV_MINOR)) == 0))
  10.168 -			goto reopen;
  10.169 -		return -errno;
  10.170 -	}
  10.171 -#endif
  10.172 -	if (eventchn_fd < 0)
  10.173 +	if (xce_handle < 0)
  10.174  		barf_perror("Failed to open evtchn device");
  10.175  
  10.176  	if (dom0_init() != 0) 
  10.177  		barf_perror("Failed to initialize dom0 state"); 
  10.178  
  10.179 -	bind.virq = VIRQ_DOM_EXC;
  10.180 -	rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind);
  10.181 -	if (rc == -1)
  10.182 +	if ((rc = xc_evtchn_bind_virq(xce_handle, VIRQ_DOM_EXC)) == -1)
  10.183  		barf_perror("Failed to bind to domain exception virq port");
  10.184  	virq_port = rc;
  10.185  
  10.186 -	return eventchn_fd;
  10.187 +	return xce_handle;
  10.188  }
  10.189  
  10.190  void domain_entry_inc(struct connection *conn)