aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xc
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-02-26 14:58:04 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2004-02-26 14:58:04 +0000
commitdcc1235856fcba9383c7c564329dabaa1e8c91e7 (patch)
tree12002b9a4e34c1c0c443b2d490bb9d9c603989ae /tools/xc
parent58ff34519272ac5c51583dc67373269f47868541 (diff)
downloadxen-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.h21
-rw-r--r--tools/xc/lib/xc_evtchn.c104
-rw-r--r--tools/xc/lib/xc_private.h1
-rw-r--r--tools/xc/py/Xc.c164
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"