svn commit: r310845 - head/sys/boot/i386/common

Toomas Soome tsoome at FreeBSD.org
Fri Dec 30 18:21:54 UTC 2016


Author: tsoome
Date: Fri Dec 30 18:21:52 2016
New Revision: 310845
URL: https://svnweb.freebsd.org/changeset/base/310845

Log:
  boot2 will deadlock if extended keys are used on text input
  
  The boot2 family of bootblocks (zfsboot/gptzfsboot) are using separate
  implementation if keyboard reading code, which has deadlock case when
  extended key (arrows etc) are pressed.
  
  The problem is about avoiding the noise from some systems, generating
  false key events with scan code 1 and ascii code 00, so the code
  does attempt to filter such cases out. Unfortunately the extended keys
  also set ascii 0, and therefore the pressed key event is ignored and
  the keypress is never read, resulting in infinite loop.
  
  This update is moving the check to keyhit() function and is allowing
  the rest of the code to process the extended keys.
  
  Reviewed by:	bapt, allanjude
  Approved by:	allanjude (mentor)
  MFC after:	1 month
  Differential Revision:	https://reviews.freebsd.org/D8608

Modified:
  head/sys/boot/i386/common/cons.c

Modified: head/sys/boot/i386/common/cons.c
==============================================================================
--- head/sys/boot/i386/common/cons.c	Fri Dec 30 18:17:44 2016	(r310844)
+++ head/sys/boot/i386/common/cons.c	Fri Dec 30 18:21:52 2016	(r310845)
@@ -65,18 +65,17 @@ int
 getc(int fn)
 {
 
-	/*
-	 * The extra comparison against zero is an attempt to work around
-	 * what appears to be a bug in QEMU and Bochs. Both emulators
-	 * sometimes report a key-press with scancode one and ascii zero
-	 * when no such key is pressed in reality. As far as I can tell,
-	 * this only happens shortly after a reboot.
-	 */
 	v86.ctl = V86_FLAGS;
 	v86.addr = 0x16;
 	v86.eax = fn << 8;
 	v86int();
-	return fn == 0 ? v86.eax & 0xff : (!V86_ZR(v86.efl) && (v86.eax & 0xff));
+
+	if (fn == 0)
+		return (v86.eax);
+
+	if (V86_ZR(v86.efl))
+		return (0);
+	return (v86.eax);
 }
 
 int
@@ -106,14 +105,22 @@ getchar(void)
 int
 keyhit(unsigned int secs)
 {
-	uint32_t t0, t1;
+	uint32_t t0, t1, c;
 
 	if (OPT_CHECK(RBX_NOINTR))
 		return (0);
 	secs *= SECOND;
 	t0 = 0;
 	for (;;) {
-		if (xgetc(1))
+		/*
+		 * The extra comparison is an attempt to work around
+		 * what appears to be a bug in QEMU and Bochs. Both emulators
+		 * sometimes report a key-press with scancode one and ascii zero
+		 * when no such key is pressed in reality. As far as I can tell,
+		 * this only happens shortly after a reboot.
+		 */
+		c = xgetc(1);
+		if (c != 0 && c != 0x0100)
 			return (1);
 		if (secs > 0) {
 			t1 = *(uint32_t *)PTOV(0x46c);
@@ -134,9 +141,19 @@ getstr(char *cmdstr, size_t cmdstrsize)
 
 	s = cmdstr;
 	for (;;) {
-		switch (c = xgetc(0)) {
-		case 0:
+		c = xgetc(0);
+
+		/* Translate some extended codes. */
+		switch (c) {
+		case 0x5300:    /* delete */
+			c = '\177';
 			break;
+		default:
+			c &= 0xff;
+			break;
+		}
+
+		switch (c) {
 		case '\177':
 		case '\b':
 			if (s > cmdstr) {
@@ -149,9 +166,11 @@ getstr(char *cmdstr, size_t cmdstrsize)
 			*s = 0;
 			return;
 		default:
-			if (s - cmdstr < cmdstrsize - 1)
-				*s++ = c;
-			putchar(c);
+			if (c >= 0x20 && c <= 0x7e) {
+				if (s - cmdstr < cmdstrsize - 1)
+					*s++ = c;
+				putchar(c);
+			}
 			break;
 		}
 	}


More information about the svn-src-all mailing list