NetBSD Problem Report #52264

From chris@groessler.org  Tue May 30 22:32:53 2017
Return-Path: <chris@groessler.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 25B4F7A175
	for <gnats-bugs@gnats.NetBSD.org>; Tue, 30 May 2017 22:32:53 +0000 (UTC)
Message-Id: <20170530223236.0F691256C5@muc-twinppc.groessler.org>
Date: Wed, 31 May 2017 00:32:35 +0200 (CEST)
From: chris@groessler.org
Reply-To: chris@groessler.org
To: gnats-bugs@NetBSD.org
Subject: kernel crash when Carrier-Detect signal changes on /dev/ttyZ0
X-Send-Pr-Version: 3.95

>Number:         52264
>Category:       port-macppc
>Synopsis:       kernel crash when Carrier-Detect signal changes on /dev/ttyZ0
>Confidential:   no
>Severity:       critical
>Priority:       medium
>Responsible:    port-macppc-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May 30 22:35:00 +0000 2017
>Last-Modified:  Sat Jun 03 10:50:00 +0000 2017
>Originator:     Christian Groessler
>Release:        -current from around May-4-2017
>Organization:
>Environment:


System: NetBSD muc-twinppc 7.99.71 NetBSD 7.99.71 (TWINPPC.MP) #1: Fri May 26 12:31:09 CEST 2017 chris@muc-twinppc:/local/netbsd-src/src/sys/arch/macppc/compile/TWINPPC.MP macppc
Architecture: powerpc
Machine: macppc
>Description:
	When the CD signal changes, I'm getting the following crash:
	http://www.groessler.org/bild/netbsd-macppc-ttyZ0-crash.jpg
	(I just took a photo and didn't type in the values.)

	Matching the addresses with netbsd.map and a disassembly of the kernel indicates that
	the crash happens in the zstty_stsoft() function of sys/dev/ic/z8530tty.c; the call to
	mutex_spin_exit(&tty_lock).
>How-To-Repeat:
	I'm using a special board to convert the built-in modem of my Mac into a serial line.
	When connected to another machine by a null-modem cable, the crash happens when I start
	"kermit" on the other machine and type "set line <xxx>". "xxx" being the serial port
	connected to the Mac on the other machine.

	The problem doesn't happen when "kermit" is already connected to the serial device prior
	to the boot of the macppc machine. But then it happens when I disconnect kermit from
	the serial line.
>Fix:
	This change fixes it for me. I was looking at sys/dev/ic/com.c for "inspiration":

------------
Index: z8530tty.c
===================================================================
RCS file: /net/swamp/zeug/netbsd-rsync/main/src/sys/dev/ic/z8530tty.c,v
retrieving revision 1.131
diff -u -p -r1.131 z8530tty.c
--- z8530tty.c	15 Nov 2014 19:18:18 -0000	1.131
+++ z8530tty.c	26 May 2017 10:30:07 -0000
@@ -547,7 +547,7 @@ zsopen(dev_t dev, int flags, int mode, s
 	struct zstty_softc *zst;
 	struct zs_chanstate *cs;
 	struct tty *tp;
-	int error;
+	int s, error;

 	zst = device_lookup_private(&zstty_cd, ZSUNIT(dev));
 	if (zst == NULL)
@@ -563,7 +563,7 @@ zsopen(dev_t dev, int flags, int mode, s
 	if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
 		return (EBUSY);

-	mutex_spin_enter(&tty_lock);
+	s = spltty();

 	/*
 	 * Do the following iff this is a first open.
@@ -576,7 +576,7 @@ zsopen(dev_t dev, int flags, int mode, s
 		/* Call the power management hook. */
 		if (cs->enable) {
 			if ((*cs->enable)(cs)) {
-				mutex_spin_exit(&tty_lock);
+				splx(s);
 				printf("%s: device enable failed\n",
 				    device_xname(zst->zst_dev));
 				return (EIO);
@@ -662,7 +662,7 @@ zsopen(dev_t dev, int flags, int mode, s
 		mutex_spin_exit(&cs->cs_lock);
 	}

-	mutex_spin_exit(&tty_lock);
+	splx(s);

 	error = ttyopen(tp, ZSDIALOUT(dev), ISSET(flags, O_NONBLOCK));
 	if (error)
@@ -894,17 +894,18 @@ zsstart(struct tty *tp)
 	struct zstty_softc *zst;
 	struct zs_chanstate *cs;
 	u_char *tba;
-	int tbc;
+	int s, tbc;

 	zst = device_lookup_private(&zstty_cd, ZSUNIT(tp->t_dev));
 	cs = zst->zst_cs;

+	s = spltty();
 	if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP))
-		return;
+		goto out;
 	if (zst->zst_tx_stopped)
-		return;
+		goto out;
 	if (!ttypull(tp))
-		return;
+		goto out;

 	/* Grab the first contiguous region of buffer space. */
 	tba = tp->t_outq.c_cf;
@@ -921,6 +922,7 @@ zsstart(struct tty *tp)
 	if (zst->zst_tbc > 1) {
 		zs_dma_setup(cs, zst->zst_tba, zst->zst_tbc);
 		mutex_spin_exit(&cs->cs_lock);
+		splx(s);
 		return;
 	}
 #endif
@@ -931,6 +933,9 @@ zsstart(struct tty *tp)
 	zst->zst_tba++;

 	mutex_spin_exit(&cs->cs_lock);
+out:
+	splx(s);
+	return;
 }

 /*
@@ -1665,9 +1670,7 @@ zstty_stsoft(struct zstty_softc *zst, st
 		/*
 		 * Inform the tty layer that carrier detect changed.
 		 */
-		mutex_spin_exit(&tty_lock);
 		(void) (*tp->t_linesw->l_modem)(tp, ISSET(rr0, ZSRR0_DCD));
-		mutex_spin_enter(&tty_lock);
 	}

 	if (ISSET(delta, cs->cs_rr0_cts)) {
------------


	There is another driver in sys/dev/ic, cy.c, which uses tty_lock. Don't know if
	it's affected, too. I don't have the hardware to test.

>Audit-Trail:
From: coypu@sdf.org
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/52264: kernel crash when Carrier-Detect signal
 changes on /dev/ttyZ0
Date: Fri, 2 Jun 2017 21:16:06 +0000

 Does restoring the original and reverting 1.119 also help?
 $ cvs rdiff -u -r1.119 -r1.118 src/sys/dev/ic/z8530tty.c | patch -p0

 Ignore the rejected part (RCSID)

From: Christian Groessler <chris@groessler.org>
To: gnats-bugs@NetBSD.org, port-macppc-maintainer@netbsd.org,
        gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/52264: kernel crash when Carrier-Detect signal
 changes on /dev/ttyZ0
Date: Sat, 3 Jun 2017 12:20:07 +0200

 I had tried that first. No, it doesn't work. I'm getting

 http://www.groessler.org/bild/netbsd-macppc-ttyZ0-crash2.jpg

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.39 2013/11/01 18:47:49 spz Exp $
$NetBSD: gnats_config.sh,v 1.8 2006/05/07 09:23:38 tsutsui Exp $
Copyright © 1994-2014 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.