In vldcp(8) fix a race between vldcpread() and vldcp_rx_intr() which
authorstsp <stsp@openbsd.org>
Sat, 13 Jan 2018 15:10:02 +0000 (15:10 +0000)
committerstsp <stsp@openbsd.org>
Sat, 13 Jan 2018 15:10:02 +0000 (15:10 +0000)
was overlooked by my previous fix.

Keep SPL at TTY in vldcpread() while manipulating the rx queue head.
Otherwise we could end up in a situation where:
1: vldcpread() reads rx_head
2: vldcpread() calls splx()
3: vldcp_rx_intr() fires, finds rx link is down, and sets rx_head = rx_tail
4: vlcdpread() resumes and sets rx_head to the value it read in step 1
-> same interrupt storm problem as described in my previous commit

ok kettenis@ mpi@

sys/arch/sparc64/dev/vldcp.c

index f8ebc73..7d8bb3a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: vldcp.c,v 1.13 2018/01/06 21:35:45 stsp Exp $ */
+/*     $OpenBSD: vldcp.c,v 1.14 2018/01/13 15:10:02 stsp Exp $ */
 /*
  * Copyright (c) 2009, 2012 Mark Kettenis
  *
@@ -397,7 +397,6 @@ retry:
                }
                goto retry;
        }
-       splx(s);
 
        ret = uiomove(lc->lc_rxq->lq_va + rx_head, 64, uio);
 
@@ -407,6 +406,7 @@ retry:
        if (err != H_EOK)
                printf("%s: hv_ldc_rx_set_qhead %d\n", __func__, err);
 
+       splx(s);
        device_unref(&sc->sc_dv);
        return (ret);
 }