Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 May 2015 07:34:09 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r283187 - stable/10/sys/dev/vt
Message-ID:  <201505210734.t4L7Y9id020714@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu May 21 07:34:08 2015
New Revision: 283187
URL: https://svnweb.freebsd.org/changeset/base/283187

Log:
  MFC r282645, r282646 and r282730:
  * Prevent switching to NULL or own window in the "vt_proc_window_switch"
    function. This fixes an issue where X11 keyboard input can appear
    stuck. The cause of the problem is a duplicate TTY device window
    switch IOCTL during boot, which leaves the "vt_switch_timer" running,
    because the current window is already selected. While at it factor out
    some NULL checks.
  * The "SYSCTL_INT()" default value is only used for read only SYSCTLs
    and is not applicable unless the integer pointer is NULL. Set it to
    zero to avoid confusion. While at it remove extra semicolon at the end
    of the "VT_SYSCTL_INT()" macro.
  * Ensure the result from signed subtraction under modulus does not
    become negative.
  
  PR:			200032

Modified:
  stable/10/sys/dev/vt/vt.h
  stable/10/sys/dev/vt/vt_core.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/vt/vt.h
==============================================================================
--- stable/10/sys/dev/vt/vt.h	Thu May 21 07:23:50 2015	(r283186)
+++ stable/10/sys/dev/vt/vt.h	Thu May 21 07:34:08 2015	(r283187)
@@ -83,10 +83,10 @@
 #define	ISSIGVALID(sig)	((sig) > 0 && (sig) < NSIG)
 
 #define	VT_SYSCTL_INT(_name, _default, _descr)				\
-static int vt_##_name = _default;					\
-SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RW, &vt_##_name, _default,\
+static int vt_##_name = (_default);					\
+SYSCTL_INT(_kern_vt, OID_AUTO, _name, CTLFLAG_RWTUN, &vt_##_name, 0,	\
 		_descr);						\
-TUNABLE_INT("kern.vt." #_name, &vt_##_name);
+TUNABLE_INT("kern.vt." #_name, &vt_##_name)
 
 struct vt_driver;
 

Modified: stable/10/sys/dev/vt/vt_core.c
==============================================================================
--- stable/10/sys/dev/vt/vt_core.c	Thu May 21 07:23:50 2015	(r283186)
+++ stable/10/sys/dev/vt/vt_core.c	Thu May 21 07:34:08 2015	(r283187)
@@ -448,12 +448,35 @@ vt_proc_window_switch(struct vt_window *
 	struct vt_device *vd;
 	int ret;
 
+	/* Prevent switching to NULL */
+	if (vw == NULL) {
+		DPRINTF(30, "%s: Cannot switch: vw is NULL.", __func__);
+		return (EINVAL);
+	}
 	vd = vw->vw_device;
 	curvw = vd->vd_curwindow;
 
+	/* Check if virtual terminal is locked */
 	if (curvw->vw_flags & VWF_VTYLOCK)
 		return (EBUSY);
 
+	/* Check if switch already in progress */
+	if (curvw->vw_flags & VWF_SWWAIT_REL) {
+		/* Check if switching to same window */
+		if (curvw->vw_switch_to == vw) {
+			DPRINTF(30, "%s: Switch in progress to same vw.", __func__);
+			return (0);	/* success */
+		}
+		DPRINTF(30, "%s: Switch in progress to different vw.", __func__);
+		return (EBUSY);
+	}
+
+	/* Avoid switching to already selected window */
+	if (vw == curvw) {
+		DPRINTF(30, "%s: Cannot switch: vw == curvw.", __func__);
+		return (0);	/* success */
+	}
+
 	/* Ask current process permission to switch away. */
 	if (curvw->vw_smode.mode == VT_PROCESS) {
 		DPRINTF(30, "%s: VT_PROCESS ", __func__);
@@ -661,8 +684,7 @@ vt_scrollmode_kbdevent(struct vt_window 
 	if (console == 0) {
 		if (c >= F_SCR && c <= MIN(L_SCR, F_SCR + VT_MAXWINDOWS - 1)) {
 			vw = vd->vd_windows[c - F_SCR];
-			if (vw != NULL)
-				vt_proc_window_switch(vw);
+			vt_proc_window_switch(vw);
 			return;
 		}
 		VT_LOCK(vd);
@@ -747,8 +769,7 @@ vt_processkey(keyboard_t *kbd, struct vt
 
 		if (c >= F_SCR && c <= MIN(L_SCR, F_SCR + VT_MAXWINDOWS - 1)) {
 			vw = vd->vd_windows[c - F_SCR];
-			if (vw != NULL)
-				vt_proc_window_switch(vw);
+			vt_proc_window_switch(vw);
 			return (0);
 		}
 
@@ -757,15 +778,13 @@ vt_processkey(keyboard_t *kbd, struct vt
 			/* Switch to next VT. */
 			c = (vw->vw_number + 1) % VT_MAXWINDOWS;
 			vw = vd->vd_windows[c];
-			if (vw != NULL)
-				vt_proc_window_switch(vw);
+			vt_proc_window_switch(vw);
 			return (0);
 		case PREV:
 			/* Switch to previous VT. */
-			c = (vw->vw_number - 1) % VT_MAXWINDOWS;
+			c = (vw->vw_number + VT_MAXWINDOWS - 1) % VT_MAXWINDOWS;
 			vw = vd->vd_windows[c];
-			if (vw != NULL)
-				vt_proc_window_switch(vw);
+			vt_proc_window_switch(vw);
 			return (0);
 		case SLK: {
 			vt_save_kbd_state(vw, kbd);
@@ -2702,8 +2721,7 @@ vt_resume(struct vt_device *vd)
 
 	if (vt_suspendswitch == 0)
 		return;
-	/* Switch back to saved window */
-	if (vd->vd_savedwindow != NULL)
-		vt_proc_window_switch(vd->vd_savedwindow);
+	/* Switch back to saved window, if any */
+	vt_proc_window_switch(vd->vd_savedwindow);
 	vd->vd_savedwindow = NULL;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201505210734.t4L7Y9id020714>