Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci PR/52331: ydc driver: sleep-under-spin-mutex bug...
details: https://anonhg.NetBSD.org/src/rev/5ef60224988d
branches: trunk
changeset: 354695:5ef60224988d
user: christos <christos%NetBSD.org@localhost>
date: Sun Jun 25 16:07:48 2017 +0000
description:
PR/52331: ydc driver: sleep-under-spin-mutex bugs in yds_allocmem
Don't hold the spin interrupt mutex while calling yds_init from resume.
Instead use a flag to short-circuit the interrupt while disabled.
diffstat:
sys/dev/pci/yds.c | 17 ++++++++++++++---
sys/dev/pci/ydsvar.h | 3 ++-
2 files changed, 16 insertions(+), 4 deletions(-)
diffs (90 lines):
diff -r 18d9cfb85ae0 -r 5ef60224988d sys/dev/pci/yds.c
--- a/sys/dev/pci/yds.c Sun Jun 25 15:56:32 2017 +0000
+++ b/sys/dev/pci/yds.c Sun Jun 25 16:07:48 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: yds.c,v 1.58 2017/06/01 02:45:11 chs Exp $ */
+/* $NetBSD: yds.c,v 1.59 2017/06/25 16:07:48 christos Exp $ */
/*
* Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto.
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: yds.c,v 1.58 2017/06/01 02:45:11 chs Exp $");
+__KERNEL_RCSID(0, "$NetBSD: yds.c,v 1.59 2017/06/25 16:07:48 christos Exp $");
#include "mpu.h"
@@ -688,6 +688,7 @@
mutex_enter(&sc->sc_lock);
mutex_spin_enter(&sc->sc_intr_lock);
+ sc->sc_enabled = 0;
sc->sc_dsctrl = pci_conf_read(pc, tag, YDS_PCI_DSCTRL);
sc->sc_legacy = pci_conf_read(pc, tag, YDS_PCI_LEGACY);
sc->sc_ba[0] = pci_conf_read(pc, tag, YDS_PCI_FM_BA);
@@ -718,14 +719,15 @@
PCI_COMMAND_MASTER_ENABLE);
pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, reg);
reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
+ mutex_spin_exit(&sc->sc_intr_lock);
if (yds_init(sc)) {
aprint_error_dev(dv, "reinitialize failed\n");
- mutex_spin_exit(&sc->sc_intr_lock);
mutex_exit(&sc->sc_lock);
return false;
}
pci_conf_write(pc, tag, YDS_PCI_DSCTRL, sc->sc_dsctrl);
+ sc->sc_enabled = 1;
mutex_spin_exit(&sc->sc_intr_lock);
sc->sc_codec[0].codec_if->vtbl->restore_ports(sc->sc_codec[0].codec_if);
mutex_exit(&sc->sc_lock);
@@ -785,6 +787,7 @@
}
aprint_normal_dev(self, "interrupting at %s\n", intrstr);
+ sc->sc_enabled = 0;
sc->sc_dmatag = pa->pa_dmat;
sc->sc_pc = pc;
sc->sc_pcitag = pa->pa_tag;
@@ -940,6 +943,10 @@
if (!pmf_device_register(self, yds_suspend, yds_resume))
aprint_error_dev(self, "couldn't establish power handler\n");
+
+ mutex_spin_enter(&sc->sc_intr_lock);
+ sc->sc_enabled = 1;
+ mutex_spin_exit(&sc->sc_intr_lock);
}
static int
@@ -1046,6 +1053,10 @@
u_int status;
mutex_spin_enter(&sc->sc_intr_lock);
+ if (!sc->sc_enabled) {
+ mutex_spin_exit(&sc->sc_intr_lock);
+ return 0;
+ }
status = YREAD4(sc, YDS_STATUS);
DPRINTFN(1, ("yds_intr: status=%08x\n", status));
diff -r 18d9cfb85ae0 -r 5ef60224988d sys/dev/pci/ydsvar.h
--- a/sys/dev/pci/ydsvar.h Sun Jun 25 15:56:32 2017 +0000
+++ b/sys/dev/pci/ydsvar.h Sun Jun 25 16:07:48 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ydsvar.h,v 1.11 2011/11/23 23:07:36 jmcneill Exp $ */
+/* $NetBSD: ydsvar.h,v 1.12 2017/06/25 16:07:48 christos Exp $ */
/*
* Copyright (c) 2000, 2001 Kazuki Sakamoto and Minoura Makoto.
@@ -66,6 +66,7 @@
bus_space_handle_t memh;
bus_dma_tag_t sc_dmatag; /* DMA tag */
u_int sc_flags;
+ int sc_enabled;
struct yds_codec_softc sc_codec[2]; /* Primary/Secondary AC97 */
Home |
Main Index |
Thread Index |
Old Index