[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] User tools send evtchn notifications via /dev/xen/evtchn
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 76a7a7aa27e40022fbfeacdd8d6ed9395e875894 # Parent 4083eb31def03aa7cb98edf4a390e2f94459efe2 User tools send evtchn notifications via /dev/xen/evtchn rather than using hypercall directly. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> diff -r 4083eb31def0 -r 76a7a7aa27e4 linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Thu Oct 6 15:07:52 2005 +++ b/linux-2.6-xen-sparse/drivers/xen/evtchn/evtchn.c Thu Oct 6 16:02:38 2005 @@ -297,6 +297,24 @@ break; } + case IOCTL_EVTCHN_NOTIFY: { + struct ioctl_evtchn_notify notify; + + rc = -EFAULT; + if (copy_from_user(¬ify, (void *)arg, sizeof(notify))) + break; + + if (notify.port >= NR_EVENT_CHANNELS) { + rc = -EINVAL; + } else if (port_user[notify.port] != u) { + rc = -ENOTCONN; + } else { + notify_remote_via_evtchn(notify.port); + rc = 0; + } + break; + } + case IOCTL_EVTCHN_RESET: { /* Initialise the ring to empty. Clear errors. */ u->ring_cons = u->ring_prod = u->ring_overflow = 0; diff -r 4083eb31def0 -r 76a7a7aa27e4 linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h --- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h Thu Oct 6 15:07:52 2005 +++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/evtchn.h Thu Oct 6 16:02:38 2005 @@ -72,9 +72,18 @@ unsigned int port; }; +/* + * Unbind previously allocated @port. + */ +#define IOCTL_EVTCHN_NOTIFY \ + _IOC(_IOC_NONE, 'E', 4, sizeof(struct ioctl_evtchn_notify)) +struct ioctl_evtchn_notify { + unsigned int port; +}; + /* Clear and reinitialise the event buffer. Clear error condition. */ #define IOCTL_EVTCHN_RESET \ - _IOC(_IOC_NONE, 'E', 4, 0) + _IOC(_IOC_NONE, 'E', 5, 0) #endif /* __LINUX_PUBLIC_EVTCHN_H__ */ diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/console/daemon/io.c --- a/tools/console/daemon/io.c Thu Oct 6 15:07:52 2005 +++ b/tools/console/daemon/io.c Thu Oct 6 16:02:38 2005 @@ -81,6 +81,13 @@ #define XENCONS_FULL(ring) (((ring)->prod - (ring)->cons) == XENCONS_RING_SIZE) #define XENCONS_SPACE(ring) (XENCONS_RING_SIZE - ((ring)->prod - (ring)->cons)) +static void evtchn_notify(struct domain *dom) +{ + struct ioctl_evtchn_notify notify; + notify.port = dom->local_port; + (void)ioctl(dom->evtchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); +} + static void buffer_append(struct domain *dom) { struct buffer *buffer = &dom->buffer; @@ -121,7 +128,7 @@ } if (notify) - xc_evtchn_send(xc, dom->local_port); + evtchn_notify(dom); } static bool buffer_empty(struct buffer *buffer) @@ -440,7 +447,7 @@ inring->buf[XENCONS_IDX(inring->prod)] = msg[i]; inring->prod++; } - xc_evtchn_send(xc, dom->local_port); + evtchn_notify(dom); } else { close(dom->tty_fd); dom->tty_fd = -1; diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/ioemu/target-i386-dm/helper2.c --- a/tools/ioemu/target-i386-dm/helper2.c Thu Oct 6 15:07:52 2005 +++ b/tools/ioemu/target-i386-dm/helper2.c Thu Oct 6 16:02:38 2005 @@ -486,11 +486,9 @@ do_ioapic(); #endif if (env->send_event) { - int ret; - ret = xc_evtchn_send(xc_handle, ioreq_local_port); - if (ret == -1) { - fprintf(logfile, "evtchn_send failed on port: %d\n", ioreq_local_port); - } + struct ioctl_evtchn_notify notify; + notify.port = ioreq_local_port; + (void)ioctl(evtchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); } } destroy_vmx_domain(); diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/libxc/xc_evtchn.c --- a/tools/libxc/xc_evtchn.c Thu Oct 6 15:07:52 2005 +++ b/tools/libxc/xc_evtchn.c Thu Oct 6 16:02:38 2005 @@ -33,92 +33,19 @@ int xc_evtchn_alloc_unbound(int xc_handle, - u32 remote_dom, u32 dom, - int *port) + u32 remote_dom) { int rc; evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound, - .u.alloc_unbound.remote_dom = (domid_t)remote_dom, - .u.alloc_unbound.dom = (domid_t)dom, - .u.alloc_unbound.port = (port != NULL) ? *port : 0 }; + .u.alloc_unbound.dom = (domid_t)dom, + .u.alloc_unbound.remote_dom = (domid_t)remote_dom }; if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) - { - if ( port != NULL ) - *port = op.u.alloc_unbound.port; - } + rc = op.u.alloc_unbound.port; return rc; -} - - -int xc_evtchn_bind_interdomain(int xc_handle, - u32 dom1, - u32 dom2, - int *port1, - int *port2) -{ - int rc; - evtchn_op_t op = { - .cmd = EVTCHNOP_bind_interdomain, - .u.bind_interdomain.dom1 = (domid_t)dom1, - .u.bind_interdomain.dom2 = (domid_t)dom2, - .u.bind_interdomain.port1 = (port1 != NULL) ? *port1 : 0, - .u.bind_interdomain.port2 = (port2 != NULL) ? *port2 : 0 }; - - if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) - { - if ( port1 != NULL ) - *port1 = op.u.bind_interdomain.port1; - if ( port2 != NULL ) - *port2 = op.u.bind_interdomain.port2; - } - - return rc; -} - - -int xc_evtchn_bind_virq(int xc_handle, - int virq, - int *port) -{ - int rc; - evtchn_op_t op = { - .cmd = EVTCHNOP_bind_virq, - .u.bind_virq.virq = (u32)virq, - .u.bind_virq.vcpu = 0 }; - - if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) - { - if ( port != NULL ) - *port = op.u.bind_virq.port; - } - - return rc; -} - - -int xc_evtchn_close(int xc_handle, - u32 dom, - int port) -{ - evtchn_op_t op = { - .cmd = EVTCHNOP_close, - .u.close.dom = (domid_t)dom, - .u.close.port = port }; - return do_evtchn_op(xc_handle, &op); -} - - -int xc_evtchn_send(int xc_handle, - int local_port) -{ - evtchn_op_t op = { - .cmd = EVTCHNOP_send, - .u.send.local_port = local_port }; - return do_evtchn_op(xc_handle, &op); } diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/libxc/xenctrl.h --- a/tools/libxc/xenctrl.h Thu Oct 6 15:07:52 2005 +++ b/tools/libxc/xenctrl.h Thu Oct 6 16:02:38 2005 @@ -306,68 +306,14 @@ * well-known port within a domain to receive events on. * * @parm xc_handle a handle to an open hypervisor interface + * @parm dom the ID of the local domain (the 'allocatee') * @parm remote_dom the ID of the domain who will later bind - * @parm dom the ID of the local domain (the 'allocatee') - * @parm port a pointer to a port. This is an in/out parameter. If *port is - * 0, then a new port will be assigned, if port is > 0 then that - * port is allocated if the port is unallocated. - * @return 0 on success, -1 on failure + * @return allocated port (in @dom) on success, -1 on failure */ int xc_evtchn_alloc_unbound(int xc_handle, - u32 remote_dom, u32 dom, - int *port); - -/** - * This function creates a pair of ports between two domains. A port can only - * be bound once within a domain. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm dom1 one of the two domains to connect. Can be DOMID_SELF. - * @parm dom2 the other domain to connect. Can be DOMID_SELF. - * @parm port1 an in/out parameter. If > 0, then try to connect *port. If - * 0, then allocate a new port and store the port in *port. - * @parm port2 the port connected on port2. This parameter behaves the same - * way as port1. - * @return 0 on success, -1 on error. - */ -int xc_evtchn_bind_interdomain(int xc_handle, - u32 dom1, - u32 dom2, - int *port1, - int *port2); -int xc_evtchn_bind_virq(int xc_handle, - int virq, - int *port); - -/** - * This function will close a single port on an event channel. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm dom the domain that the port exists on. May be DOMID_SELF. - * @parm port the port to close - * @return 0 on success, -1 on error - */ -int xc_evtchn_close(int xc_handle, - u32 dom, /* may be DOMID_SELF */ - int port); - -/** - * This function generates a notify event on a bound port. - * - * Notifies can be read within Linux by opening /dev/xen/evtchn and reading - * a 16 bit value. The result will be the port the event occurred on. When - * events occur, the port is masked until the 16 bit port value is written back - * to the file. When /dev/xen/evtchn is opened, it has to be bound via an - * ioctl to each port to listen on. The ioctl for binding is _IO('E', 2). The - * parameter is the port to listen on. - * - * @parm xc_handle a handle to an open hypervisor interface - * @parm local_port the port to generate the notify on - * @return 0 on success, -1 on error - */ -int xc_evtchn_send(int xc_handle, - int local_port); + u32 remote_dom); + int xc_evtchn_status(int xc_handle, u32 dom, /* may be DOMID_SELF */ int port, diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/python/xen/lowlevel/xc/xc.c --- a/tools/python/xen/lowlevel/xc/xc.c Thu Oct 6 15:07:52 2005 +++ b/tools/python/xen/lowlevel/xc/xc.c Thu Oct 6 16:02:38 2005 @@ -433,7 +433,7 @@ XcObject *xc = (XcObject *)self; u32 dom = DOMID_SELF, remote_dom; - int port = 0; + int port; static char *kwd_list[] = { "remote_dom", "dom", NULL }; @@ -441,95 +441,10 @@ &remote_dom, &dom) ) return NULL; - if ( xc_evtchn_alloc_unbound(xc->xc_handle, remote_dom, dom, &port) != 0 ) + if ( (port = xc_evtchn_alloc_unbound(xc->xc_handle, dom, remote_dom)) < 0 ) return PyErr_SetFromErrno(xc_error); return PyInt_FromLong(port); -} - -static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - - u32 dom1 = DOMID_SELF, dom2 = DOMID_SELF; - int port1 = 0, port2 = 0; - - static char *kwd_list[] = { "dom1", "dom2", "port1", "port2", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiii", kwd_list, - &dom1, &dom2, &port1, &port2) ) - return NULL; - - if ( xc_evtchn_bind_interdomain(xc->xc_handle, dom1, - dom2, &port1, &port2) != 0 ) - return PyErr_SetFromErrno(xc_error); - - return Py_BuildValue("{s:i,s:i}", - "port1", port1, - "port2", port2); -} - -static PyObject *pyxc_evtchn_bind_virq(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - - int virq, port; - - static char *kwd_list[] = { "virq", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &virq) ) - return NULL; - - if ( xc_evtchn_bind_virq(xc->xc_handle, virq, &port) != 0 ) - return PyErr_SetFromErrno(xc_error); - - return PyInt_FromLong(port); -} - -static PyObject *pyxc_evtchn_close(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - - u32 dom = DOMID_SELF; - int port; - - static char *kwd_list[] = { "port", "dom", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, - &port, &dom) ) - return NULL; - - if ( xc_evtchn_close(xc->xc_handle, dom, port) != 0 ) - return PyErr_SetFromErrno(xc_error); - - Py_INCREF(zero); - return zero; -} - -static PyObject *pyxc_evtchn_send(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - - int port; - - static char *kwd_list[] = { "port", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) ) - return NULL; - - if ( xc_evtchn_send(xc->xc_handle, port) != 0 ) - return PyErr_SetFromErrno(xc_error); - - Py_INCREF(zero); - return zero; } static PyObject *pyxc_evtchn_status(PyObject *self, @@ -1032,38 +947,6 @@ " dom [int]: Remote domain to accept connections from.\n\n" "Returns: [int] Unbound event-channel port.\n" }, - { "evtchn_bind_interdomain", - (PyCFunction)pyxc_evtchn_bind_interdomain, - METH_VARARGS | METH_KEYWORDS, "\n" - "Open an event channel between two domains.\n" - " dom1 [int, SELF]: First domain to be connected.\n" - " dom2 [int, SELF]: Second domain to be connected.\n\n" - "Returns: [dict] dictionary is empty on failure.\n" - " port1 [int]: Port-id for endpoint at dom1.\n" - " port2 [int]: Port-id for endpoint at dom2.\n" }, - - { "evtchn_bind_virq", - (PyCFunction)pyxc_evtchn_bind_virq, - METH_VARARGS | METH_KEYWORDS, "\n" - "Bind an event channel to the specified VIRQ.\n" - " virq [int]: VIRQ to bind.\n\n" - "Returns: [int] Bound event-channel port.\n" }, - - { "evtchn_close", - (PyCFunction)pyxc_evtchn_close, - METH_VARARGS | METH_KEYWORDS, "\n" - "Close an event channel. If interdomain, sets remote end to 'unbound'.\n" - " dom [int, SELF]: Dom-id of one endpoint of the channel.\n" - " port [int]: Port-id of one endpoint of the channel.\n\n" - "Returns: [int] 0 on success; -1 on error.\n" }, - - { "evtchn_send", - (PyCFunction)pyxc_evtchn_send, - METH_VARARGS | METH_KEYWORDS, "\n" - "Send an event along a locally-connected event channel.\n" - " port [int]: Port-id of a local channel endpoint.\n\n" - "Returns: [int] 0 on success; -1 on error.\n" }, - { "evtchn_status", (PyCFunction)pyxc_evtchn_status, METH_VARARGS | METH_KEYWORDS, "\n" diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/xenstore/Makefile --- a/tools/xenstore/Makefile Thu Oct 6 15:07:52 2005 +++ b/tools/xenstore/Makefile Thu Oct 6 16:02:38 2005 @@ -29,7 +29,7 @@ all: libxenstore.so xenstored $(CLIENTS) xs_tdb_dump -testcode: xs_test xenstored_test xs_random xs_dom0_test +testcode: xs_test xenstored_test xs_random xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@ @@ -74,7 +74,7 @@ clean: testsuite-clean rm -f *.o *.opic *.so rm -f xenstored xs_random xs_stress xs_crashme - rm -f xs_test xenstored_test xs_dom0_test + rm -f xs_test xenstored_test $(RM) $(PROG_DEP) print-dir: @@ -120,9 +120,6 @@ rm -rf $(TESTDIR)/store $(TESTDIR)/transactions export $(TESTENV); PID=`./xenstored_test --output-pid --trace-file=/tmp/trace`; ./xs_stress 5000; ret=$$?; kill $$PID; exit $$ret -xs_dom0_test: xs_dom0_test.o utils.o - $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@ - TAGS: etags `find . -name '*.[ch]'` diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/xenstore/fake_libxc.c --- a/tools/xenstore/fake_libxc.c Thu Oct 6 15:07:52 2005 +++ b/tools/xenstore/fake_libxc.c Thu Oct 6 16:02:38 2005 @@ -36,12 +36,11 @@ static u16 port; /* The event channel maps to a signal, shared page to an mmapped file. */ -int xc_evtchn_send(int xc_handle __attribute__((unused)), int local_port) +void evtchn_notify(int local_port) { assert(local_port == port); if (kill(xs_test_pid, SIGUSR2) != 0) barf_perror("fake event channel failed"); - return 0; } void *xc_map_foreign_range(int xc_handle, u32 dom __attribute__((unused)), @@ -107,15 +106,6 @@ return 1; } -int xc_evtchn_bind_virq(int xc_handle __attribute__((unused)), - int virq __attribute__((unused)), - int *port) -{ - if (port) - *port = 0; - return 0; -} - static void send_to_fd(int signo __attribute__((unused))) { int saved_errno = errno; diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/xenstore/xenstored_core.c --- a/tools/xenstore/xenstored_core.c Thu Oct 6 15:07:52 2005 +++ b/tools/xenstore/xenstored_core.c Thu Oct 6 16:02:38 2005 @@ -51,6 +51,8 @@ #include "xenstored_domain.h" #include "xenctrl.h" #include "tdb.h" + +int event_fd; static bool verbose; LIST_HEAD(connections); @@ -309,8 +311,7 @@ return 0; } -static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock, - int event_fd) +static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock) { struct connection *i; int max; @@ -1464,7 +1465,7 @@ int main(int argc, char *argv[]) { - int opt, *sock, *ro_sock, event_fd, max; + int opt, *sock, *ro_sock, max; struct sockaddr_un addr; fd_set inset, outset; bool dofork = true; @@ -1568,7 +1569,7 @@ #endif /* Get ready to listen to the tools. */ - max = initialize_set(&inset, &outset, *sock, *ro_sock, event_fd); + max = initialize_set(&inset, &outset, *sock, *ro_sock); /* Main loop. */ /* FIXME: Rewrite so noone can starve. */ @@ -1588,7 +1589,7 @@ accept_connection(*ro_sock, false); if (FD_ISSET(event_fd, &inset)) - handle_event(event_fd); + handle_event(); list_for_each_entry(i, &connections, list) { if (i->domain) @@ -1624,7 +1625,6 @@ } } - max = initialize_set(&inset, &outset, *sock, *ro_sock, - event_fd); - } -} + max = initialize_set(&inset, &outset, *sock, *ro_sock); + } +} diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/xenstore/xenstored_core.h --- a/tools/xenstore/xenstored_core.h Thu Oct 6 15:07:52 2005 +++ b/tools/xenstore/xenstored_core.h Thu Oct 6 16:02:38 2005 @@ -173,4 +173,6 @@ void trace_watch_timeout(const struct connection *conn, const char *node, const char *token); void trace(const char *fmt, ...); +extern int event_fd; + #endif /* _XENSTORED_CORE_H */ diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/xenstore/xenstored_domain.c --- a/tools/xenstore/xenstored_domain.c Thu Oct 6 15:07:52 2005 +++ b/tools/xenstore/xenstored_domain.c Thu Oct 6 16:02:38 2005 @@ -79,6 +79,17 @@ char buf[0]; } __attribute__((packed)); +#ifndef TESTING +static void evtchn_notify(int port) +{ + struct ioctl_evtchn_notify notify; + notify.port = port; + (void)ioctl(event_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); +} +#else +extern void evtchn_notify(int port); +#endif + /* FIXME: Mark connection as broken (close it?) when this happens. */ static bool check_buffer(const struct ringbuf_head *h) { @@ -164,9 +175,7 @@ memcpy(dest, data, len); mb(); update_output_chunk(conn->domain->output, len); - /* FIXME: Probably not neccessary. */ - mb(); - xc_evtchn_send(*xc_handle, conn->domain->port); + evtchn_notify(conn->domain->port); return len; } @@ -199,7 +208,7 @@ /* If it was full, tell them we've taken some. */ if (was_full) - xc_evtchn_send(*xc_handle, conn->domain->port); + evtchn_notify(conn->domain->port); return len; } @@ -249,7 +258,7 @@ } /* We scan all domains rather than use the information given here. */ -void handle_event(int event_fd) +void handle_event(void) { u16 port; diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/xenstore/xenstored_domain.h --- a/tools/xenstore/xenstored_domain.h Thu Oct 6 15:07:52 2005 +++ b/tools/xenstore/xenstored_domain.h Thu Oct 6 16:02:38 2005 @@ -20,7 +20,7 @@ #ifndef _XENSTORED_DOMAIN_H #define _XENSTORED_DOMAIN_H -void handle_event(int event_fd); +void handle_event(void); /* domid, mfn, eventchn, path */ void do_introduce(struct connection *conn, struct buffered_data *in); diff -r 4083eb31def0 -r 76a7a7aa27e4 tools/xenstore/xs_dom0_test.c --- a/tools/xenstore/xs_dom0_test.c Thu Oct 6 15:07:52 2005 +++ /dev/null Thu Oct 6 16:02:38 2005 @@ -1,43 +0,0 @@ -/* Test introduction of domain 0 */ -#include <linux/ioctl.h> -#include <sys/ioctl.h> -#include "xs.h" -#include "utils.h" -#include <xenctrl.h> -#include <xen/linux/privcmd.h> -#include <stdio.h> -#include <unistd.h> -#include <sys/mman.h> - -int main() -{ - int h, local = 0, kernel = 0; - long err; - void *page; - - h = xc_interface_open(); - if (h < 0) - barf_perror("Failed to open xc"); - - if (xc_evtchn_bind_interdomain(h, DOMID_SELF, 0, &local, &kernel) != 0) - barf_perror("Failed to bind interdomain"); - - printf("Got ports %i & %i\n", local, kernel); - - err = ioctl(h, IOCTL_PRIVCMD_INITDOMAIN_STORE, kernel); - if (err < 0) - barf_perror("Failed to initialize store"); - printf("Got mfn %li\n", err); - - page = xc_map_foreign_range(h, 0, getpagesize(), PROT_READ|PROT_WRITE, - err); - if (!page) - barf_perror("Failed to map page %li", err); - printf("Mapped page at %p\n", page); - printf("Page says %s\n", (char *)page); - munmap(page, getpagesize()); - printf("unmapped\n"); - - return 0; -} - _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |