ia64/xen-unstable

changeset 8167:f5b119533cc8

Define explicit evtchn_port_t type (32 bits) and plumb up
to user space thru /dev/xen/evtchn.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Dec 01 15:22:22 2005 +0100 (2005-12-01)
parents d84ffe8f32ae
children 6b18f820f6a7
files linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c tools/console/daemon/io.c tools/ioemu/target-i386-dm/helper2.c tools/ioemu/vl.c tools/libxc/xc_evtchn.c tools/libxc/xenctrl.h tools/xenstore/fake_libxc.c tools/xenstore/xenstored_domain.c xen/include/public/event_channel.h
line diff
     1.1 --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Thu Dec 01 07:31:50 2005 +0000
     1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c	Thu Dec 01 15:22:22 2005 +0100
     1.3 @@ -50,9 +50,9 @@
     1.4  
     1.5  struct per_user_data {
     1.6  	/* Notification ring, accessed via /dev/xen/evtchn. */
     1.7 -#define EVTCHN_RING_SIZE     2048  /* 2048 16-bit entries */
     1.8 +#define EVTCHN_RING_SIZE     (PAGE_SIZE / sizeof(evtchn_port_t))
     1.9  #define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
    1.10 -	u16 *ring;
    1.11 +	evtchn_port_t *ring;
    1.12  	unsigned int ring_cons, ring_prod, ring_overflow;
    1.13  
    1.14  	/* Processes wait on this queue when ring is empty. */
    1.15 @@ -75,7 +75,7 @@ void evtchn_device_upcall(int port)
    1.16  
    1.17  	if ((u = port_user[port]) != NULL) {
    1.18  		if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
    1.19 -			u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port;
    1.20 +			u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
    1.21  			if (u->ring_cons == u->ring_prod++) {
    1.22  				wake_up_interruptible(&u->evtchn_wait);
    1.23  				kill_fasync(&u->evtchn_async_queue,
    1.24 @@ -94,52 +94,40 @@ static ssize_t evtchn_read(struct file *
    1.25  {
    1.26  	int rc;
    1.27  	unsigned int c, p, bytes1 = 0, bytes2 = 0;
    1.28 -	DECLARE_WAITQUEUE(wait, current);
    1.29  	struct per_user_data *u = file->private_data;
    1.30  
    1.31 -	add_wait_queue(&u->evtchn_wait, &wait);
    1.32 -
    1.33 -	count &= ~1; /* even number of bytes */
    1.34 +	/* Whole number of ports. */
    1.35 +	count &= ~(sizeof(evtchn_port_t)-1);
    1.36  
    1.37 -	if (count == 0) {
    1.38 -		rc = 0;
    1.39 -		goto out;
    1.40 -	}
    1.41 +	if (count == 0)
    1.42 +		return 0;
    1.43  
    1.44  	if (count > PAGE_SIZE)
    1.45  		count = PAGE_SIZE;
    1.46  
    1.47  	for (;;) {
    1.48 -		set_current_state(TASK_INTERRUPTIBLE);
    1.49 +		if (u->ring_overflow)
    1.50 +			return -EFBIG;
    1.51  
    1.52  		if ((c = u->ring_cons) != (p = u->ring_prod))
    1.53  			break;
    1.54  
    1.55 -		if (u->ring_overflow) {
    1.56 -			rc = -EFBIG;
    1.57 -			goto out;
    1.58 -		}
    1.59 +		if (file->f_flags & O_NONBLOCK)
    1.60 +			return -EAGAIN;
    1.61  
    1.62 -		if (file->f_flags & O_NONBLOCK) {
    1.63 -			rc = -EAGAIN;
    1.64 -			goto out;
    1.65 -		}
    1.66 -
    1.67 -		if (signal_pending(current)) {
    1.68 -			rc = -ERESTARTSYS;
    1.69 -			goto out;
    1.70 -		}
    1.71 -
    1.72 -		schedule();
    1.73 +		rc = wait_event_interruptible(
    1.74 +			u->evtchn_wait, u->ring_cons != u->ring_prod);
    1.75 +		if (rc)
    1.76 +			return rc;
    1.77  	}
    1.78  
    1.79  	/* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
    1.80  	if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
    1.81  		bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
    1.82 -			sizeof(u16);
    1.83 -		bytes2 = EVTCHN_RING_MASK(p) * sizeof(u16);
    1.84 +			sizeof(evtchn_port_t);
    1.85 +		bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
    1.86  	} else {
    1.87 -		bytes1 = (p - c) * sizeof(u16);
    1.88 +		bytes1 = (p - c) * sizeof(evtchn_port_t);
    1.89  		bytes2 = 0;
    1.90  	}
    1.91  
    1.92 @@ -153,32 +141,26 @@ static ssize_t evtchn_read(struct file *
    1.93  
    1.94  	if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
    1.95  	    ((bytes2 != 0) &&
    1.96 -	     copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) {
    1.97 -		rc = -EFAULT;
    1.98 -		goto out;
    1.99 -	}
   1.100 -
   1.101 -	u->ring_cons += (bytes1 + bytes2) / sizeof(u16);
   1.102 +	     copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
   1.103 +		return -EFAULT;
   1.104  
   1.105 -	rc = bytes1 + bytes2;
   1.106 +	u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
   1.107  
   1.108 - out:
   1.109 -	__set_current_state(TASK_RUNNING);
   1.110 -	remove_wait_queue(&u->evtchn_wait, &wait);
   1.111 -	return rc;
   1.112 +	return bytes1 + bytes2;
   1.113  }
   1.114  
   1.115  static ssize_t evtchn_write(struct file *file, const char __user *buf,
   1.116                              size_t count, loff_t *ppos)
   1.117  {
   1.118  	int  rc, i;
   1.119 -	u16 *kbuf = (u16 *)__get_free_page(GFP_KERNEL);
   1.120 +	evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
   1.121  	struct per_user_data *u = file->private_data;
   1.122  
   1.123  	if (kbuf == NULL)
   1.124  		return -ENOMEM;
   1.125  
   1.126 -	count &= ~1; /* even number of bytes */
   1.127 +	/* Whole number of ports. */
   1.128 +	count &= ~(sizeof(evtchn_port_t)-1);
   1.129  
   1.130  	if (count == 0) {
   1.131  		rc = 0;
   1.132 @@ -194,7 +176,7 @@ static ssize_t evtchn_write(struct file 
   1.133  	}
   1.134  
   1.135  	spin_lock_irq(&port_user_lock);
   1.136 -	for (i = 0; i < (count/2); i++)
   1.137 +	for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
   1.138  		if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
   1.139  			unmask_evtchn(kbuf[i]);
   1.140  	spin_unlock_irq(&port_user_lock);
   1.141 @@ -379,8 +361,8 @@ static int evtchn_open(struct inode *ino
   1.142  	memset(u, 0, sizeof(*u));
   1.143  	init_waitqueue_head(&u->evtchn_wait);
   1.144  
   1.145 -	if ((u->ring = (u16 *)__get_free_page(GFP_KERNEL)) == NULL)
   1.146 -	{
   1.147 +	u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
   1.148 +	if (u->ring == NULL) {
   1.149  		kfree(u);
   1.150  		return -ENOMEM;
   1.151  	}
   1.152 @@ -400,8 +382,7 @@ static int evtchn_release(struct inode *
   1.153  
   1.154  	free_page((unsigned long)u->ring);
   1.155  
   1.156 -	for (i = 0; i < NR_EVENT_CHANNELS; i++)
   1.157 -	{
   1.158 +	for (i = 0; i < NR_EVENT_CHANNELS; i++) {
   1.159  		int ret;
   1.160  		if (port_user[i] != u)
   1.161  			continue;
   1.162 @@ -447,10 +428,9 @@ static int __init evtchn_init(void)
   1.163  	spin_lock_init(&port_user_lock);
   1.164  	memset(port_user, 0, sizeof(port_user));
   1.165  
   1.166 -	/* (DEVFS) create '/dev/misc/evtchn'. */
   1.167 +	/* Create '/dev/misc/evtchn'. */
   1.168  	err = misc_register(&evtchn_miscdev);
   1.169 -	if (err != 0)
   1.170 -	{
   1.171 +	if (err != 0) {
   1.172  		printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
   1.173  		return err;
   1.174  	}
     2.1 --- a/tools/console/daemon/io.c	Thu Dec 01 07:31:50 2005 +0000
     2.2 +++ b/tools/console/daemon/io.c	Thu Dec 01 15:22:22 2005 +0100
     2.3 @@ -62,7 +62,7 @@ struct domain
     2.4  	struct domain *next;
     2.5  	char *conspath;
     2.6  	int ring_ref;
     2.7 -	int local_port;
     2.8 +	evtchn_port_t local_port;
     2.9  	int evtchn_fd;
    2.10  	struct xencons_interface *interface;
    2.11  };
    2.12 @@ -488,7 +488,7 @@ static void handle_tty_write(struct doma
    2.13  
    2.14  static void handle_ring_read(struct domain *dom)
    2.15  {
    2.16 -	uint16_t v;
    2.17 +	evtchn_port_t v;
    2.18  
    2.19  	if (!read_sync(dom->evtchn_fd, &v, sizeof(v)))
    2.20  		return;
     3.1 --- a/tools/ioemu/target-i386-dm/helper2.c	Thu Dec 01 07:31:50 2005 +0000
     3.2 +++ b/tools/ioemu/target-i386-dm/helper2.c	Thu Dec 01 15:22:22 2005 +0100
     3.3 @@ -125,7 +125,7 @@ int evtchn_fd = -1;
     3.4  
     3.5  //the evtchn port for polling the notification,
     3.6  //should be inputed as bochs's parameter
     3.7 -uint16_t ioreq_remote_port, ioreq_local_port;
     3.8 +evtchn_port_t ioreq_remote_port, ioreq_local_port;
     3.9  
    3.10  //some functions to handle the io req packet
    3.11  void sp_info()
    3.12 @@ -170,12 +170,12 @@ ioreq_t* __cpu_get_ioreq(void)
    3.13  ioreq_t* cpu_get_ioreq(void)
    3.14  {
    3.15      int rc;
    3.16 -    uint16_t port;
    3.17 +    evtchn_port_t port;
    3.18  
    3.19      rc = read(evtchn_fd, &port, sizeof(port));
    3.20      if ((rc == sizeof(port)) && (port == ioreq_local_port)) {
    3.21          // unmask the wanted port again
    3.22 -        write(evtchn_fd, &ioreq_local_port, 2);
    3.23 +        write(evtchn_fd, &ioreq_local_port, sizeof(port));
    3.24  
    3.25          //get the io packet from shared memory
    3.26          return __cpu_get_ioreq();
     4.1 --- a/tools/ioemu/vl.c	Thu Dec 01 07:31:50 2005 +0000
     4.2 +++ b/tools/ioemu/vl.c	Thu Dec 01 15:22:22 2005 +0100
     4.3 @@ -2907,7 +2907,7 @@ int main(int argc, char **argv)
     4.4                  break;
     4.5              case QEMU_OPTION_p:
     4.6                  {
     4.7 -                    extern uint16_t ioreq_remote_port;
     4.8 +                    extern evtchn_port_t ioreq_remote_port;
     4.9                      ioreq_remote_port = atoi(optarg);
    4.10                      fprintf(logfile, "eport: %d\n", ioreq_remote_port);
    4.11                  }
     5.1 --- a/tools/libxc/xc_evtchn.c	Thu Dec 01 07:31:50 2005 +0000
     5.2 +++ b/tools/libxc/xc_evtchn.c	Thu Dec 01 15:22:22 2005 +0100
     5.3 @@ -51,7 +51,7 @@ int xc_evtchn_alloc_unbound(int xc_handl
     5.4  
     5.5  int xc_evtchn_status(int xc_handle,
     5.6                       uint32_t dom,
     5.7 -                     int port,
     5.8 +                     evtchn_port_t port,
     5.9                       xc_evtchn_status_t *status)
    5.10  {
    5.11      int         rc;
     6.1 --- a/tools/libxc/xenctrl.h	Thu Dec 01 07:31:50 2005 +0000
     6.2 +++ b/tools/libxc/xenctrl.h	Thu Dec 01 15:22:22 2005 +0100
     6.3 @@ -334,7 +334,7 @@ int xc_evtchn_alloc_unbound(int xc_handl
     6.4  
     6.5  int xc_evtchn_status(int xc_handle,
     6.6                       uint32_t dom, /* may be DOMID_SELF */
     6.7 -                     int port,
     6.8 +                     evtchn_port_t port,
     6.9                       xc_evtchn_status_t *status);
    6.10  
    6.11  int xc_physdev_pci_access_modify(int xc_handle,
     7.1 --- a/tools/xenstore/fake_libxc.c	Thu Dec 01 07:31:50 2005 +0000
     7.2 +++ b/tools/xenstore/fake_libxc.c	Thu Dec 01 15:22:22 2005 +0100
     7.3 @@ -34,7 +34,7 @@
     7.4  
     7.5  static int sigfd;
     7.6  static int xs_test_pid;
     7.7 -static uint16_t port;
     7.8 +static evtchn_port_t port;
     7.9  
    7.10  /* The event channel maps to a signal, shared page to an mmapped file. */
    7.11  void evtchn_notify(int local_port)
     8.1 --- a/tools/xenstore/xenstored_domain.c	Thu Dec 01 07:31:50 2005 +0000
     8.2 +++ b/tools/xenstore/xenstored_domain.c	Thu Dec 01 15:22:22 2005 +0100
     8.3 @@ -41,7 +41,7 @@
     8.4  #include <xen/linux/evtchn.h>
     8.5  
     8.6  static int *xc_handle;
     8.7 -static int virq_port;
     8.8 +static evtchn_port_t virq_port;
     8.9  
    8.10  int eventchn_fd = -1; 
    8.11  
    8.12 @@ -53,11 +53,11 @@ struct domain
    8.13  	unsigned int domid;
    8.14  
    8.15  	/* Event channel port */
    8.16 -	uint16_t port;
    8.17 +	evtchn_port_t port;
    8.18  
    8.19  	/* The remote end of the event channel, used only to validate
    8.20  	   repeated domain introductions. */
    8.21 -	uint16_t remote_port;
    8.22 +	evtchn_port_t remote_port;
    8.23  
    8.24  	/* The mfn associated with the event channel, used only to validate
    8.25  	   repeated domain introductions. */
    8.26 @@ -224,7 +224,7 @@ static void domain_cleanup(void)
    8.27  /* We scan all domains rather than use the information given here. */
    8.28  void handle_event(void)
    8.29  {
    8.30 -	uint16_t port;
    8.31 +	evtchn_port_t port;
    8.32  
    8.33  	if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
    8.34  		barf_perror("Failed to read from event fd");
    8.35 @@ -314,7 +314,7 @@ void do_introduce(struct connection *con
    8.36  	char *vec[3];
    8.37  	unsigned int domid;
    8.38  	unsigned long mfn;
    8.39 -	uint16_t port;
    8.40 +	evtchn_port_t port;
    8.41  
    8.42  	if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
    8.43  		send_error(conn, EINVAL);
    8.44 @@ -460,7 +460,8 @@ void restore_existing_connections(void)
    8.45  
    8.46  static int dom0_init(void) 
    8.47  { 
    8.48 -        int rc, fd, port; 
    8.49 +        int rc, fd;
    8.50 +	evtchn_port_t port; 
    8.51          unsigned long mfn; 
    8.52          char str[20]; 
    8.53          struct domain *dom0; 
     9.1 --- a/xen/include/public/event_channel.h	Thu Dec 01 07:31:50 2005 +0000
     9.2 +++ b/xen/include/public/event_channel.h	Thu Dec 01 15:22:22 2005 +0100
     9.3 @@ -9,6 +9,8 @@
     9.4  #ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
     9.5  #define __XEN_PUBLIC_EVENT_CHANNEL_H__
     9.6  
     9.7 +typedef uint32_t evtchn_port_t;
     9.8 +
     9.9  /*
    9.10   * EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
    9.11   * accepting interdomain bindings from domain <remote_dom>. A fresh port
    9.12 @@ -20,9 +22,9 @@
    9.13  #define EVTCHNOP_alloc_unbound    6
    9.14  typedef struct evtchn_alloc_unbound {
    9.15      /* IN parameters */
    9.16 -    domid_t  dom, remote_dom;
    9.17 +    domid_t dom, remote_dom;
    9.18      /* OUT parameters */
    9.19 -    uint32_t port;
    9.20 +    evtchn_port_t port;
    9.21  } evtchn_alloc_unbound_t;
    9.22  
    9.23  /*
    9.24 @@ -37,10 +39,10 @@ typedef struct evtchn_alloc_unbound {
    9.25  #define EVTCHNOP_bind_interdomain 0
    9.26  typedef struct evtchn_bind_interdomain {
    9.27      /* IN parameters. */
    9.28 -    domid_t  remote_dom;
    9.29 -    uint32_t remote_port;
    9.30 +    domid_t remote_dom;
    9.31 +    evtchn_port_t remote_port;
    9.32      /* OUT parameters. */
    9.33 -    uint32_t local_port;
    9.34 +    evtchn_port_t local_port;
    9.35  } evtchn_bind_interdomain_t;
    9.36  
    9.37  /*
    9.38 @@ -57,7 +59,7 @@ typedef struct evtchn_bind_virq {
    9.39      uint32_t virq;
    9.40      uint32_t vcpu;
    9.41      /* OUT parameters. */
    9.42 -    uint32_t port;
    9.43 +    evtchn_port_t port;
    9.44  } evtchn_bind_virq_t;
    9.45  
    9.46  /*
    9.47 @@ -73,7 +75,7 @@ typedef struct evtchn_bind_pirq {
    9.48  #define BIND_PIRQ__WILL_SHARE 1
    9.49      uint32_t flags; /* BIND_PIRQ__* */
    9.50      /* OUT parameters. */
    9.51 -    uint32_t port;
    9.52 +    evtchn_port_t port;
    9.53  } evtchn_bind_pirq_t;
    9.54  
    9.55  /*
    9.56 @@ -86,7 +88,7 @@ typedef struct evtchn_bind_pirq {
    9.57  typedef struct evtchn_bind_ipi {
    9.58      uint32_t vcpu;
    9.59      /* OUT parameters. */
    9.60 -    uint32_t port;
    9.61 +    evtchn_port_t port;
    9.62  } evtchn_bind_ipi_t;
    9.63  
    9.64  /*
    9.65 @@ -97,7 +99,7 @@ typedef struct evtchn_bind_ipi {
    9.66  #define EVTCHNOP_close            3
    9.67  typedef struct evtchn_close {
    9.68      /* IN parameters. */
    9.69 -    uint32_t port;
    9.70 +    evtchn_port_t port;
    9.71  } evtchn_close_t;
    9.72  
    9.73  /*
    9.74 @@ -107,7 +109,7 @@ typedef struct evtchn_close {
    9.75  #define EVTCHNOP_send             4
    9.76  typedef struct evtchn_send {
    9.77      /* IN parameters. */
    9.78 -    uint32_t port;
    9.79 +    evtchn_port_t port;
    9.80  } evtchn_send_t;
    9.81  
    9.82  /*
    9.83 @@ -122,7 +124,7 @@ typedef struct evtchn_send {
    9.84  typedef struct evtchn_status {
    9.85      /* IN parameters */
    9.86      domid_t  dom;
    9.87 -    uint32_t port;
    9.88 +    evtchn_port_t port;
    9.89      /* OUT parameters */
    9.90  #define EVTCHNSTAT_closed       0  /* Channel is not in use.                 */
    9.91  #define EVTCHNSTAT_unbound      1  /* Channel is waiting interdom connection.*/
    9.92 @@ -134,11 +136,11 @@ typedef struct evtchn_status {
    9.93      uint32_t vcpu;                 /* VCPU to which this channel is bound.   */
    9.94      union {
    9.95          struct {
    9.96 -            domid_t  dom;
    9.97 +            domid_t dom;
    9.98          } unbound; /* EVTCHNSTAT_unbound */
    9.99          struct {
   9.100 -            domid_t  dom;
   9.101 -            uint32_t port;
   9.102 +            domid_t dom;
   9.103 +            evtchn_port_t port;
   9.104          } interdomain; /* EVTCHNSTAT_interdomain */
   9.105          uint32_t pirq;      /* EVTCHNSTAT_pirq        */
   9.106          uint32_t virq;      /* EVTCHNSTAT_virq        */
   9.107 @@ -158,7 +160,7 @@ typedef struct evtchn_status {
   9.108  #define EVTCHNOP_bind_vcpu        8
   9.109  typedef struct evtchn_bind_vcpu {
   9.110      /* IN parameters. */
   9.111 -    uint32_t port;
   9.112 +    evtchn_port_t port;
   9.113      uint32_t vcpu;
   9.114  } evtchn_bind_vcpu_t;
   9.115