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/dac4dc9df8d6
branches:  trunk
changeset: 824996:dac4dc9df8d6
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 199b8f0122b1 -r dac4dc9df8d6 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 199b8f0122b1 -r dac4dc9df8d6 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