summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2015-12-21 19:43:16 +0000
committermikeb <mikeb@openbsd.org>2015-12-21 19:43:16 +0000
commit925a4773a9a2261d5c4460732cce033c7be8bd88 (patch)
tree5c949f57ff981ad57bff74fd1e557a5ce07f75fc
parentRemove NULL-checks before free(). (diff)
downloadwireguard-openbsd-925a4773a9a2261d5c4460732cce033c7be8bd88.tar.xz
wireguard-openbsd-925a4773a9a2261d5c4460732cce033c7be8bd88.zip
Introduce xen_intr_mask and xen_intr_unmask primitives
Mask the event port during xen_intr_establish, but don't set the masked flag in the intsrc. By providing mask and unmask routines we allow the device to decide when to perform these actions. The port will still be unmasked during xen_intr_enable. This allows netfront to fulfil the intr_barrier pattern requirements fairly easily and at the same time should be sufficient for diskfront that doesn't need to fiddle with interrupt masking.
-rw-r--r--sys/dev/pv/xen.c37
-rw-r--r--sys/dev/pv/xenvar.h4
2 files changed, 39 insertions, 2 deletions
diff --git a/sys/dev/pv/xen.c b/sys/dev/pv/xen.c
index 2a93d5d07ec..d2e7072ff09 100644
--- a/sys/dev/pv/xen.c
+++ b/sys/dev/pv/xen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: xen.c,v 1.17 2015/12/21 18:17:36 mikeb Exp $ */
+/* $OpenBSD: xen.c,v 1.18 2015/12/21 19:43:16 mikeb Exp $ */
/*
* Copyright (c) 2015 Mike Belopuhov
@@ -620,6 +620,9 @@ xen_intr_establish(evtchn_port_t port, xen_intr_handle_t *xih,
SLIST_INSERT_HEAD(&sc->sc_intrs, xi, xi_entry);
+ /* Mask the event port */
+ setbit((char *)&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
+
#if defined(XEN_DEBUG) && disabled
memset(&es, 0, sizeof(es));
es.dom = DOMID_SELF;
@@ -697,6 +700,38 @@ xen_intr_enable(void)
}
}
+void
+xen_intr_mask(xen_intr_handle_t xih)
+{
+ struct xen_softc *sc = xen_sc;
+ evtchn_port_t port = (evtchn_port_t)xih;
+ struct xen_intsrc *xi;
+
+ if ((xi = xen_lookup_intsrc(sc, port)) != NULL) {
+ xi->xi_masked = 1;
+ setbit((char *)&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
+ membar_producer();
+ }
+}
+
+int
+xen_intr_unmask(xen_intr_handle_t xih)
+{
+ struct xen_softc *sc = xen_sc;
+ evtchn_port_t port = (evtchn_port_t)xih;
+ struct xen_intsrc *xi;
+ struct evtchn_unmask eu;
+
+ if ((xi = xen_lookup_intsrc(sc, port)) != NULL) {
+ xi->xi_masked = 0;
+ if (!isset(sc->sc_ipg->evtchn_mask, xi->xi_port))
+ return (0);
+ eu.port = xi->xi_port;
+ return (xen_hypercall(sc, XC_EVTCHN, 2, EVTCHNOP_unmask, &eu));
+ }
+ return (0);
+}
+
static int
xen_attach_print(void *aux, const char *name)
{
diff --git a/sys/dev/pv/xenvar.h b/sys/dev/pv/xenvar.h
index 4d306ba68f4..6b0c136c58f 100644
--- a/sys/dev/pv/xenvar.h
+++ b/sys/dev/pv/xenvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: xenvar.h,v 1.14 2015/12/21 18:17:36 mikeb Exp $ */
+/* $OpenBSD: xenvar.h,v 1.15 2015/12/21 19:43:16 mikeb Exp $ */
/*
* Copyright (c) 2015 Mike Belopuhov
@@ -90,6 +90,8 @@ int xen_intr_establish(evtchn_port_t, xen_intr_handle_t *, void (*)(void *),
void *, char *);
int xen_intr_disestablish(xen_intr_handle_t);
void xen_intr_enable(void);
+void xen_intr_mask(xen_intr_handle_t);
+int xen_intr_unmask(xen_intr_handle_t);
/*
* XenStore