Commit 6609cff6 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Greg Kroah-Hartman
Browse files

vt: make vt_console_print() compatible with the unicode screen buffer



When kernel messages are printed to the console, they appear blank on
the unicode screen. This is because vt_console_print() is lacking a call
to vc_uniscr_putc(). However the later function assumes vc->vc_x is
always up to date when called, which is not the case here as
vt_console_print() uses it to mark the beginning of the display update.

This patch reworks (and simplifies) vt_console_print() so that vc->vc_x
is always valid and keeps the start of display update in a local variable
instead, which finally allows for adding the missing vc_uniscr_putc()
call.

Signed-off-by: default avatarNicolas Pitre <nico@linaro.org>
Cc: stable@vger.kernel.org # v4.19+
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent fc01d8c6
Loading
Loading
Loading
Loading
+15 −32
Original line number Diff line number Diff line
@@ -2884,8 +2884,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
	unsigned char c;
	static DEFINE_SPINLOCK(printing_lock);
	const ushort *start;
	ushort cnt = 0;
	ushort myx;
	ushort start_x, cnt;
	int kmsg_console;

	/* console busy or not yet initialized */
@@ -2898,10 +2897,6 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
	if (kmsg_console && vc_cons_allocated(kmsg_console - 1))
		vc = vc_cons[kmsg_console - 1].d;

	/* read `x' only after setting currcons properly (otherwise
	   the `x' macro will read the x of the foreground console). */
	myx = vc->vc_x;

	if (!vc_cons_allocated(fg_console)) {
		/* impossible */
		/* printk("vt_console_print: tty %d not allocated ??\n", currcons+1); */
@@ -2916,53 +2911,41 @@ static void vt_console_print(struct console *co, const char *b, unsigned count)
		hide_cursor(vc);

	start = (ushort *)vc->vc_pos;

	/* Contrived structure to try to emulate original need_wrap behaviour
	 * Problems caused when we have need_wrap set on '\n' character */
	start_x = vc->vc_x;
	cnt = 0;
	while (count--) {
		c = *b++;
		if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
			if (cnt > 0) {
				if (con_is_visible(vc))
					vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
				vc->vc_x += cnt;
				if (vc->vc_need_wrap)
					vc->vc_x--;
			if (cnt && con_is_visible(vc))
				vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
			cnt = 0;
			}
			if (c == 8) {		/* backspace */
				bs(vc);
				start = (ushort *)vc->vc_pos;
				myx = vc->vc_x;
				start_x = vc->vc_x;
				continue;
			}
			if (c != 13)
				lf(vc);
			cr(vc);
			start = (ushort *)vc->vc_pos;
			myx = vc->vc_x;
			start_x = vc->vc_x;
			if (c == 10 || c == 13)
				continue;
		}
		vc_uniscr_putc(vc, c);
		scr_writew((vc->vc_attr << 8) + c, (unsigned short *)vc->vc_pos);
		notify_write(vc, c);
		cnt++;
		if (myx == vc->vc_cols - 1) {
		if (vc->vc_x == vc->vc_cols - 1) {
			vc->vc_need_wrap = 1;
			continue;
		}
		} else {
			vc->vc_pos += 2;
		myx++;
	}
	if (cnt > 0) {
		if (con_is_visible(vc))
			vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
		vc->vc_x += cnt;
		if (vc->vc_x == vc->vc_cols) {
			vc->vc_x--;
			vc->vc_need_wrap = 1;
			vc->vc_x++;
		}
	}
	if (cnt && con_is_visible(vc))
		vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
	set_cursor(vc);
	notify_update(vc);