From owner-svn-src-head@freebsd.org Wed Mar 29 14:46:27 2017 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 97E3ED23F6C; Wed, 29 Mar 2017 14:46:27 +0000 (UTC) (envelope-from bde@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 722F63CA2; Wed, 29 Mar 2017 14:46:27 +0000 (UTC) (envelope-from bde@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v2TEkQIF020808; Wed, 29 Mar 2017 14:46:26 GMT (envelope-from bde@FreeBSD.org) Received: (from bde@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v2TEkQ3v020805; Wed, 29 Mar 2017 14:46:26 GMT (envelope-from bde@FreeBSD.org) Message-Id: <201703291446.v2TEkQ3v020805@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bde set sender to bde@FreeBSD.org using -f From: Bruce Evans Date: Wed, 29 Mar 2017 14:46:26 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r316136 - head/sys/dev/syscons X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Mar 2017 14:46:27 -0000 Author: bde Date: Wed Mar 29 14:46:26 2017 New Revision: 316136 URL: https://svnweb.freebsd.org/changeset/base/316136 Log: The switch to kernel terminal context needs to update more than the cursor position. Especially the screen size, and potentially everything except the input state and attributes. Do this by changing the cursor position setting method to a general syncing method. Use proper constructors instead of copying to create kernel terminal contexts. We really want clones and not new instances, but there is no method for cloning and there is nothing in the active instance that needs to be cloned exactly. Add proper destructors for kernel terminal contexts. I doubt that the destructor code has every been reached, but if it was then it leaked the memory of the clones. Remove freeing of statically allocated memory for the non-kernel terminal context for the same terminal as the kernel. This is in the nearly unreachable code. This used to not happen because delicate context swapping made the user context use the dynamic memory and kernel context the static memory. I didn't restore this swapping since it would have been unnatural to have all kernel contexts except 1 dynamic. The constructor for terminal context has bad layering for reasons related to the bug. It has to return static memory early before malloc() works. Callers also can't allocate memory until after the first constructor selects an emulator and tells upper layers the size of its context. After that, the cloning hack required the cloning code to allocate the memory, but for all other constructors it would be better for the terminal layer to allocate and deallocate the memory in all cases. Zero the memory when allocating terminal contexts dynamically. Modified: head/sys/dev/syscons/scterm-teken.c head/sys/dev/syscons/syscons.c head/sys/dev/syscons/syscons.h Modified: head/sys/dev/syscons/scterm-teken.c ============================================================================== --- head/sys/dev/syscons/scterm-teken.c Wed Mar 29 11:03:08 2017 (r316135) +++ head/sys/dev/syscons/scterm-teken.c Wed Mar 29 14:46:26 2017 (r316136) @@ -62,7 +62,7 @@ static sc_term_default_attr_t scteken_de static sc_term_clear_t scteken_clear; static sc_term_input_t scteken_input; static sc_term_fkeystr_t scteken_fkeystr; -static sc_term_set_cursor_t scteken_set_cursor; +static sc_term_sync_t scteken_sync; static void scteken_nop(void); typedef struct { @@ -89,7 +89,7 @@ static sc_term_sw_t sc_term_scteken = { (sc_term_notify_t *)scteken_nop, scteken_input, scteken_fkeystr, - scteken_set_cursor, + scteken_sync, }; SCTERM_MODULE(scteken, sc_term_scteken); @@ -219,7 +219,7 @@ scteken_clear(scr_stat *scp) teken_stat *ts = scp->ts; sc_move_cursor(scp, 0, 0); - scteken_set_cursor(scp, 0, 0); + scteken_sync(scp); sc_vtb_clear(&scp->vtb, scp->sc->scr_map[0x20], scteken_te_to_sc_attr(teken_get_curattr(&ts->ts_teken)) << 8); @@ -284,13 +284,16 @@ scteken_fkeystr(scr_stat *scp, int c) } static void -scteken_set_cursor(scr_stat *scp, int col, int row) +scteken_sync(scr_stat *scp) { teken_stat *ts = scp->ts; teken_pos_t tp; - tp.tp_col = col; - tp.tp_row = row; + tp.tp_col = scp->xsize; + tp.tp_row = scp->ysize; + teken_set_winsize_noreset(&ts->ts_teken, &tp); + tp.tp_col = scp->xpos; + tp.tp_row = scp->ypos; teken_set_cursor(&ts->ts_teken, &tp); } Modified: head/sys/dev/syscons/syscons.c ============================================================================== --- head/sys/dev/syscons/syscons.c Wed Mar 29 11:03:08 2017 (r316135) +++ head/sys/dev/syscons/syscons.c Wed Mar 29 14:46:26 2017 (r316136) @@ -567,8 +567,9 @@ sc_attach_unit(int unit, int flags) /* assert(sc_console->ts != NULL); */ oldts = sc_console->ts; for (i = 0; i <= mp_maxid; i++) { - ts = malloc(sc_console->tsw->te_size, M_DEVBUF, M_WAITOK); - bcopy(oldts, ts, sc_console->tsw->te_size); + ts = malloc(sc_console->tsw->te_size, M_DEVBUF, + M_WAITOK | M_ZERO); + (*sc_console->tsw->te_init)(sc_console, &ts, SC_TE_COLD_INIT); sc_console->ts = ts; (*sc_console->tsw->te_default_attr)(sc_console, sc_kattrtab[i], SC_KERNEL_CONS_REV_ATTR); @@ -1705,6 +1706,9 @@ sc_cninit(struct consdev *cp) static void sc_cnterm(struct consdev *cp) { + void *ts; + int i; + /* we are not the kernel console any more, release everything */ if (sc_console_unit < 0) @@ -1715,6 +1719,12 @@ sc_cnterm(struct consdev *cp) sccnupdate(sc_console); #endif + for (i = 0; i <= mp_maxid; i++) { + ts = kernel_console_ts[i]; + kernel_console_ts[i] = NULL; + (*sc_console->tsw->te_term)(sc_console, &ts); + free(ts, M_DEVBUF); + } scterm(sc_console_unit, SC_KERNEL_CONSOLE); sc_console_unit = -1; sc_console = NULL; @@ -1977,11 +1987,11 @@ sc_cnputc(struct consdev *cd, int c) ts = kernel_console_ts[PCPU_GET(cpuid)]; if (ts != NULL) { scp->ts = ts; - (*scp->tsw->te_set_cursor)(scp, scp->xpos, scp->ypos); + (*scp->tsw->te_sync)(scp); } sc_puts(scp, buf, 1); scp->ts = oldts; - (*scp->tsw->te_set_cursor)(scp, scp->xpos, scp->ypos); + (*scp->tsw->te_sync)(scp); } s = spltty(); /* block sckbdevent and scrn_timer */ @@ -3196,7 +3206,7 @@ scinit(int unit, int flags) scp->xpos = col; scp->ypos = row; scp->cursor_pos = scp->cursor_oldpos = row*scp->xsize + col; - (*scp->tsw->te_set_cursor)(scp, col, row); + (*scp->tsw->te_sync)(scp); /* Sync BIOS cursor shape to s/w (sc only). */ if (bios_value.cursor_end < scp->font_size) @@ -3312,12 +3322,11 @@ scterm(int unit, int flags) scp = sc_get_stat(sc->dev[0]); if (scp->tsw) (*scp->tsw->te_term)(scp, &scp->ts); - if (scp->ts != NULL) - free(scp->ts, M_DEVBUF); mtx_destroy(&sc->video_mtx); /* clear the structure */ if (!(flags & SC_KERNEL_CONSOLE)) { + free(scp->ts, M_DEVBUF); /* XXX: We need delete_dev() for this */ free(sc->dev, M_DEVBUF); #if 0 Modified: head/sys/dev/syscons/syscons.h ============================================================================== --- head/sys/dev/syscons/syscons.h Wed Mar 29 11:03:08 2017 (r316135) +++ head/sys/dev/syscons/syscons.h Wed Mar 29 14:46:26 2017 (r316136) @@ -394,7 +394,7 @@ typedef void sc_term_notify_t(scr_stat * #define SC_TE_NOTIFY_VTSWITCH_OUT 1 typedef int sc_term_input_t(scr_stat *scp, int c, struct tty *tp); typedef const char *sc_term_fkeystr_t(scr_stat *scp, int c); -typedef void sc_term_set_cursor_t(scr_stat *scp, int col, int row); +typedef void sc_term_sync_t(scr_stat *scp); typedef struct sc_term_sw { LIST_ENTRY(sc_term_sw) link; @@ -413,7 +413,7 @@ typedef struct sc_term_sw { sc_term_notify_t *te_notify; sc_term_input_t *te_input; sc_term_fkeystr_t *te_fkeystr; - sc_term_set_cursor_t *te_set_cursor; + sc_term_sync_t *te_sync; } sc_term_sw_t; #define SCTERM_MODULE(name, sw) \