aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/xc/lib/xc.h39
-rw-r--r--tools/xc/lib/xc_evtchn.c51
-rw-r--r--tools/xc/lib/xc_linux_build.c1
-rw-r--r--tools/xc/lib/xc_netbsd_build.c1
-rw-r--r--tools/xc/py/Xc.c57
-rwxr-xr-xtools/xend/lib/main.py8
-rw-r--r--tools/xend/lib/utils.c3
7 files changed, 98 insertions, 62 deletions
diff --git a/tools/xc/lib/xc.h b/tools/xc/lib/xc.h
index aba2906842..1045be69d0 100644
--- a/tools/xc/lib/xc.h
+++ b/tools/xc/lib/xc.h
@@ -165,25 +165,38 @@ int xc_vbd_probe(int xc_handle,
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, /* may be DOMID_SELF */
- int *port1,
- int *port2);
+
+typedef struct {
+#define EVTCHNSTAT_closed 0 /* Chennel is not in use. */
+#define EVTCHNSTAT_unbound 1 /* Channel is not bound to a source. */
+#define EVTCHNSTAT_interdomain 2 /* Channel is connected to remote domain. */
+#define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */
+#define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */
+ int status;
+ union {
+ struct {
+ u64 dom;
+ int port;
+ } interdomain;
+ int pirq;
+ int virq;
+ } u;
+} xc_evtchn_status_t;
+
+int xc_evtchn_bind_interdomain(int xc_handle,
+ u64 dom1, /* may be DOMID_SELF */
+ u64 dom2, /* may be DOMID_SELF */
+ 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);
+ u64 dom, /* may be DOMID_SELF */
+ int port,
+ xc_evtchn_status_t *status);
int xc_physdev_pci_access_modify(int xc_handle,
u64 domid,
diff --git a/tools/xc/lib/xc_evtchn.c b/tools/xc/lib/xc_evtchn.c
index b3e17f8951..a92cc5b903 100644
--- a/tools/xc/lib/xc_evtchn.c
+++ b/tools/xc/lib/xc_evtchn.c
@@ -29,25 +29,25 @@ static int do_evtchn_op(int xc_handle, evtchn_op_t *op)
out1: return ret;
}
-int xc_evtchn_open(int xc_handle,
- u64 dom1,
- u64 dom2,
- int *port1,
- int *port2)
+int xc_evtchn_bind_interdomain(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;
+ op.cmd = EVTCHNOP_bind_interdomain;
+ op.u.bind_interdomain.dom1 = (domid_t)dom1;
+ op.u.bind_interdomain.dom2 = (domid_t)dom2;
if ( (rc = do_evtchn_op(xc_handle, &op)) == 0 )
{
if ( port1 != NULL )
- *port1 = op.u.open.port1;
+ *port1 = op.u.bind_interdomain.port1;
if ( port2 != NULL )
- *port2 = op.u.open.port2;
+ *port2 = op.u.bind_interdomain.port2;
}
return rc;
@@ -77,27 +77,32 @@ int xc_evtchn_send(int xc_handle,
int xc_evtchn_status(int xc_handle,
- u64 dom1,
- int port1,
- u64 *dom2,
- int *port2,
- int *chn_status)
+ u64 dom,
+ int port,
+ xc_evtchn_status_t *status)
{
evtchn_op_t op;
int rc;
op.cmd = EVTCHNOP_status;
- op.u.status.dom1 = (domid_t)dom1;
- op.u.status.port1 = port1;
+ op.u.status.dom = (domid_t)dom;
+ op.u.status.port = port;
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;
+ switch ( status->status = op.u.status.status )
+ {
+ case EVTCHNSTAT_interdomain:
+ status->u.interdomain.dom = (u64)op.u.status.u.interdomain.dom;
+ status->u.interdomain.port = op.u.status.u.interdomain.port;
+ break;
+ case EVTCHNSTAT_pirq:
+ status->u.pirq = op.u.status.u.pirq;
+ break;
+ case EVTCHNSTAT_virq:
+ status->u.virq = op.u.status.u.virq;
+ break;
+ }
}
return rc;
diff --git a/tools/xc/lib/xc_linux_build.c b/tools/xc/lib/xc_linux_build.c
index fa388d52ef..f9f6949348 100644
--- a/tools/xc/lib/xc_linux_build.c
+++ b/tools/xc/lib/xc_linux_build.c
@@ -248,6 +248,7 @@ static int setup_guestos(int xc_handle,
/* shared_info page starts its life empty. */
shared_info = map_pfn_writeable(pm_handle, shared_info_frame);
memset(shared_info, 0, PAGE_SIZE);
+ shared_info->evtchn_upcall_mask = ~0UL; /* mask all upcalls */
unmap_pfn(pm_handle, shared_info);
/* Send the page update requests down to the hypervisor. */
diff --git a/tools/xc/lib/xc_netbsd_build.c b/tools/xc/lib/xc_netbsd_build.c
index 3472f32257..ae7ebecc6e 100644
--- a/tools/xc/lib/xc_netbsd_build.c
+++ b/tools/xc/lib/xc_netbsd_build.c
@@ -183,6 +183,7 @@ static int setup_guestos(int xc_handle,
/* shared_info page starts its life empty. */
shared_info = map_pfn_writeable(pm_handle, shared_info_frame);
memset(shared_info, 0, PAGE_SIZE);
+ shared_info->evtchn_upcall_mask = ~0UL; /* mask all upcalls */
unmap_pfn(pm_handle, shared_info);
/* Send the page update requests down to the hypervisor. */
diff --git a/tools/xc/py/Xc.c b/tools/xc/py/Xc.c
index 85ad49de9a..96b9bf491a 100644
--- a/tools/xc/py/Xc.c
+++ b/tools/xc/py/Xc.c
@@ -687,9 +687,9 @@ static PyObject *pyxc_vbd_probe(PyObject *self,
return list;
}
-static PyObject *pyxc_evtchn_open(PyObject *self,
- PyObject *args,
- PyObject *kwds)
+static PyObject *pyxc_evtchn_bind_interdomain(PyObject *self,
+ PyObject *args,
+ PyObject *kwds)
{
XcObject *xc = (XcObject *)self;
@@ -702,7 +702,8 @@ static PyObject *pyxc_evtchn_open(PyObject *self,
&dom1, &dom2) )
return NULL;
- if ( xc_evtchn_open(xc->xc_handle, dom1, dom2, &port1, &port2) != 0 )
+ 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}",
@@ -759,34 +760,45 @@ static PyObject *pyxc_evtchn_status(PyObject *self,
XcObject *xc = (XcObject *)self;
PyObject *dict;
- u64 dom1 = DOMID_SELF, dom2;
- int port1, port2, status, ret;
+ u64 dom = DOMID_SELF;
+ int port, ret;
+ xc_evtchn_status_t status;
static char *kwd_list[] = { "port", "dom", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|L", kwd_list,
- &port1, &dom1) )
+ &port, &dom) )
return NULL;
- ret = xc_evtchn_status(xc->xc_handle, dom1, port1, &dom2, &port2, &status);
+ ret = xc_evtchn_status(xc->xc_handle, dom, port, &status);
if ( ret != 0 )
return PyErr_SetFromErrno(xc_error);
- switch ( status )
+ switch ( status.status )
{
case EVTCHNSTAT_closed:
dict = Py_BuildValue("{s:s}",
"status", "closed");
break;
- case EVTCHNSTAT_disconnected:
+ case EVTCHNSTAT_unbound:
dict = Py_BuildValue("{s:s}",
- "status", "disconnected");
+ "status", "unbound");
break;
- case EVTCHNSTAT_connected:
+ case EVTCHNSTAT_interdomain:
dict = Py_BuildValue("{s:s,s:L,s:i}",
- "status", "connected",
- "dom", dom2,
- "port", port2);
+ "status", "interdomain",
+ "dom", status.u.interdomain.dom,
+ "port", status.u.interdomain.port);
+ break;
+ case EVTCHNSTAT_pirq:
+ dict = Py_BuildValue("{s:s,s:i}",
+ "status", "pirq",
+ "irq", status.u.pirq);
+ break;
+ case EVTCHNSTAT_virq:
+ dict = Py_BuildValue("{s:s,s:i}",
+ "status", "virq",
+ "irq", status.u.virq);
break;
default:
dict = Py_BuildValue("{}");
@@ -1134,8 +1146,8 @@ 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,
+ { "evtchn_bind_interdomain",
+ (PyCFunction)pyxc_evtchn_bind_interdomain,
METH_VARARGS | METH_KEYWORDS, "\n"
"Open an event channel between two domains.\n"
" dom1 [long, SELF]: First domain to be connected.\n"
@@ -1166,10 +1178,13 @@ static PyMethodDef pyxc_methods[] = {
" 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" },
+ " status [str]: 'closed', 'unbound', 'interdomain', 'pirq',"
+ " or 'virq'.\n"
+ "The following are returned if 'status' is 'interdomain':\n"
+ " dom [long]: Dom-id of remote endpoint.\n"
+ " port [int]: Port-id of remote endpoint.\n"
+ "The following are returned if 'status' is 'pirq' or 'virq':\n"
+ " irq [int]: IRQ number.\n" },
{ "physdev_pci_access_modify",
(PyCFunction)pyxc_physdev_pci_access_modify,
diff --git a/tools/xend/lib/main.py b/tools/xend/lib/main.py
index 15b2f089cc..6cbfa5ad35 100755
--- a/tools/xend/lib/main.py
+++ b/tools/xend/lib/main.py
@@ -175,16 +175,16 @@ def daemon_loop():
# getting clogged with stale connections.
if type == notifier.DISCONNECT:
ret = xc.evtchn_status(idx)
- if ret['status'] != 'connected':
+ if ret['status'] == 'interdomain':
notifier.clear(idx, notifier.NORMAL)
notifier.clear(idx, notifier.DISCONNECT)
if control_list.has_key(idx):
(port, rbuf, wbuf, con_if) = control_list[idx]
con_if.close()
del control_list[idx], port, rbuf, wbuf, con_if
- elif ret['status'] == 'disconnected':
- # There's noone to do the closure for us...
- xc.evtchn_close(idx)
+ elif ret['status'] == 'unbound':
+ # There's noone to do the closure for us...
+ xc.evtchn_close(idx)
# A standard notification: probably means there are messages to
# read or that there is space to write messages.
diff --git a/tools/xend/lib/utils.c b/tools/xend/lib/utils.c
index 07cba257f5..e57b7ed9d3 100644
--- a/tools/xend/lib/utils.c
+++ b/tools/xend/lib/utils.c
@@ -632,7 +632,8 @@ static PyObject *xu_port_new(PyObject *self, PyObject *args)
goto fail2;
}
- if ( xc_evtchn_open(xup->xc_handle, DOMID_SELF, dom, &port1, &port2) != 0 )
+ if ( xc_evtchn_bind_interdomain(xup->xc_handle,
+ DOMID_SELF, dom, &port1, &port2) != 0 )
{
PyErr_SetString(port_error, "Could not open channel to domain");
goto fail3;