[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

kernel/1438: pcvt: scroll_lock may hang the kernel




>Number:         1438
>Category:       kernel
>Synopsis:       pcvt: scroll_lock may hang the kernel
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Oct 10 04:50:01 MDT 2000
>Last-Modified:
>Originator:     Mathias Schmocker
>Organization:
Mathias Schmocker              SMAT Engineering Sarl
Tel. +41 22 800 3400           Bvd Georges-Favon 20
Fax. +41 22 800 3401           P.O. Box
mailto:smat@acm.org            CH-1211 Geneva 11
http://www.smat.ch/            Switzerland
>Release:        OpenBSD 2.8-beta (GENERIC) updated 1-OCT-2000
>Environment:
	System      : OpenBSD 2.8, 2.7 also affected
	Architecture: OpenBSD.i386
	Machine     : i386
>Description:
	The console pcvt driver implements scroll_lock with tsleep() and
	wakeup() calls (see /sys/arch/i386/isa/pcvt/pcvt_vtf.c and
	pcvt_kbd.c). This may possibly conflict with the tty driver to
	wich pcvt is attached. It is possible to hang the kernel with
	the scroll_lock key as follows:
>How-To-Repeat:
	cd / ; find .    or    cd / ; ls -R
	then scroll_lock on a virtual console until the kernel hangs.
	X is not affected (the X-Term does'nt respond to scroll_lock but
	only to CTRL-S / CTRL-Q).
>Fix:
	I have tried to use tsleep() wakup() differently, without success.

	I have implemented simple XON/XOFF scroll_lock emulation and
	linked CTRL-S CTRL-Q, and output restart with the keyboard leds,
	this works for me. There is still a cosmetic fix to implement:
	i.e SHIFT PgUp after scroll_lock updates sometimes only a portion
	of the screen, any volunteers ?

	I have fixed this after fixing update_led() as explained in
	PR# 1432. The update_led() fix is not directly related with this
	problem.

	I have not tested this fix with the new copy/paste functions in
	pcvt, but I don't think there will be a problem.

	Here are the diffs with my patched sources after reporting
	PR# 1432 (the diffs with the original sources are on different
	line numbers, see the context):

	In directory /sys/arch/i386/isa/pcvt/ :

	file pcvt_kbd.c --> XON/XOFF scroll_lock emulation and update_led()
--- pcvt_kbd.c.NEW.PR_1432	Thu Oct  5 10:34:03 2000
+++ pcvt_kbd.c	Tue Oct 10 09:16:46 2000
@@ -76,6 +76,7 @@
 #include "vt.h"
 /* #if NVT > 0 */
 
+#include <sys/ttydefaults.h>	/* CSTOP, CSTART for XON/XOFF scrlck emul. */
 #include "pcvt_hdr.h"		/* global include */
 
 #define LEDSTATE_UPDATE_PENDING (1 << 3)
@@ -969,9 +970,7 @@
 	u_char *cp, dt, key;
 	u_short	type;
 	static u_char kbd_lastkey = 0; /* last keystroke */
-#ifdef XSERVER
 	static char	keybuf[2] = {0}; /* the second 0 is a delimiter! */
-#endif /* XSERVER */
 
 	static struct {
 		u_char extended: 1;	/* extended prefix seen */
@@ -1332,6 +1331,7 @@
 
 	type &= KBD_MASK;
 
+	keybuf[0] = 0;
 	switch (type) {
 	case KBD_SHFTLOCK:
 		if (!kbd_status.breakseen && key != kbd_lastkey)
@@ -1351,7 +1351,9 @@
 			update_led(KBD_SCROLL);
 
 			if (!(vsp->scroll_lock))
-				wakeup((caddr_t)&(vsp->scroll_lock));
+				keybuf[0] = CSTART;
+			else
+				keybuf[0] = CSTOP;
 		}
 		break;
 
@@ -1385,6 +1387,16 @@
 		kbd_lastkey = key;
 
 	cp = xlatkey2ascii(key);	/* have a key */
+
+	if (cp)				/* link ^S/^Q to scrlck led */
+		if (((*cp == CSTOP) && (!vsp->scroll_lock)) ||
+		    ((*cp == CSTART) && (vsp->scroll_lock))) {
+			vsp->scroll_lock ^= 1;
+			update_led(KBD_SCROLL);
+		}
+
+	if (keybuf[0])			/* XON/XOFF scrlck emul. */
+		cp = (u_char *)keybuf;
 
 	if (cp == NULL && !noblock)
 		goto loop;
------- END OF PATCH

	file pcvt_vtf.c --> removed the tsleep() lines
--- pcvt_vtf.c.NEW.PR_1432	Wed Oct  4 21:27:50 2000
+++ pcvt_vtf.c	Tue Oct 10 09:19:11 2000
@@ -2012,9 +2012,6 @@
 	fillw(user_attr | ' ',
 	    (caddr_t)(svsp->Crtat + ((svsp->scrr_end - n + 1) * svsp->maxcol)),
 	    n * svsp->maxcol);
-
-/*XXX*/	if (svsp->scroll_lock && svsp->openf && curproc)
-		tsleep((caddr_t)&(svsp->scroll_lock), PUSER, "scrlck", 0);
 }
 
 /*---------------------------------------------------------------------------*
@@ -2063,9 +2060,6 @@
 	fillw(user_attr | ' ',
 	    (caddr_t)(svsp->Crtat + (svsp->scrr_beg * svsp->maxcol)),
 	    n * svsp->maxcol);
-
-/*XXX*/	if (svsp->scroll_lock && svsp->openf && curproc)
-		tsleep((caddr_t)&(svsp->scroll_lock), PUSER, "scrlck", 0);
 }
 
 /*---------------------------------------------------------------------------*
------- END OF PATCH

	file pcvt_out.c --> scroll_lock update upon screen roll_up
--- pcvt_out.c.NEW.PR_1432	Wed Oct  4 21:27:02 2000
+++ pcvt_out.c	Tue Oct 10 11:25:56 2000
@@ -1327,6 +1327,11 @@
 
 			svsp->cur_offset -= svsp->maxcol;/* update position */
 
+			if (svsp->scroll_lock) {	/* remove scrlck  */
+				svsp->scroll_lock ^= 1;	/* CSTART,CSTOP   */
+				update_led(KBD_SCROLL);	/* XON/XOFF emul. */
+			}
+
 			if(switch_page != -1)	/* someone wanted to switch ? */
 			{
 				vgapage(switch_page);	/* yes, then switch ! */
------- END OF PATCH

	Please contact me for other infos.
	Mathias smat@acm.org

>Audit-Trail:
>Unformatted: