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; } _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"