# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID f5b119533cc825726c9ecaa3bd2650b38033d4d8
# Parent d84ffe8f32aef5fe6732dfe83503b36bf1824cd3
Define explicit evtchn_port_t type (32 bits) and plumb up
to user space thru /dev/xen/evtchn.
Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>
diff -r d84ffe8f32ae -r f5b119533cc8
linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c
--- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Thu Dec 1 07:31:50 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Thu Dec 1 14:22:22 2005
@@ -50,9 +50,9 @@
struct per_user_data {
/* Notification ring, accessed via /dev/xen/evtchn. */
-#define EVTCHN_RING_SIZE 2048 /* 2048 16-bit entries */
+#define EVTCHN_RING_SIZE (PAGE_SIZE / sizeof(evtchn_port_t))
#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
- u16 *ring;
+ evtchn_port_t *ring;
unsigned int ring_cons, ring_prod, ring_overflow;
/* Processes wait on this queue when ring is empty. */
@@ -75,7 +75,7 @@
if ((u = port_user[port]) != NULL) {
if ((u->ring_prod - u->ring_cons) < EVTCHN_RING_SIZE) {
- u->ring[EVTCHN_RING_MASK(u->ring_prod)] = (u16)port;
+ u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
if (u->ring_cons == u->ring_prod++) {
wake_up_interruptible(&u->evtchn_wait);
kill_fasync(&u->evtchn_async_queue,
@@ -94,52 +94,40 @@
{
int rc;
unsigned int c, p, bytes1 = 0, bytes2 = 0;
- DECLARE_WAITQUEUE(wait, current);
struct per_user_data *u = file->private_data;
- add_wait_queue(&u->evtchn_wait, &wait);
-
- count &= ~1; /* even number of bytes */
-
- if (count == 0) {
- rc = 0;
- goto out;
- }
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
+
+ if (count == 0)
+ return 0;
if (count > PAGE_SIZE)
count = PAGE_SIZE;
for (;;) {
- set_current_state(TASK_INTERRUPTIBLE);
+ if (u->ring_overflow)
+ return -EFBIG;
if ((c = u->ring_cons) != (p = u->ring_prod))
break;
- if (u->ring_overflow) {
- rc = -EFBIG;
- goto out;
- }
-
- if (file->f_flags & O_NONBLOCK) {
- rc = -EAGAIN;
- goto out;
- }
-
- if (signal_pending(current)) {
- rc = -ERESTARTSYS;
- goto out;
- }
-
- schedule();
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ rc = wait_event_interruptible(
+ u->evtchn_wait, u->ring_cons != u->ring_prod);
+ if (rc)
+ return rc;
}
/* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
- sizeof(u16);
- bytes2 = EVTCHN_RING_MASK(p) * sizeof(u16);
+ sizeof(evtchn_port_t);
+ bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
} else {
- bytes1 = (p - c) * sizeof(u16);
+ bytes1 = (p - c) * sizeof(evtchn_port_t);
bytes2 = 0;
}
@@ -153,32 +141,26 @@
if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
((bytes2 != 0) &&
- copy_to_user(&buf[bytes1], &u->ring[0], bytes2))) {
- rc = -EFAULT;
- goto out;
- }
-
- u->ring_cons += (bytes1 + bytes2) / sizeof(u16);
-
- rc = bytes1 + bytes2;
-
- out:
- __set_current_state(TASK_RUNNING);
- remove_wait_queue(&u->evtchn_wait, &wait);
- return rc;
+ copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
+ return -EFAULT;
+
+ u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
+
+ return bytes1 + bytes2;
}
static ssize_t evtchn_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
int rc, i;
- u16 *kbuf = (u16 *)__get_free_page(GFP_KERNEL);
+ evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
struct per_user_data *u = file->private_data;
if (kbuf == NULL)
return -ENOMEM;
- count &= ~1; /* even number of bytes */
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
if (count == 0) {
rc = 0;
@@ -194,7 +176,7 @@
}
spin_lock_irq(&port_user_lock);
- for (i = 0; i < (count/2); i++)
+ for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
unmask_evtchn(kbuf[i]);
spin_unlock_irq(&port_user_lock);
@@ -379,8 +361,8 @@
memset(u, 0, sizeof(*u));
init_waitqueue_head(&u->evtchn_wait);
- if ((u->ring = (u16 *)__get_free_page(GFP_KERNEL)) == NULL)
- {
+ u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+ if (u->ring == NULL) {
kfree(u);
return -ENOMEM;
}
@@ -400,8 +382,7 @@
free_page((unsigned long)u->ring);
- for (i = 0; i < NR_EVENT_CHANNELS; i++)
- {
+ for (i = 0; i < NR_EVENT_CHANNELS; i++) {
int ret;
if (port_user[i] != u)
continue;
@@ -447,10 +428,9 @@
spin_lock_init(&port_user_lock);
memset(port_user, 0, sizeof(port_user));
- /* (DEVFS) create '/dev/misc/evtchn'. */
+ /* Create '/dev/misc/evtchn'. */
err = misc_register(&evtchn_miscdev);
- if (err != 0)
- {
+ if (err != 0) {
printk(KERN_ALERT "Could not register /dev/misc/evtchn\n");
return err;
}
diff -r d84ffe8f32ae -r f5b119533cc8 tools/console/daemon/io.c
--- a/tools/console/daemon/io.c Thu Dec 1 07:31:50 2005
+++ b/tools/console/daemon/io.c Thu Dec 1 14:22:22 2005
@@ -62,7 +62,7 @@
struct domain *next;
char *conspath;
int ring_ref;
- int local_port;
+ evtchn_port_t local_port;
int evtchn_fd;
struct xencons_interface *interface;
};
@@ -488,7 +488,7 @@
static void handle_ring_read(struct domain *dom)
{
- uint16_t v;
+ evtchn_port_t v;
if (!read_sync(dom->evtchn_fd, &v, sizeof(v)))
return;
diff -r d84ffe8f32ae -r f5b119533cc8 tools/ioemu/target-i386-dm/helper2.c
--- a/tools/ioemu/target-i386-dm/helper2.c Thu Dec 1 07:31:50 2005
+++ b/tools/ioemu/target-i386-dm/helper2.c Thu Dec 1 14:22:22 2005
@@ -125,7 +125,7 @@
//the evtchn port for polling the notification,
//should be inputed as bochs's parameter
-uint16_t ioreq_remote_port, ioreq_local_port;
+evtchn_port_t ioreq_remote_port, ioreq_local_port;
//some functions to handle the io req packet
void sp_info()
@@ -170,12 +170,12 @@
ioreq_t* cpu_get_ioreq(void)
{
int rc;
- uint16_t port;
+ evtchn_port_t port;
rc = read(evtchn_fd, &port, sizeof(port));
if ((rc == sizeof(port)) && (port == ioreq_local_port)) {
// unmask the wanted port again
- write(evtchn_fd, &ioreq_local_port, 2);
+ write(evtchn_fd, &ioreq_local_port, sizeof(port));
//get the io packet from shared memory
return __cpu_get_ioreq();
diff -r d84ffe8f32ae -r f5b119533cc8 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Thu Dec 1 07:31:50 2005
+++ b/tools/ioemu/vl.c Thu Dec 1 14:22:22 2005
@@ -2907,7 +2907,7 @@
break;
case QEMU_OPTION_p:
{
- extern uint16_t ioreq_remote_port;
+ extern evtchn_port_t ioreq_remote_port;
ioreq_remote_port = atoi(optarg);
fprintf(logfile, "eport: %d\n", ioreq_remote_port);
}
diff -r d84ffe8f32ae -r f5b119533cc8 tools/libxc/xc_evtchn.c
--- a/tools/libxc/xc_evtchn.c Thu Dec 1 07:31:50 2005
+++ b/tools/libxc/xc_evtchn.c Thu Dec 1 14:22:22 2005
@@ -51,7 +51,7 @@
int xc_evtchn_status(int xc_handle,
uint32_t dom,
- int port,
+ evtchn_port_t port,
xc_evtchn_status_t *status)
{
int rc;
diff -r d84ffe8f32ae -r f5b119533cc8 tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Thu Dec 1 07:31:50 2005
+++ b/tools/libxc/xenctrl.h Thu Dec 1 14:22:22 2005
@@ -334,7 +334,7 @@
int xc_evtchn_status(int xc_handle,
uint32_t dom, /* may be DOMID_SELF */
- int port,
+ evtchn_port_t port,
xc_evtchn_status_t *status);
int xc_physdev_pci_access_modify(int xc_handle,
diff -r d84ffe8f32ae -r f5b119533cc8 tools/xenstore/fake_libxc.c
--- a/tools/xenstore/fake_libxc.c Thu Dec 1 07:31:50 2005
+++ b/tools/xenstore/fake_libxc.c Thu Dec 1 14:22:22 2005
@@ -34,7 +34,7 @@
static int sigfd;
static int xs_test_pid;
-static uint16_t port;
+static evtchn_port_t port;
/* The event channel maps to a signal, shared page to an mmapped file. */
void evtchn_notify(int local_port)
diff -r d84ffe8f32ae -r f5b119533cc8 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Thu Dec 1 07:31:50 2005
+++ b/tools/xenstore/xenstored_domain.c Thu Dec 1 14:22:22 2005
@@ -41,7 +41,7 @@
#include <xen/linux/evtchn.h>
static int *xc_handle;
-static int virq_port;
+static evtchn_port_t virq_port;
int eventchn_fd = -1;
@@ -53,11 +53,11 @@
unsigned int domid;
/* Event channel port */
- uint16_t port;
+ evtchn_port_t port;
/* The remote end of the event channel, used only to validate
repeated domain introductions. */
- uint16_t remote_port;
+ evtchn_port_t remote_port;
/* The mfn associated with the event channel, used only to validate
repeated domain introductions. */
@@ -224,7 +224,7 @@
/* We scan all domains rather than use the information given here. */
void handle_event(void)
{
- uint16_t port;
+ evtchn_port_t port;
if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port))
barf_perror("Failed to read from event fd");
@@ -314,7 +314,7 @@
char *vec[3];
unsigned int domid;
unsigned long mfn;
- uint16_t port;
+ evtchn_port_t port;
if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) {
send_error(conn, EINVAL);
@@ -460,7 +460,8 @@
static int dom0_init(void)
{
- int rc, fd, port;
+ int rc, fd;
+ evtchn_port_t port;
unsigned long mfn;
char str[20];
struct domain *dom0;
diff -r d84ffe8f32ae -r f5b119533cc8 xen/include/public/event_channel.h
--- a/xen/include/public/event_channel.h Thu Dec 1 07:31:50 2005
+++ b/xen/include/public/event_channel.h Thu Dec 1 14:22:22 2005
@@ -8,6 +8,8 @@
#ifndef __XEN_PUBLIC_EVENT_CHANNEL_H__
#define __XEN_PUBLIC_EVENT_CHANNEL_H__
+
+typedef uint32_t evtchn_port_t;
/*
* EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
@@ -20,9 +22,9 @@
#define EVTCHNOP_alloc_unbound 6
typedef struct evtchn_alloc_unbound {
/* IN parameters */
- domid_t dom, remote_dom;
+ domid_t dom, remote_dom;
/* OUT parameters */
- uint32_t port;
+ evtchn_port_t port;
} evtchn_alloc_unbound_t;
/*
@@ -37,10 +39,10 @@
#define EVTCHNOP_bind_interdomain 0
typedef struct evtchn_bind_interdomain {
/* IN parameters. */
- domid_t remote_dom;
- uint32_t remote_port;
+ domid_t remote_dom;
+ evtchn_port_t remote_port;
/* OUT parameters. */
- uint32_t local_port;
+ evtchn_port_t local_port;
} evtchn_bind_interdomain_t;
/*
@@ -57,7 +59,7 @@
uint32_t virq;
uint32_t vcpu;
/* OUT parameters. */
- uint32_t port;
+ evtchn_port_t port;
} evtchn_bind_virq_t;
/*
@@ -73,7 +75,7 @@
#define BIND_PIRQ__WILL_SHARE 1
uint32_t flags; /* BIND_PIRQ__* */
/* OUT parameters. */
- uint32_t port;
+ evtchn_port_t port;
} evtchn_bind_pirq_t;
/*
@@ -86,7 +88,7 @@
typedef struct evtchn_bind_ipi {
uint32_t vcpu;
/* OUT parameters. */
- uint32_t port;
+ evtchn_port_t port;
} evtchn_bind_ipi_t;
/*
@@ -97,7 +99,7 @@
#define EVTCHNOP_close 3
typedef struct evtchn_close {
/* IN parameters. */
- uint32_t port;
+ evtchn_port_t port;
} evtchn_close_t;
/*
@@ -107,7 +109,7 @@
#define EVTCHNOP_send 4
typedef struct evtchn_send {
/* IN parameters. */
- uint32_t port;
+ evtchn_port_t port;
} evtchn_send_t;
/*
@@ -122,7 +124,7 @@
typedef struct evtchn_status {
/* IN parameters */
domid_t dom;
- uint32_t port;
+ evtchn_port_t port;
/* OUT parameters */
#define EVTCHNSTAT_closed 0 /* Channel is not in use. */
#define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/
@@ -134,11 +136,11 @@
uint32_t vcpu; /* VCPU to which this channel is bound. */
union {
struct {
- domid_t dom;
+ domid_t dom;
} unbound; /* EVTCHNSTAT_unbound */
struct {
- domid_t dom;
- uint32_t port;
+ domid_t dom;
+ evtchn_port_t port;
} interdomain; /* EVTCHNSTAT_interdomain */
uint32_t pirq; /* EVTCHNSTAT_pirq */
uint32_t virq; /* EVTCHNSTAT_virq */
@@ -158,7 +160,7 @@
#define EVTCHNOP_bind_vcpu 8
typedef struct evtchn_bind_vcpu {
/* IN parameters. */
- uint32_t port;
+ evtchn_port_t port;
uint32_t vcpu;
} evtchn_bind_vcpu_t;
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|