summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2017-07-23 13:51:12 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2017-07-23 13:51:12 +0000
commit9e923a08f464c558a9d9404a71304e68fd9a42c9 (patch)
tree08d6c7cdf82766ed254616a6a449a362effee121 /sys
parent8887a76a351d1af00b4a6cb2ca81d34dfadde2fd (diff)
Prevent a possible "MAC context already removed" panic in iwm_auth().
This panic happens if iwm_newstate_task() sleeps and wakes up after iwm_stop(). The error path of iwm_newstate_task() attempts to reset driver flags and firmware state, which should not be done if iwm_stop() has already done so. A more comprehensive fix for such races is being worked on but not ready yet. For now, check the generation counter in the error path of iwm_auth() and only clean up state if that counter hasn't changed. Problem reported and workaround tested by giovanni@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/if_iwm.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/sys/dev/pci/if_iwm.c b/sys/dev/pci/if_iwm.c
index 88cbcd7498b..7dc3a4564c0 100644
--- a/sys/dev/pci/if_iwm.c
+++ b/sys/dev/pci/if_iwm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_iwm.c,v 1.203 2017/07/22 16:48:58 stsp Exp $ */
+/* $OpenBSD: if_iwm.c,v 1.204 2017/07/23 13:51:11 stsp Exp $ */
/*
* Copyright (c) 2014, 2016 genua gmbh <info@genua.de>
@@ -5375,7 +5375,7 @@ iwm_auth(struct iwm_softc *sc)
struct ieee80211com *ic = &sc->sc_ic;
struct iwm_node *in = (void *)ic->ic_bss;
uint32_t duration;
- int err;
+ int generation = sc->sc_generation, err;
splassert(IPL_NET);
@@ -5427,11 +5427,15 @@ iwm_auth(struct iwm_softc *sc)
return 0;
rm_binding:
- iwm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_REMOVE);
- sc->sc_flags &= ~IWM_FLAG_BINDING_ACTIVE;
+ if (generation == sc->sc_generation) {
+ iwm_binding_cmd(sc, in, IWM_FW_CTXT_ACTION_REMOVE);
+ sc->sc_flags &= ~IWM_FLAG_BINDING_ACTIVE;
+ }
rm_mac_ctxt:
- iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_REMOVE, 0);
- sc->sc_flags &= ~IWM_FLAG_MAC_ACTIVE;
+ if (generation == sc->sc_generation) {
+ iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_REMOVE, 0);
+ sc->sc_flags &= ~IWM_FLAG_MAC_ACTIVE;
+ }
return err;
}