summaryrefslogtreecommitdiff
path: root/sys/dev/pci
diff options
context:
space:
mode:
authorJan Klemkow <jan@cvs.openbsd.org>2023-07-19 20:22:06 +0000
committerJan Klemkow <jan@cvs.openbsd.org>2023-07-19 20:22:06 +0000
commit807be46d23c02394a5b2b0ea02994b42d38276e2 (patch)
tree528bbaaca2b0d8e1e4471945460e7ef6b43d878d /sys/dev/pci
parent16cf5b2ab630d0ed4c68332b1503e798de408a92 (diff)
Protect ixl(4) admin queue with mutex(9).
with tweaks from bluhm tested by bluhm ok bluhm@
Diffstat (limited to 'sys/dev/pci')
-rw-r--r--sys/dev/pci/if_ixl.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/sys/dev/pci/if_ixl.c b/sys/dev/pci/if_ixl.c
index 3aa9c226c57..5f42dd53953 100644
--- a/sys/dev/pci/if_ixl.c
+++ b/sys/dev/pci/if_ixl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ixl.c,v 1.87 2023/02/06 20:27:45 jan Exp $ */
+/* $OpenBSD: if_ixl.c,v 1.88 2023/07/19 20:22:05 jan Exp $ */
/*
* Copyright (c) 2013-2015, Intel Corporation
@@ -1274,6 +1274,7 @@ struct ixl_softc {
unsigned int sc_atq_prod;
unsigned int sc_atq_cons;
+ struct mutex sc_atq_mtx;
struct ixl_dmamem sc_arq;
struct task sc_arq_task;
struct ixl_aq_bufs sc_arq_idle;
@@ -1723,6 +1724,8 @@ ixl_attach(struct device *parent, struct device *self, void *aux)
/* initialise the adminq */
+ mtx_init(&sc->sc_atq_mtx, IPL_NET);
+
if (ixl_dmamem_alloc(sc, &sc->sc_atq,
sizeof(struct ixl_aq_desc) * IXL_AQ_NUM, IXL_AQ_ALIGN) != 0) {
printf("\n" "%s: unable to allocate atq\n", DEVNAME(sc));
@@ -3599,7 +3602,7 @@ ixl_atq_post(struct ixl_softc *sc, struct ixl_atq *iatq)
struct ixl_aq_desc *atq, *slot;
unsigned int prod;
- /* assert locked */
+ mtx_enter(&sc->sc_atq_mtx);
atq = IXL_DMA_KVA(&sc->sc_atq);
prod = sc->sc_atq_prod;
@@ -3618,6 +3621,8 @@ ixl_atq_post(struct ixl_softc *sc, struct ixl_atq *iatq)
prod &= IXL_AQ_MASK;
sc->sc_atq_prod = prod;
ixl_wr(sc, sc->sc_aq_regs->atq_tail, prod);
+
+ mtx_leave(&sc->sc_atq_mtx);
}
static void
@@ -3628,11 +3633,15 @@ ixl_atq_done(struct ixl_softc *sc)
unsigned int cons;
unsigned int prod;
+ mtx_enter(&sc->sc_atq_mtx);
+
prod = sc->sc_atq_prod;
cons = sc->sc_atq_cons;
- if (prod == cons)
+ if (prod == cons) {
+ mtx_leave(&sc->sc_atq_mtx);
return;
+ }
atq = IXL_DMA_KVA(&sc->sc_atq);
@@ -3645,6 +3654,7 @@ ixl_atq_done(struct ixl_softc *sc)
if (!ISSET(slot->iaq_flags, htole16(IXL_AQ_DD)))
break;
+ KASSERT(slot->iaq_cookie != 0);
iatq = (struct ixl_atq *)slot->iaq_cookie;
iatq->iatq_desc = *slot;
@@ -3661,6 +3671,8 @@ ixl_atq_done(struct ixl_softc *sc)
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
sc->sc_atq_cons = cons;
+
+ mtx_leave(&sc->sc_atq_mtx);
}
static void
@@ -3691,6 +3703,8 @@ ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm)
unsigned int prod;
unsigned int t = 0;
+ mtx_enter(&sc->sc_atq_mtx);
+
atq = IXL_DMA_KVA(&sc->sc_atq);
prod = sc->sc_atq_prod;
slot = atq + prod;
@@ -3712,8 +3726,10 @@ ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm)
while (ixl_rd(sc, sc->sc_aq_regs->atq_head) != prod) {
delaymsec(1);
- if (t++ > tm)
+ if (t++ > tm) {
+ mtx_leave(&sc->sc_atq_mtx);
return (ETIMEDOUT);
+ }
}
bus_dmamap_sync(sc->sc_dmat, IXL_DMA_MAP(&sc->sc_atq),
@@ -3724,6 +3740,7 @@ ixl_atq_poll(struct ixl_softc *sc, struct ixl_aq_desc *iaq, unsigned int tm)
sc->sc_atq_cons = prod;
+ mtx_leave(&sc->sc_atq_mtx);
return (0);
}