Use atomic operations to manipulate event masking bits
authormikeb <mikeb@openbsd.org>
Wed, 3 Aug 2016 17:14:41 +0000 (17:14 +0000)
committermikeb <mikeb@openbsd.org>
Wed, 3 Aug 2016 17:14:41 +0000 (17:14 +0000)
sys/dev/pv/xen.c
sys/dev/pv/xenvar.h

index 8f4be60..2ec7c4c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: xen.c,v 1.59 2016/08/03 14:55:57 mikeb Exp $  */
+/*     $OpenBSD: xen.c,v 1.60 2016/08/03 17:14:41 mikeb Exp $  */
 
 /*
  * Copyright (c) 2015 Mike Belopuhov
@@ -743,7 +743,7 @@ xen_intr_establish(evtchn_port_t port, xen_intr_handle_t *xih, int domain,
        SLIST_INSERT_HEAD(&sc->sc_intrs, xi, xi_entry);
 
        /* Mask the event port */
-       setbit((char *)&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
+       atomic_setbit_ptr(&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
 
 #if defined(XEN_DEBUG) && disabled
        memset(&es, 0, sizeof(es));
@@ -789,9 +789,8 @@ xen_intr_disestablish(xen_intr_handle_t xih)
 
        taskq_destroy(xi->xi_taskq);
 
-       setbit((char *)&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
-       clrbit((char *)&sc->sc_ipg->evtchn_pending[0], xi->xi_port);
-       virtio_membar_sync();
+       atomic_setbit_ptr(&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
+       atomic_clearbit_ptr(&sc->sc_ipg->evtchn_pending[0], xi->xi_port);
 
        if (!xi->xi_noclose) {
                ec.port = xi->xi_port;
@@ -837,8 +836,7 @@ xen_intr_mask(xen_intr_handle_t xih)
 
        if ((xi = xen_lookup_intsrc(sc, port)) != NULL) {
                xi->xi_masked = 1;
-               setbit((char *)&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
-               virtio_membar_sync();
+               atomic_setbit_ptr(&sc->sc_ipg->evtchn_mask[0], xi->xi_port);
        }
 }
 
index a3cb403..428002d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: xenvar.h,v 1.34 2016/08/03 14:55:58 mikeb Exp $       */
+/*     $OpenBSD: xenvar.h,v 1.35 2016/08/03 17:14:41 mikeb Exp $       */
 
 /*
  * Copyright (c) 2015 Mike Belopuhov
@@ -143,6 +143,18 @@ struct xs_transaction {
        struct xs_softc         *xst_sc;
 };
 
+static inline int
+atomic_setbit_ptr(volatile void *ptr, int bit)
+{
+       int obit;
+
+       __asm__ __volatile__ ("lock btsl %2,%1; sbbl %0,%0" :
+           "=r" (obit), "=m" (*(volatile long *)ptr) : "Ir" (bit) :
+           "memory");
+
+       return (obit);
+}
+
 static inline int
 atomic_clearbit_ptr(volatile void *ptr, int bit)
 {