diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-02-26 14:58:04 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2004-02-26 14:58:04 +0000 |
commit | dcc1235856fcba9383c7c564329dabaa1e8c91e7 (patch) | |
tree | 12002b9a4e34c1c0c443b2d490bb9d9c603989ae /tools/xc | |
parent | 58ff34519272ac5c51583dc67373269f47868541 (diff) | |
download | xen-dcc1235856fcba9383c7c564329dabaa1e8c91e7.tar.gz xen-dcc1235856fcba9383c7c564329dabaa1e8c91e7.tar.bz2 xen-dcc1235856fcba9383c7c564329dabaa1e8c91e7.zip |
bitkeeper revision 1.749.1.2 (403e097cnc0BYoVqLwFH7-TpqyBF_w)
xc_evtchn.c:
new file
event_channel.h, event_channel.c, Xc.c, xc_private.h, xc.h:
Plumb event channels thru to Python wrapper.
Diffstat (limited to 'tools/xc')
-rw-r--r-- | tools/xc/lib/xc.h | 21 | ||||
-rw-r--r-- | tools/xc/lib/xc_evtchn.c | 104 | ||||
-rw-r--r-- | tools/xc/lib/xc_private.h | 1 | ||||
-rw-r--r-- | tools/xc/py/Xc.c | 164 |
4 files changed, 290 insertions, 0 deletions
diff --git a/tools/xc/lib/xc.h b/tools/xc/lib/xc.h index 74a4fca2ed..2200177932 100644 --- a/tools/xc/lib/xc.h +++ b/tools/xc/lib/xc.h @@ -156,6 +156,27 @@ int xc_vbd_probe(int xc_handle, unsigned int max_vbds, xc_vbd_t *vbds); +#define DOMID_SELF (~1ULL) +#define EVTCHNSTAT_closed 0 /* Chennel is not in use. */ +#define EVTCHNSTAT_disconnected 1 /* Channel is not connected to remote. */ +#define EVTCHNSTAT_connected 2 /* Channel is connected to remote. */ +int xc_evtchn_open(int xc_handle, + u64 dom1, /* may be DOMID_SELF */ + u64 dom2, + int *port1, + int *port2); +int xc_evtchn_close(int xc_handle, + u64 dom, /* may be DOMID_SELF */ + int port); +int xc_evtchn_send(int xc_handle, + int local_port); +int xc_evtchn_status(int xc_handle, + u64 dom1, /* may be DOMID_SELF */ + int port1, + u64 *dom2, + int *port2, + int *chn_status); + int xc_readconsolering(int xc_handle, char *str, unsigned int max_chars, diff --git a/tools/xc/lib/xc_evtchn.c b/tools/xc/lib/xc_evtchn.c new file mode 100644 index 0000000000..b3e17f8951 --- /dev/null +++ b/tools/xc/lib/xc_evtchn.c @@ -0,0 +1,104 @@ +/****************************************************************************** + * xc_evtchn.c + * + * API for manipulating and accessing inter-domain event channels. + * + * Copyright (c) 2004, K A Fraser. + */ + +#include "xc_private.h" + +static int do_evtchn_op(int xc_handle, evtchn_op_t *op) +{ + int ret = -1; + privcmd_hypercall_t hypercall; + + hypercall.op = __HYPERVISOR_event_channel_op; + hypercall.arg[0] = (unsigned long)op; + + if ( mlock(op, sizeof(*op)) != 0 ) + { + PERROR("Could not lock memory for Xen hypercall"); + goto out1; + } + + if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) + goto out2; + + out2: (void)munlock(op, sizeof(*op)); + out1: return ret; +} + +int xc_evtchn_open(int xc_handle, + u64 dom1, + u64 dom2, + int *port1, + int *port2) +{ + evtchn_op_t op; + int rc; + + op.cmd = EVTCHNOP_open; + op.u.open.dom1 = (domid_t)dom1; + op.u.open.dom2 = (domid_t)dom2; + + if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) + { + if ( port1 != NULL ) + *port1 = op.u.open.port1; + if ( port2 != NULL ) + *port2 = op.u.open.port2; + } + + return rc; +} + + +int xc_evtchn_close(int xc_handle, + u64 dom, + int port) +{ + evtchn_op_t op; + op.cmd = EVTCHNOP_close; + op.u.close.dom = (domid_t)dom; + op.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; + op.cmd = EVTCHNOP_send; + op.u.send.local_port = local_port; + return do_evtchn_op(xc_handle, &op); +} + + +int xc_evtchn_status(int xc_handle, + u64 dom1, + int port1, + u64 *dom2, + int *port2, + int *chn_status) +{ + evtchn_op_t op; + int rc; + + op.cmd = EVTCHNOP_status; + op.u.status.dom1 = (domid_t)dom1; + op.u.status.port1 = port1; + + if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 ) + { + if ( dom2 != NULL ) + *dom2 = (u64)op.u.status.dom2; + if ( port2 != NULL ) + *port2 = op.u.status.port2; + if ( chn_status != NULL ) + *chn_status = op.u.status.status; + } + + return rc; +} diff --git a/tools/xc/lib/xc_private.h b/tools/xc/lib/xc_private.h index f5e2c25247..2b5d5604cd 100644 --- a/tools/xc/lib/xc_private.h +++ b/tools/xc/lib/xc_private.h @@ -20,6 +20,7 @@ #include <hypervisor-ifs/hypervisor-if.h> #include <hypervisor-ifs/dom0_ops.h> #include <hypervisor-ifs/vbd.h> +#include <hypervisor-ifs/event_channel.h> #define _PAGE_PRESENT 0x001 #define _PAGE_RW 0x002 diff --git a/tools/xc/py/Xc.c b/tools/xc/py/Xc.c index 2376be5eae..fe29da1cde 100644 --- a/tools/xc/py/Xc.c +++ b/tools/xc/py/Xc.c @@ -765,6 +765,133 @@ static PyObject *pyxc_vbd_probe(PyObject *self, return list; } +static PyObject *pyxc_evtchn_open(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + PyObject *dict; + + u64 dom1 = DOMID_SELF, dom2; + int port1, port2, ret; + + static char *kwd_list[] = { "dom2", "dom1", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "L|L", kwd_list, + &dom2, &dom1) ) + { + DPRINTF("could not parse parameter list."); + return NULL; + } + + ret = xc_evtchn_open(xc->xc_handle, dom1, dom2, &port1, &port2); + + if ( ret < 0 ) + dict = Py_BuildValue("{}"); + else + dict = Py_BuildValue("{s:i,s:i}", + "port1", port1, + "port2", port2); + + return dict; +} + +static PyObject *pyxc_evtchn_close(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + + u64 dom = DOMID_SELF; + int port, ret; + + static char *kwd_list[] = { "port", "dom", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|L", kwd_list, + &port, &dom) ) + { + DPRINTF("could not parse parameter list."); + return NULL; + } + + ret = xc_evtchn_close(xc->xc_handle, dom, port); + + return PyInt_FromLong(ret); +} + +static PyObject *pyxc_evtchn_send(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + + int port, ret; + + static char *kwd_list[] = { "port", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, &port) ) + { + DPRINTF("could not parse parameter list."); + return NULL; + } + + ret = xc_evtchn_send(xc->xc_handle, port); + + return PyInt_FromLong(ret); +} + +static PyObject *pyxc_evtchn_status(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + PyObject *dict; + + u64 dom1 = DOMID_SELF, dom2; + int port1, port2, status, ret; + + static char *kwd_list[] = { "port", "dom", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|L", kwd_list, + &port1, &dom1) ) + { + DPRINTF("could not parse parameter list."); + return NULL; + } + + ret = xc_evtchn_status(xc->xc_handle, dom1, port1, &dom2, &port2, &status); + + if ( ret < 0 ) + { + dict = Py_BuildValue("{}"); + } + else + { + switch ( status ) + { + case EVTCHNSTAT_closed: + dict = Py_BuildValue("{s:s}", + "status", "closed"); + break; + case EVTCHNSTAT_disconnected: + dict = Py_BuildValue("{s:s}", + "status", "disconnected"); + break; + case EVTCHNSTAT_connected: + dict = Py_BuildValue("{s:s,s:L,s:i}", + "status", "connected", + "dom", dom2, + "port", port2); + break; + default: + dict = Py_BuildValue("{}"); + break; + } + } + + return dict; +} + static PyObject *pyxc_readconsolering(PyObject *self, PyObject *args, PyObject *kwds) @@ -1031,6 +1158,43 @@ static PyMethodDef pyxc_methods[] = { " writeable [int]: Bool - is this VBD writeable?\n" " nr_sectors [long]: Size of this VBD, in 512-byte sectors.\n" }, + { "evtchn_open", + (PyCFunction)pyxc_evtchn_open, + METH_VARARGS | METH_KEYWORDS, "\n" + "Open an event channel between two domains.\n" + " dom1 [long, SELF]: First domain to be connected.\n" + " dom2 [long]: 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_close", + (PyCFunction)pyxc_evtchn_close, + METH_VARARGS | METH_KEYWORDS, "\n" + "Close an event channel.\n" + " dom [long, 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" + "Query the status of an event channel.\n" + " dom [long, SELF]: Dom-id of one endpoint of the channel.\n" + " port [int]: Port-id of one endpoint of the channel.\n\n" + "Returns: [dict] dictionary is empty on failure.\n" + " status [str]: 'closed', 'disconnected', or 'connected'.\n" + "The following are also returned if 'status' is 'connected':\n" + " dom [long]: Port-id for endpoint at dom1.\n" + " port [int]: Port-id for endpoint at dom2.\n" }, + { "readconsolering", (PyCFunction)pyxc_readconsolering, METH_VARARGS | METH_KEYWORDS, "\n" |