* [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles @ 2016-12-04 10:53 Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling ` (5 more replies) 0 siblings, 6 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> -- Changes in v7: - Add new callback to consw struct for flushing video console driver's scrollback buffer. Fixes issues with escape sequence '\e[3J' reported by Adam Borowski (kilobyte@angband.pl). - Fix style issues Changes in v6: - Change of check if feature is enabled in vgacon_scrollback_switch() Changes in v5: - Clearify documentation - Skip superfluous array initialization - Disable scrollback if buffer allocation fails - Refactor vgacon_switch_scrollback() - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch() - Add check for fg_console in vgacon_scrollback_update Changes in v4.1: - Fix compiler error Changes in v4: - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to VGACON_SOFT_SCROLLBACK_PERSISTENT - Split into two patches - Rework documentation - Remove cosmetic changes in comments (postponed) Changes in v3: - Add config option for this feature - Fallback to old scrollback buffer if kcalloc() fails - Remove ioctl() call again and add documentation about existing escape sequence to flush the scrollback buffer Changes in v2: - Add ioctl() call to flush scrollback buffer - (Patch v2 was not labeled as such, sorry) Manuel Schölling (3): console: Move scrollback data into its own struct console: Add callback to flush scrollback buffer to consw struct console: Add persistent scrollback buffers for all VGA consoles drivers/tty/vt/vt.c | 9 +++ drivers/video/console/Kconfig | 25 ++++++- drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++------------- include/linux/console.h | 4 + 4 files changed, 148 insertions(+), 55 deletions(-) -- 2.1.4 ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v7 1/3] console: Move scrollback data into its own struct 2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2016-12-04 10:53 ` Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling ` (4 subsequent siblings) 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a562..48b9764 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; +static struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollback; static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; + if (vgacon_scrollback.data) { + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; + vgacon_scrollback.rows = rows - 1; + vgacon_scrollback.size = rows * pitch; } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, + 1024, GFP_NOWAIT); vgacon_scrollback_init(vga_video_num_columns * 2); } @@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + if (!vgacon_scrollback.size || c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + vgacon_scrollback.cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + vgacon_scrollback.tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (vgacon_scrollback.tail >= vgacon_scrollback.size) + vgacon_scrollback.tail = 0; - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; + if (vgacon_scrollback.cnt > vgacon_scrollback.rows) + vgacon_scrollback.cnt = vgacon_scrollback.rows; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback_save = 0; + vgacon_scrollback.save = 0; - if (!vga_is_gfx && !vgacon_scrollback_restore) { + if (!vga_is_gfx && !vgacon_scrollback.restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.restore = 1; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } @@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback) + if (!vgacon_scrollback.data) return; - if (!vgacon_scrollback_save) { + if (!vgacon_scrollback.save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback_save = 1; + vgacon_scrollback.save = 1; } - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; + vgacon_scrollback.restore = 0; + start = vgacon_scrollback.cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; + if (start > vgacon_scrollback.cnt) + start = vgacon_scrollback.cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; + if (end > vgacon_scrollback.cnt) + end = vgacon_scrollback.cnt; - vgacon_scrollback_cur = start; + vgacon_scrollback.cur = start; count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback_size; + soff += vgacon_scrollback.size; - count = vgacon_scrollback_cnt - start; + count = vgacon_scrollback.cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); + copysize = min(count, vgacon_scrollback.size - soff); + scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback, count); + scr_memcpyw(d, vgacon_scrollback.data, count); d += count; } -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct 2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling @ 2016-12-04 10:53 ` Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling ` (3 subsequent siblings) 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel This new callback is in preparation for persistent scrollback buffer support for VGA consoles. With a single scrollback buffer for all consoles, we could flush the buffer just by invocating consw->con_switch(). But when each VGA console has its own scrollback buffer, we need a new callback to tell the video console driver which buffer to flush. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/tty/vt/vt.c | 9 +++++++++ drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++- include/linux/console.h | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4c10a9d..9d3ce50 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc) vc->vc_sw->con_save_screen(vc); } +static void flush_scrollback(struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + if (vc->vc_sw->con_flush_scrollback) + vc->vc_sw->con_flush_scrollback(vc); +} + /* * Redrawing of screen */ @@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar) case 3: /* erase scroll-back buffer (and whole display) */ scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, vc->vc_screenbuf_size); + flush_scrollback(vc); set_origin(vc); if (con_is_visible(vc)) update_screen(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 48b9764..9a7c2bb 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -173,6 +173,16 @@ static struct vgacon_scrollback_info { int restore; } vgacon_scrollback; +static void vgacon_scrollback_reset(size_t reset_size) +{ + if (vgacon_scrollback.data && reset_size > 0) + memset(vgacon_scrollback.data, 0, reset_size); + + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; +} + static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; @@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) } else vgacon_cursor(c, CM_MOVE); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + if (c->vc_num == fg_console) + vgacon_scrollback_reset(size); +} #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) @@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_vram_size); vga_set_mem_top(c); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ +} #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ static const char *vgacon_startup(void) @@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, return true; } - /* * The console `switch' structure for the VGA based console */ @@ -1362,6 +1383,7 @@ const struct consw vga_con = { .con_save_screen = vgacon_save_screen, .con_build_attr = vgacon_build_attr, .con_invert_region = vgacon_invert_region, + .con_flush_scrollback = vgacon_flush_scrollback, }; EXPORT_SYMBOL(vga_con); diff --git a/include/linux/console.h b/include/linux/console.h index 9c26c66..5949d18 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -73,6 +73,10 @@ struct consw { u16 *(*con_screen_pos)(struct vc_data *, int); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); /* + * Flush the video console driver's scrollback buffer + */ + void (*con_flush_scrollback)(struct vc_data *); + /* * Prepare the console for the debugger. This includes, but is not * limited to, unblanking the console, loading an appropriate * palette, and allowing debugger generated output. -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles 2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling @ 2016-12-04 10:53 ` Manuel Schölling 2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH ` (2 subsequent siblings) 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-04 10:53 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel Add a scrollback buffers for each VGA console. The benefit is that the scrollback history is not flushed when switching between consoles but is persistent. The buffers are allocated on demand when a new console is opened. This breaks tools like clear_console that rely on flushing the scrollback history by switching back and forth between consoles which is why this feature is disabled by default. Use the escape sequence \e[3J instead for flushing the buffer. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/Kconfig | 25 +++++++- drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..c5742d2 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE range 1 1024 default "64" help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer + Enter the amount of System RAM to allocate for scrollback + buffers of VGA consoles. Each 64KB will give you approximately + 16 80x25 screenfuls of scrollback buffer. + +config VGACON_SOFT_SCROLLBACK_PERSISTENT + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if the scrollback history should persist when switching + between consoles. Otherwise, the scrollback history will be flushed + each time the console is switched. + + This feature might break your tool of choice to flush the scrollback + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) + will be broken, which might cause security issues. + You can use the escape sequence \e[3J instead if this feature is + activated. + + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each + created tty device. + So if you use a RAM-constrained system, say N here. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9a7c2bb..ca23d22 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static struct vgacon_scrollback_info { +struct vgacon_scrollback_info { void *data; int tail; int size; @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { int cur; int save; int restore; -} vgacon_scrollback; +}; + +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; +#else +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; +#endif -static void vgacon_scrollback_reset(size_t reset_size) +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { - if (vgacon_scrollback.data && reset_size > 0) - memset(vgacon_scrollback.data, 0, reset_size); + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; + + if (scrollback->data && reset_size > 0) + memset(scrollback->data, 0, reset_size); - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; + scrollback->cnt = 0; + scrollback->tail = 0; + scrollback->cur = 0; } -static void vgacon_scrollback_init(int pitch) +static void vgacon_scrollback_init(int vc_num) { - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback.data) { - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; - vgacon_scrollback.rows = rows - 1; - vgacon_scrollback.size = rows * pitch; + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size / pitch; + void *data; + + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, + GFP_NOWAIT); + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + + vgacon_scrollback_cur->rows = rows - 1; + vgacon_scrollback_cur->size = rows * pitch; + + vgacon_scrollback_reset(vc_num, size); +} + +static void vgacon_scrollback_switch(int vc_num) +{ +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vc_num = 0; +#endif + + if (!vgacon_scrollbacks[vc_num].data) { + vgacon_scrollback_init(vc_num); + } else { +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + vgacon_scrollback_reset(vc_num, size); +#endif } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, - 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback.size || c->vc_num != fg_console) + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || + c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, + scr_memcpyw(vgacon_scrollback_cur->data + + vgacon_scrollback_cur->tail, p, c->vc_size_row); - vgacon_scrollback.cnt++; + + vgacon_scrollback_cur->cnt++; p += c->vc_size_row; - vgacon_scrollback.tail += c->vc_size_row; + vgacon_scrollback_cur->tail += c->vc_size_row; - if (vgacon_scrollback.tail >= vgacon_scrollback.size) - vgacon_scrollback.tail = 0; + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) + vgacon_scrollback_cur->tail = 0; - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) - vgacon_scrollback.cnt = vgacon_scrollback.rows; + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback.save = 0; + vgacon_scrollback_cur->save = 0; - if (!vga_is_gfx && !vgacon_scrollback.restore) { + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback.restore = 1; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->restore = 1; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback.data) + if (!vgacon_scrollback_cur->data) return; - if (!vgacon_scrollback.save) { + if (!vgacon_scrollback_cur->save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback.save = 1; + vgacon_scrollback_cur->save = 1; } - vgacon_scrollback.restore = 0; - start = vgacon_scrollback.cur + lines; + vgacon_scrollback_cur->restore = 0; + start = vgacon_scrollback_cur->cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback.cnt) - start = vgacon_scrollback.cnt; + if (start > vgacon_scrollback_cur->cnt) + start = vgacon_scrollback_cur->cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback.cnt) - end = vgacon_scrollback.cnt; + if (end > vgacon_scrollback_cur->cnt) + end = vgacon_scrollback_cur->cnt; - vgacon_scrollback.cur = start; + vgacon_scrollback_cur->cur = start; count = end - start; - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * - c->vc_size_row); + soff = vgacon_scrollback_cur->tail - + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback.size; + soff += vgacon_scrollback_cur->size; - count = vgacon_scrollback.cnt - start; + count = vgacon_scrollback_cur->cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback.size - soff); - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); + copysize = min(count, vgacon_scrollback_cur->size - soff); + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback.data, count); + scr_memcpyw(d, vgacon_scrollback_cur->data, count); d += count; } @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) { size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - if (c->vc_num == fg_console) - vgacon_scrollback_reset(size); + vgacon_scrollback_reset(c->vc_num, size); } #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) #define vgacon_scrollback_update(...) do { } while (0) +#define vgacon_scrollback_switch(...) do { } while (0) static void vgacon_restore_screen(struct vc_data *c) { @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); + vgacon_scrollback_switch(c->vc_num); return 0; /* Redrawing not needed */ } -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles 2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling ` (2 preceding siblings ...) 2016-12-04 10:53 ` [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2016-12-06 10:02 ` Greg KH 2016-12-06 16:32 ` Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 5 siblings, 1 reply; 49+ messages in thread From: Greg KH @ 2016-12-06 10:02 UTC (permalink / raw) To: Manuel Schölling Cc: plagnioj, tomi.valkeinen, jslaby, andrey_utkin, kilobyte, linux-fbdev, linux-kernel On Sun, Dec 04, 2016 at 11:53:53AM +0100, Manuel Schölling wrote: > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > Tested-by: Adam Borowski <kilobyte@angband.pl> > > -- > Changes in v7: > - Add new callback to consw struct for flushing video console driver's > scrollback buffer. Fixes issues with escape sequence '\e[3J' reported > by Adam Borowski (kilobyte@angband.pl). > - Fix style issues But this is now v8, right? I see two v7 patch series in my inbox :( confused, greg k-h ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles 2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH @ 2016-12-06 16:32 ` Manuel Schölling 0 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-06 16:32 UTC (permalink / raw) To: Greg KH Cc: plagnioj, tomi.valkeinen, jslaby, andrey_utkin, kilobyte, linux-fbdev, linux-kernel Hi Greg, On Di, 2016-12-06 at 11:02 +0100, Greg KH wrote: > On Sun, Dec 04, 2016 at 11:53:53AM +0100, Manuel Schölling wrote: > > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > > Tested-by: Adam Borowski <kilobyte@angband.pl> > > > > -- > > Changes in v7: > > - Add new callback to consw struct for flushing video console driver's > > scrollback buffer. Fixes issues with escape sequence '\e[3J' reported > > by Adam Borowski (kilobyte@angband.pl). > > - Fix style issues > > But this is now v8, right? I see two v7 patch series in my inbox :( > > confused, Sorry for causing confusion. I wasn't sure about the workflow so asked on #kernelnewbies a few days ago but apparently I misunderstood the advice I got there: This is just the same patch (v7) as I sent before, but I added the Tested-By/Reviewed-By tags. ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles 2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling ` (3 preceding siblings ...) 2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH @ 2016-12-21 16:37 ` Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling ` (3 more replies) 2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 5 siblings, 4 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> -- Changes in v7: - Add new callback to consw struct for flushing video console driver's scrollback buffer. Fixes issues with escape sequence '\e[3J' reported by Adam Borowski (kilobyte@angband.pl). - Fix style issues Changes in v6: - Change of check if feature is enabled in vgacon_scrollback_switch() Changes in v5: - Clearify documentation - Skip superfluous array initialization - Disable scrollback if buffer allocation fails - Refactor vgacon_switch_scrollback() - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch() - Add check for fg_console in vgacon_scrollback_update Changes in v4.1: - Fix compiler error Changes in v4: - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to VGACON_SOFT_SCROLLBACK_PERSISTENT - Split into two patches - Rework documentation - Remove cosmetic changes in comments (postponed) Changes in v3: - Add config option for this feature - Fallback to old scrollback buffer if kcalloc() fails - Remove ioctl() call again and add documentation about existing escape sequence to flush the scrollback buffer Changes in v2: - Add ioctl() call to flush scrollback buffer - (Patch v2 was not labeled as such, sorry) Manuel Schölling (3): console: Move scrollback data into its own struct console: Add callback to flush scrollback buffer to consw struct console: Add persistent scrollback buffers for all VGA consoles drivers/tty/vt/vt.c | 9 +++ drivers/video/console/Kconfig | 25 ++++++- drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++------------- include/linux/console.h | 4 + 4 files changed, 148 insertions(+), 55 deletions(-) -- 2.1.4 ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct 2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling @ 2016-12-21 16:37 ` Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling ` (2 subsequent siblings) 3 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a562..48b9764 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; +static struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollback; static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; + if (vgacon_scrollback.data) { + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; + vgacon_scrollback.rows = rows - 1; + vgacon_scrollback.size = rows * pitch; } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, + 1024, GFP_NOWAIT); vgacon_scrollback_init(vga_video_num_columns * 2); } @@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + if (!vgacon_scrollback.size || c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + vgacon_scrollback.cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + vgacon_scrollback.tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (vgacon_scrollback.tail >= vgacon_scrollback.size) + vgacon_scrollback.tail = 0; - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; + if (vgacon_scrollback.cnt > vgacon_scrollback.rows) + vgacon_scrollback.cnt = vgacon_scrollback.rows; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback_save = 0; + vgacon_scrollback.save = 0; - if (!vga_is_gfx && !vgacon_scrollback_restore) { + if (!vga_is_gfx && !vgacon_scrollback.restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.restore = 1; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } @@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback) + if (!vgacon_scrollback.data) return; - if (!vgacon_scrollback_save) { + if (!vgacon_scrollback.save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback_save = 1; + vgacon_scrollback.save = 1; } - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; + vgacon_scrollback.restore = 0; + start = vgacon_scrollback.cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; + if (start > vgacon_scrollback.cnt) + start = vgacon_scrollback.cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; + if (end > vgacon_scrollback.cnt) + end = vgacon_scrollback.cnt; - vgacon_scrollback_cur = start; + vgacon_scrollback.cur = start; count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback_size; + soff += vgacon_scrollback.size; - count = vgacon_scrollback_cnt - start; + count = vgacon_scrollback.cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); + copysize = min(count, vgacon_scrollback.size - soff); + scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback, count); + scr_memcpyw(d, vgacon_scrollback.data, count); d += count; } -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct 2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling @ 2016-12-21 16:37 ` Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-04 13:54 ` [PATCH RESEND v7 0/3] " Andrey Utkin 3 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel This new callback is in preparation for persistent scrollback buffer support for VGA consoles. With a single scrollback buffer for all consoles, we could flush the buffer just by invocating consw->con_switch(). But when each VGA console has its own scrollback buffer, we need a new callback to tell the video console driver which buffer to flush. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/tty/vt/vt.c | 9 +++++++++ drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++- include/linux/console.h | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4c10a9d..9d3ce50 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc) vc->vc_sw->con_save_screen(vc); } +static void flush_scrollback(struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + if (vc->vc_sw->con_flush_scrollback) + vc->vc_sw->con_flush_scrollback(vc); +} + /* * Redrawing of screen */ @@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar) case 3: /* erase scroll-back buffer (and whole display) */ scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, vc->vc_screenbuf_size); + flush_scrollback(vc); set_origin(vc); if (con_is_visible(vc)) update_screen(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 48b9764..9a7c2bb 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -173,6 +173,16 @@ static struct vgacon_scrollback_info { int restore; } vgacon_scrollback; +static void vgacon_scrollback_reset(size_t reset_size) +{ + if (vgacon_scrollback.data && reset_size > 0) + memset(vgacon_scrollback.data, 0, reset_size); + + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; +} + static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; @@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) } else vgacon_cursor(c, CM_MOVE); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + if (c->vc_num == fg_console) + vgacon_scrollback_reset(size); +} #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) @@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_vram_size); vga_set_mem_top(c); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ +} #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ static const char *vgacon_startup(void) @@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, return true; } - /* * The console `switch' structure for the VGA based console */ @@ -1362,6 +1383,7 @@ const struct consw vga_con = { .con_save_screen = vgacon_save_screen, .con_build_attr = vgacon_build_attr, .con_invert_region = vgacon_invert_region, + .con_flush_scrollback = vgacon_flush_scrollback, }; EXPORT_SYMBOL(vga_con); diff --git a/include/linux/console.h b/include/linux/console.h index 9c26c66..5949d18 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -73,6 +73,10 @@ struct consw { u16 *(*con_screen_pos)(struct vc_data *, int); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); /* + * Flush the video console driver's scrollback buffer + */ + void (*con_flush_scrollback)(struct vc_data *); + /* * Prepare the console for the debugger. This includes, but is not * limited to, unblanking the console, loading an appropriate * palette, and allowing debugger generated output. -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles 2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling @ 2016-12-21 16:37 ` Manuel Schölling 2017-01-04 13:54 ` [PATCH RESEND v7 0/3] " Andrey Utkin 3 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2016-12-21 16:37 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel Add a scrollback buffers for each VGA console. The benefit is that the scrollback history is not flushed when switching between consoles but is persistent. The buffers are allocated on demand when a new console is opened. This breaks tools like clear_console that rely on flushing the scrollback history by switching back and forth between consoles which is why this feature is disabled by default. Use the escape sequence \e[3J instead for flushing the buffer. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/Kconfig | 25 +++++++- drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..c5742d2 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE range 1 1024 default "64" help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer + Enter the amount of System RAM to allocate for scrollback + buffers of VGA consoles. Each 64KB will give you approximately + 16 80x25 screenfuls of scrollback buffer. + +config VGACON_SOFT_SCROLLBACK_PERSISTENT + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if the scrollback history should persist when switching + between consoles. Otherwise, the scrollback history will be flushed + each time the console is switched. + + This feature might break your tool of choice to flush the scrollback + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) + will be broken, which might cause security issues. + You can use the escape sequence \e[3J instead if this feature is + activated. + + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each + created tty device. + So if you use a RAM-constrained system, say N here. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9a7c2bb..ca23d22 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static struct vgacon_scrollback_info { +struct vgacon_scrollback_info { void *data; int tail; int size; @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { int cur; int save; int restore; -} vgacon_scrollback; +}; + +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; +#else +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; +#endif -static void vgacon_scrollback_reset(size_t reset_size) +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { - if (vgacon_scrollback.data && reset_size > 0) - memset(vgacon_scrollback.data, 0, reset_size); + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; + + if (scrollback->data && reset_size > 0) + memset(scrollback->data, 0, reset_size); - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; + scrollback->cnt = 0; + scrollback->tail = 0; + scrollback->cur = 0; } -static void vgacon_scrollback_init(int pitch) +static void vgacon_scrollback_init(int vc_num) { - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback.data) { - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; - vgacon_scrollback.rows = rows - 1; - vgacon_scrollback.size = rows * pitch; + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size / pitch; + void *data; + + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, + GFP_NOWAIT); + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + + vgacon_scrollback_cur->rows = rows - 1; + vgacon_scrollback_cur->size = rows * pitch; + + vgacon_scrollback_reset(vc_num, size); +} + +static void vgacon_scrollback_switch(int vc_num) +{ +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vc_num = 0; +#endif + + if (!vgacon_scrollbacks[vc_num].data) { + vgacon_scrollback_init(vc_num); + } else { +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + vgacon_scrollback_reset(vc_num, size); +#endif } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, - 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback.size || c->vc_num != fg_console) + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || + c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, + scr_memcpyw(vgacon_scrollback_cur->data + + vgacon_scrollback_cur->tail, p, c->vc_size_row); - vgacon_scrollback.cnt++; + + vgacon_scrollback_cur->cnt++; p += c->vc_size_row; - vgacon_scrollback.tail += c->vc_size_row; + vgacon_scrollback_cur->tail += c->vc_size_row; - if (vgacon_scrollback.tail >= vgacon_scrollback.size) - vgacon_scrollback.tail = 0; + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) + vgacon_scrollback_cur->tail = 0; - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) - vgacon_scrollback.cnt = vgacon_scrollback.rows; + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback.save = 0; + vgacon_scrollback_cur->save = 0; - if (!vga_is_gfx && !vgacon_scrollback.restore) { + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback.restore = 1; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->restore = 1; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback.data) + if (!vgacon_scrollback_cur->data) return; - if (!vgacon_scrollback.save) { + if (!vgacon_scrollback_cur->save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback.save = 1; + vgacon_scrollback_cur->save = 1; } - vgacon_scrollback.restore = 0; - start = vgacon_scrollback.cur + lines; + vgacon_scrollback_cur->restore = 0; + start = vgacon_scrollback_cur->cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback.cnt) - start = vgacon_scrollback.cnt; + if (start > vgacon_scrollback_cur->cnt) + start = vgacon_scrollback_cur->cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback.cnt) - end = vgacon_scrollback.cnt; + if (end > vgacon_scrollback_cur->cnt) + end = vgacon_scrollback_cur->cnt; - vgacon_scrollback.cur = start; + vgacon_scrollback_cur->cur = start; count = end - start; - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * - c->vc_size_row); + soff = vgacon_scrollback_cur->tail - + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback.size; + soff += vgacon_scrollback_cur->size; - count = vgacon_scrollback.cnt - start; + count = vgacon_scrollback_cur->cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback.size - soff); - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); + copysize = min(count, vgacon_scrollback_cur->size - soff); + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback.data, count); + scr_memcpyw(d, vgacon_scrollback_cur->data, count); d += count; } @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) { size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - if (c->vc_num == fg_console) - vgacon_scrollback_reset(size); + vgacon_scrollback_reset(c->vc_num, size); } #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) #define vgacon_scrollback_update(...) do { } while (0) +#define vgacon_scrollback_switch(...) do { } while (0) static void vgacon_restore_screen(struct vc_data *c) { @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); + vgacon_scrollback_switch(c->vc_num); return 0; /* Redrawing not needed */ } -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles 2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling ` (2 preceding siblings ...) 2016-12-21 16:37 ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2017-01-04 13:54 ` Andrey Utkin 2017-01-05 11:33 ` [PATCH v8 " Manuel Schölling ` (3 more replies) 3 siblings, 4 replies; 49+ messages in thread From: Andrey Utkin @ 2017-01-04 13:54 UTC (permalink / raw) To: Manuel Schölling Cc: plagnioj, tomi.valkeinen, jslaby, gregkh, kilobyte, linux-fbdev, linux-kernel Manuel, Previous Greg KH reply implied that you should send it marked as v8 for it to gain visibility and avoid confusion. Just prepend your changes history with something like Changes in v8: - Added Reviewed-by, Tested-by statements ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v8 0/3] console: Add persistent scrollback buffers for all VGA consoles 2017-01-04 13:54 ` [PATCH RESEND v7 0/3] " Andrey Utkin @ 2017-01-05 11:33 ` Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 1/3] console: Move scrollback data into its own struct Manuel Schölling ` (2 subsequent siblings) 3 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> -- Changes in v8: - Add Reviewed-by/Tested-By statements Changes in v7: - Add new callback to consw struct for flushing video console driver's scrollback buffer. Fixes issues with escape sequence '\e[3J' reported by Adam Borowski (kilobyte@angband.pl). - Fix style issues Changes in v6: - Change of check if feature is enabled in vgacon_scrollback_switch() Changes in v5: - Clearify documentation - Skip superfluous array initialization - Disable scrollback if buffer allocation fails - Refactor vgacon_switch_scrollback() - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch() - Add check for fg_console in vgacon_scrollback_update Changes in v4.1: - Fix compiler error Changes in v4: - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to VGACON_SOFT_SCROLLBACK_PERSISTENT - Split into two patches - Rework documentation - Remove cosmetic changes in comments (postponed) Changes in v3: - Add config option for this feature - Fallback to old scrollback buffer if kcalloc() fails - Remove ioctl() call again and add documentation about existing escape sequence to flush the scrollback buffer Changes in v2: - Add ioctl() call to flush scrollback buffer - (Patch v2 was not labeled as such, sorry) Manuel Schölling (3): console: Move scrollback data into its own struct console: Add callback to flush scrollback buffer to consw struct console: Add persistent scrollback buffers for all VGA consoles drivers/tty/vt/vt.c | 9 +++ drivers/video/console/Kconfig | 25 ++++++- drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++------------- include/linux/console.h | 4 + 4 files changed, 148 insertions(+), 55 deletions(-) -- 2.11.0 ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v8 1/3] console: Move scrollback data into its own struct 2017-01-04 13:54 ` [PATCH RESEND v7 0/3] " Andrey Utkin 2017-01-05 11:33 ` [PATCH v8 " Manuel Schölling @ 2017-01-05 11:33 ` Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 3 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a56232b7c..48b97648d4af 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; +static struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollback; static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; + if (vgacon_scrollback.data) { + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; + vgacon_scrollback.rows = rows - 1; + vgacon_scrollback.size = rows * pitch; } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, + 1024, GFP_NOWAIT); vgacon_scrollback_init(vga_video_num_columns * 2); } @@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + if (!vgacon_scrollback.size || c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + vgacon_scrollback.cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + vgacon_scrollback.tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (vgacon_scrollback.tail >= vgacon_scrollback.size) + vgacon_scrollback.tail = 0; - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; + if (vgacon_scrollback.cnt > vgacon_scrollback.rows) + vgacon_scrollback.cnt = vgacon_scrollback.rows; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback_save = 0; + vgacon_scrollback.save = 0; - if (!vga_is_gfx && !vgacon_scrollback_restore) { + if (!vga_is_gfx && !vgacon_scrollback.restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.restore = 1; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } @@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback) + if (!vgacon_scrollback.data) return; - if (!vgacon_scrollback_save) { + if (!vgacon_scrollback.save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback_save = 1; + vgacon_scrollback.save = 1; } - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; + vgacon_scrollback.restore = 0; + start = vgacon_scrollback.cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; + if (start > vgacon_scrollback.cnt) + start = vgacon_scrollback.cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; + if (end > vgacon_scrollback.cnt) + end = vgacon_scrollback.cnt; - vgacon_scrollback_cur = start; + vgacon_scrollback.cur = start; count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback_size; + soff += vgacon_scrollback.size; - count = vgacon_scrollback_cnt - start; + count = vgacon_scrollback.cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); + copysize = min(count, vgacon_scrollback.size - soff); + scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback, count); + scr_memcpyw(d, vgacon_scrollback.data, count); d += count; } -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct 2017-01-04 13:54 ` [PATCH RESEND v7 0/3] " Andrey Utkin 2017-01-05 11:33 ` [PATCH v8 " Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 1/3] console: Move scrollback data into its own struct Manuel Schölling @ 2017-01-05 11:33 ` Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 3 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling This new callback is in preparation for persistent scrollback buffer support for VGA consoles. With a single scrollback buffer for all consoles, we could flush the buffer just by invocating consw->con_switch(). But when each VGA console has its own scrollback buffer, we need a new callback to tell the video console driver which buffer to flush. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/tty/vt/vt.c | 9 +++++++++ drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++- include/linux/console.h | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4c10a9df3b91..9d3ce505e7ab 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc) vc->vc_sw->con_save_screen(vc); } +static void flush_scrollback(struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + if (vc->vc_sw->con_flush_scrollback) + vc->vc_sw->con_flush_scrollback(vc); +} + /* * Redrawing of screen */ @@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar) case 3: /* erase scroll-back buffer (and whole display) */ scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, vc->vc_screenbuf_size); + flush_scrollback(vc); set_origin(vc); if (con_is_visible(vc)) update_screen(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 48b97648d4af..9a7c2bbc5326 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -173,6 +173,16 @@ static struct vgacon_scrollback_info { int restore; } vgacon_scrollback; +static void vgacon_scrollback_reset(size_t reset_size) +{ + if (vgacon_scrollback.data && reset_size > 0) + memset(vgacon_scrollback.data, 0, reset_size); + + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; +} + static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; @@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) } else vgacon_cursor(c, CM_MOVE); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + if (c->vc_num == fg_console) + vgacon_scrollback_reset(size); +} #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) @@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_vram_size); vga_set_mem_top(c); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ +} #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ static const char *vgacon_startup(void) @@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, return true; } - /* * The console `switch' structure for the VGA based console */ @@ -1362,6 +1383,7 @@ const struct consw vga_con = { .con_save_screen = vgacon_save_screen, .con_build_attr = vgacon_build_attr, .con_invert_region = vgacon_invert_region, + .con_flush_scrollback = vgacon_flush_scrollback, }; EXPORT_SYMBOL(vga_con); diff --git a/include/linux/console.h b/include/linux/console.h index 9c26c6685587..5949d1855589 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -73,6 +73,10 @@ struct consw { u16 *(*con_screen_pos)(struct vc_data *, int); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); /* + * Flush the video console driver's scrollback buffer + */ + void (*con_flush_scrollback)(struct vc_data *); + /* * Prepare the console for the debugger. This includes, but is not * limited to, unblanking the console, loading an appropriate * palette, and allowing debugger generated output. -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles 2017-01-04 13:54 ` [PATCH RESEND v7 0/3] " Andrey Utkin ` (2 preceding siblings ...) 2017-01-05 11:33 ` [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling @ 2017-01-05 11:33 ` Manuel Schölling [not found] ` <CGME20170110162224epcas1p2095912fa6b73a1457fa86396149e78e9@epcas1p2.samsung.com> 3 siblings, 1 reply; 49+ messages in thread From: Manuel Schölling @ 2017-01-05 11:33 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling Add a scrollback buffers for each VGA console. The benefit is that the scrollback history is not flushed when switching between consoles but is persistent. The buffers are allocated on demand when a new console is opened. This breaks tools like clear_console that rely on flushing the scrollback history by switching back and forth between consoles which is why this feature is disabled by default. Use the escape sequence \e[3J instead for flushing the buffer. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/Kconfig | 25 +++++++- drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index c3f1fb9ee820..f500e58f7636 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE range 1 1024 default "64" help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer + Enter the amount of System RAM to allocate for scrollback + buffers of VGA consoles. Each 64KB will give you approximately + 16 80x25 screenfuls of scrollback buffer. + +config VGACON_SOFT_SCROLLBACK_PERSISTENT + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if the scrollback history should persist when switching + between consoles. Otherwise, the scrollback history will be flushed + each time the console is switched. + + This feature might break your tool of choice to flush the scrollback + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) + will be broken, which might cause security issues. + You can use the escape sequence \e[3J instead if this feature is + activated. + + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each + created tty device. + So if you use a RAM-constrained system, say N here. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9a7c2bbc5326..ca23d222e029 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static struct vgacon_scrollback_info { +struct vgacon_scrollback_info { void *data; int tail; int size; @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { int cur; int save; int restore; -} vgacon_scrollback; +}; + +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; +#else +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; +#endif -static void vgacon_scrollback_reset(size_t reset_size) +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { - if (vgacon_scrollback.data && reset_size > 0) - memset(vgacon_scrollback.data, 0, reset_size); + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; + + if (scrollback->data && reset_size > 0) + memset(scrollback->data, 0, reset_size); - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; + scrollback->cnt = 0; + scrollback->tail = 0; + scrollback->cur = 0; } -static void vgacon_scrollback_init(int pitch) +static void vgacon_scrollback_init(int vc_num) { - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback.data) { - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; - vgacon_scrollback.rows = rows - 1; - vgacon_scrollback.size = rows * pitch; + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size / pitch; + void *data; + + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, + GFP_NOWAIT); + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + + vgacon_scrollback_cur->rows = rows - 1; + vgacon_scrollback_cur->size = rows * pitch; + + vgacon_scrollback_reset(vc_num, size); +} + +static void vgacon_scrollback_switch(int vc_num) +{ +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vc_num = 0; +#endif + + if (!vgacon_scrollbacks[vc_num].data) { + vgacon_scrollback_init(vc_num); + } else { +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + vgacon_scrollback_reset(vc_num, size); +#endif } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, - 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback.size || c->vc_num != fg_console) + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || + c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, + scr_memcpyw(vgacon_scrollback_cur->data + + vgacon_scrollback_cur->tail, p, c->vc_size_row); - vgacon_scrollback.cnt++; + + vgacon_scrollback_cur->cnt++; p += c->vc_size_row; - vgacon_scrollback.tail += c->vc_size_row; + vgacon_scrollback_cur->tail += c->vc_size_row; - if (vgacon_scrollback.tail >= vgacon_scrollback.size) - vgacon_scrollback.tail = 0; + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) + vgacon_scrollback_cur->tail = 0; - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) - vgacon_scrollback.cnt = vgacon_scrollback.rows; + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback.save = 0; + vgacon_scrollback_cur->save = 0; - if (!vga_is_gfx && !vgacon_scrollback.restore) { + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback.restore = 1; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->restore = 1; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback.data) + if (!vgacon_scrollback_cur->data) return; - if (!vgacon_scrollback.save) { + if (!vgacon_scrollback_cur->save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback.save = 1; + vgacon_scrollback_cur->save = 1; } - vgacon_scrollback.restore = 0; - start = vgacon_scrollback.cur + lines; + vgacon_scrollback_cur->restore = 0; + start = vgacon_scrollback_cur->cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback.cnt) - start = vgacon_scrollback.cnt; + if (start > vgacon_scrollback_cur->cnt) + start = vgacon_scrollback_cur->cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback.cnt) - end = vgacon_scrollback.cnt; + if (end > vgacon_scrollback_cur->cnt) + end = vgacon_scrollback_cur->cnt; - vgacon_scrollback.cur = start; + vgacon_scrollback_cur->cur = start; count = end - start; - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * - c->vc_size_row); + soff = vgacon_scrollback_cur->tail - + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback.size; + soff += vgacon_scrollback_cur->size; - count = vgacon_scrollback.cnt - start; + count = vgacon_scrollback_cur->cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback.size - soff); - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); + copysize = min(count, vgacon_scrollback_cur->size - soff); + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback.data, count); + scr_memcpyw(d, vgacon_scrollback_cur->data, count); d += count; } @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) { size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - if (c->vc_num == fg_console) - vgacon_scrollback_reset(size); + vgacon_scrollback_reset(c->vc_num, size); } #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) #define vgacon_scrollback_update(...) do { } while (0) +#define vgacon_scrollback_switch(...) do { } while (0) static void vgacon_restore_screen(struct vc_data *c) { @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); + vgacon_scrollback_switch(c->vc_num); return 0; /* Redrawing not needed */ } -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
[parent not found: <CGME20170110162224epcas1p2095912fa6b73a1457fa86396149e78e9@epcas1p2.samsung.com>]
* Re: [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles [not found] ` <CGME20170110162224epcas1p2095912fa6b73a1457fa86396149e78e9@epcas1p2.samsung.com> @ 2017-01-10 16:22 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20170110164435epcas1p314efb9c6ea3ffb971fce06f3bfaec736@epcas1p3.samsung.com> 0 siblings, 1 reply; 49+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2017-01-10 16:22 UTC (permalink / raw) To: Manuel Schölling Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev Hi, The patchset generally looks fine to me but I have a question regarding new VGACON_SOFT_SCROLLBACK_PERSISTENT config option. Since the code size impact to support the persistent scrollback feature is minimal wouldn't it be better to always include it? The feature would be disabled by default and could be enabled by using the new kernel command line parameter (you may also add a new config option for enabling it by default if desired). Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics On Thursday, January 05, 2017 12:33:20 PM Manuel Schölling wrote: > Add a scrollback buffers for each VGA console. The benefit is that > the scrollback history is not flushed when switching between consoles > but is persistent. > The buffers are allocated on demand when a new console is opened. > > This breaks tools like clear_console that rely on flushing the > scrollback history by switching back and forth between consoles > which is why this feature is disabled by default. > Use the escape sequence \e[3J instead for flushing the buffer. > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > Tested-by: Adam Borowski <kilobyte@angband.pl> > --- > drivers/video/console/Kconfig | 25 +++++++- > drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- > 2 files changed, 111 insertions(+), 56 deletions(-) > > diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig > index c3f1fb9ee820..f500e58f7636 100644 > --- a/drivers/video/console/Kconfig > +++ b/drivers/video/console/Kconfig > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE > range 1 1024 > default "64" > help > - Enter the amount of System RAM to allocate for the scrollback > - buffer. Each 64KB will give you approximately 16 80x25 > - screenfuls of scrollback buffer > + Enter the amount of System RAM to allocate for scrollback > + buffers of VGA consoles. Each 64KB will give you approximately > + 16 80x25 screenfuls of scrollback buffer. > + > +config VGACON_SOFT_SCROLLBACK_PERSISTENT > + bool "Persistent Scrollback History for each console" > + depends on VGACON_SOFT_SCROLLBACK > + default n > + help > + Say Y here if the scrollback history should persist when switching > + between consoles. Otherwise, the scrollback history will be flushed > + each time the console is switched. > + > + This feature might break your tool of choice to flush the scrollback > + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) > + will be broken, which might cause security issues. > + You can use the escape sequence \e[3J instead if this feature is > + activated. > + > + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each > + created tty device. > + So if you use a RAM-constrained system, say N here. > > config MDA_CONSOLE > depends on !M68K && !PARISC && ISA > diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c > index 9a7c2bbc5326..ca23d222e029 100644 > --- a/drivers/video/console/vgacon.c > +++ b/drivers/video/console/vgacon.c > @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) > > #ifdef CONFIG_VGACON_SOFT_SCROLLBACK > /* software scrollback */ > -static struct vgacon_scrollback_info { > +struct vgacon_scrollback_info { > void *data; > int tail; > int size; > @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { > int cur; > int save; > int restore; > -} vgacon_scrollback; > +}; > + > +static struct vgacon_scrollback_info *vgacon_scrollback_cur; > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; > +#else > +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; > +#endif > > -static void vgacon_scrollback_reset(size_t reset_size) > +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) > { > - if (vgacon_scrollback.data && reset_size > 0) > - memset(vgacon_scrollback.data, 0, reset_size); > + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; > + > + if (scrollback->data && reset_size > 0) > + memset(scrollback->data, 0, reset_size); > > - vgacon_scrollback.cnt = 0; > - vgacon_scrollback.tail = 0; > - vgacon_scrollback.cur = 0; > + scrollback->cnt = 0; > + scrollback->tail = 0; > + scrollback->cur = 0; > } > > -static void vgacon_scrollback_init(int pitch) > +static void vgacon_scrollback_init(int vc_num) > { > - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; > - > - if (vgacon_scrollback.data) { > - vgacon_scrollback.cnt = 0; > - vgacon_scrollback.tail = 0; > - vgacon_scrollback.cur = 0; > - vgacon_scrollback.rows = rows - 1; > - vgacon_scrollback.size = rows * pitch; > + int pitch = vga_video_num_columns * 2; > + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > + int rows = size / pitch; > + void *data; > + > + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, > + GFP_NOWAIT); > + > + vgacon_scrollbacks[vc_num].data = data; > + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; > + > + vgacon_scrollback_cur->rows = rows - 1; > + vgacon_scrollback_cur->size = rows * pitch; > + > + vgacon_scrollback_reset(vc_num, size); > +} > + > +static void vgacon_scrollback_switch(int vc_num) > +{ > +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > + vc_num = 0; > +#endif > + > + if (!vgacon_scrollbacks[vc_num].data) { > + vgacon_scrollback_init(vc_num); > + } else { > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; > +#else > + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > + > + vgacon_scrollback_reset(vc_num, size); > +#endif > } > } > > static void vgacon_scrollback_startup(void) > { > - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, > - 1024, GFP_NOWAIT); > - vgacon_scrollback_init(vga_video_num_columns * 2); > + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; > + vgacon_scrollback_init(0); > } > > static void vgacon_scrollback_update(struct vc_data *c, int t, int count) > { > void *p; > > - if (!vgacon_scrollback.size || c->vc_num != fg_console) > + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || > + c->vc_num != fg_console) > return; > > p = (void *) (c->vc_origin + t * c->vc_size_row); > > while (count--) { > - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, > + scr_memcpyw(vgacon_scrollback_cur->data + > + vgacon_scrollback_cur->tail, > p, c->vc_size_row); > - vgacon_scrollback.cnt++; > + > + vgacon_scrollback_cur->cnt++; > p += c->vc_size_row; > - vgacon_scrollback.tail += c->vc_size_row; > + vgacon_scrollback_cur->tail += c->vc_size_row; > > - if (vgacon_scrollback.tail >= vgacon_scrollback.size) > - vgacon_scrollback.tail = 0; > + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) > + vgacon_scrollback_cur->tail = 0; > > - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) > - vgacon_scrollback.cnt = vgacon_scrollback.rows; > + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) > + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; > > - vgacon_scrollback.cur = vgacon_scrollback.cnt; > + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; > } > } > > static void vgacon_restore_screen(struct vc_data *c) > { > - vgacon_scrollback.save = 0; > + vgacon_scrollback_cur->save = 0; > > - if (!vga_is_gfx && !vgacon_scrollback.restore) { > + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { > scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, > c->vc_screenbuf_size > vga_vram_size ? > vga_vram_size : c->vc_screenbuf_size); > - vgacon_scrollback.restore = 1; > - vgacon_scrollback.cur = vgacon_scrollback.cnt; > + vgacon_scrollback_cur->restore = 1; > + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; > } > } > > @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) > return; > } > > - if (!vgacon_scrollback.data) > + if (!vgacon_scrollback_cur->data) > return; > > - if (!vgacon_scrollback.save) { > + if (!vgacon_scrollback_cur->save) { > vgacon_cursor(c, CM_ERASE); > vgacon_save_screen(c); > - vgacon_scrollback.save = 1; > + vgacon_scrollback_cur->save = 1; > } > > - vgacon_scrollback.restore = 0; > - start = vgacon_scrollback.cur + lines; > + vgacon_scrollback_cur->restore = 0; > + start = vgacon_scrollback_cur->cur + lines; > end = start + abs(lines); > > if (start < 0) > start = 0; > > - if (start > vgacon_scrollback.cnt) > - start = vgacon_scrollback.cnt; > + if (start > vgacon_scrollback_cur->cnt) > + start = vgacon_scrollback_cur->cnt; > > if (end < 0) > end = 0; > > - if (end > vgacon_scrollback.cnt) > - end = vgacon_scrollback.cnt; > + if (end > vgacon_scrollback_cur->cnt) > + end = vgacon_scrollback_cur->cnt; > > - vgacon_scrollback.cur = start; > + vgacon_scrollback_cur->cur = start; > count = end - start; > - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * > - c->vc_size_row); > + soff = vgacon_scrollback_cur->tail - > + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); > soff -= count * c->vc_size_row; > > if (soff < 0) > - soff += vgacon_scrollback.size; > + soff += vgacon_scrollback_cur->size; > > - count = vgacon_scrollback.cnt - start; > + count = vgacon_scrollback_cur->cnt - start; > > if (count > c->vc_rows) > count = c->vc_rows; > @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) > > count *= c->vc_size_row; > /* how much memory to end of buffer left? */ > - copysize = min(count, vgacon_scrollback.size - soff); > - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); > + copysize = min(count, vgacon_scrollback_cur->size - soff); > + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); > d += copysize; > count -= copysize; > > if (count) { > - scr_memcpyw(d, vgacon_scrollback.data, count); > + scr_memcpyw(d, vgacon_scrollback_cur->data, count); > d += count; > } > > @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) > { > size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > > - if (c->vc_num == fg_console) > - vgacon_scrollback_reset(size); > + vgacon_scrollback_reset(c->vc_num, size); > } > #else > #define vgacon_scrollback_startup(...) do { } while (0) > #define vgacon_scrollback_init(...) do { } while (0) > #define vgacon_scrollback_update(...) do { } while (0) > +#define vgacon_scrollback_switch(...) do { } while (0) > > static void vgacon_restore_screen(struct vc_data *c) > { > @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) > vgacon_doresize(c, c->vc_cols, c->vc_rows); > } > > - vgacon_scrollback_init(c->vc_size_row); > + vgacon_scrollback_switch(c->vc_num); > return 0; /* Redrawing not needed */ > } ^ permalink raw reply [flat|nested] 49+ messages in thread
[parent not found: <CGME20170110164435epcas1p314efb9c6ea3ffb971fce06f3bfaec736@epcas1p3.samsung.com>]
* Re: [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles [not found] ` <CGME20170110164435epcas1p314efb9c6ea3ffb971fce06f3bfaec736@epcas1p3.samsung.com> @ 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz 2017-01-10 17:31 ` Manuel Schölling ` (5 more replies) 0 siblings, 6 replies; 49+ messages in thread From: Bartlomiej Zolnierkiewicz @ 2017-01-10 16:44 UTC (permalink / raw) To: Manuel Schölling Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Tuesday, January 10, 2017 05:22:22 PM Bartlomiej Zolnierkiewicz wrote: > > Hi, > > The patchset generally looks fine to me but I have a question > regarding new VGACON_SOFT_SCROLLBACK_PERSISTENT config option. > > Since the code size impact to support the persistent scrollback > feature is minimal wouldn't it be better to always include it? > > The feature would be disabled by default and could be enabled > by using the new kernel command line parameter (you may also add > a new config option for enabling it by default if desired). Something like: #ifdef VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT static bool scrollback_persistent = 1; #else static bool scrollback_persistent; #endif module_param_named(scrollback_persistent, scrollback_persistent, bool, 0); MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback feature"); and then use scrollback_persistent variable in vgacon_scrollback_switch() to control the actual behavior instead of ifdefs. Best regards, -- Bartlomiej Zolnierkiewicz Samsung R&D Institute Poland Samsung Electronics > Best regards, > -- > Bartlomiej Zolnierkiewicz > Samsung R&D Institute Poland > Samsung Electronics > > On Thursday, January 05, 2017 12:33:20 PM Manuel Schölling wrote: > > Add a scrollback buffers for each VGA console. The benefit is that > > the scrollback history is not flushed when switching between consoles > > but is persistent. > > The buffers are allocated on demand when a new console is opened. > > > > This breaks tools like clear_console that rely on flushing the > > scrollback history by switching back and forth between consoles > > which is why this feature is disabled by default. > > Use the escape sequence \e[3J instead for flushing the buffer. > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > > Tested-by: Adam Borowski <kilobyte@angband.pl> > > --- > > drivers/video/console/Kconfig | 25 +++++++- > > drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- > > 2 files changed, 111 insertions(+), 56 deletions(-) > > > > diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig > > index c3f1fb9ee820..f500e58f7636 100644 > > --- a/drivers/video/console/Kconfig > > +++ b/drivers/video/console/Kconfig > > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE > > range 1 1024 > > default "64" > > help > > - Enter the amount of System RAM to allocate for the scrollback > > - buffer. Each 64KB will give you approximately 16 80x25 > > - screenfuls of scrollback buffer > > + Enter the amount of System RAM to allocate for scrollback > > + buffers of VGA consoles. Each 64KB will give you approximately > > + 16 80x25 screenfuls of scrollback buffer. > > + > > +config VGACON_SOFT_SCROLLBACK_PERSISTENT > > + bool "Persistent Scrollback History for each console" > > + depends on VGACON_SOFT_SCROLLBACK > > + default n > > + help > > + Say Y here if the scrollback history should persist when switching > > + between consoles. Otherwise, the scrollback history will be flushed > > + each time the console is switched. > > + > > + This feature might break your tool of choice to flush the scrollback > > + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) > > + will be broken, which might cause security issues. > > + You can use the escape sequence \e[3J instead if this feature is > > + activated. > > + > > + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each > > + created tty device. > > + So if you use a RAM-constrained system, say N here. > > > > config MDA_CONSOLE > > depends on !M68K && !PARISC && ISA > > diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c > > index 9a7c2bbc5326..ca23d222e029 100644 > > --- a/drivers/video/console/vgacon.c > > +++ b/drivers/video/console/vgacon.c > > @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) > > > > #ifdef CONFIG_VGACON_SOFT_SCROLLBACK > > /* software scrollback */ > > -static struct vgacon_scrollback_info { > > +struct vgacon_scrollback_info { > > void *data; > > int tail; > > int size; > > @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { > > int cur; > > int save; > > int restore; > > -} vgacon_scrollback; > > +}; > > + > > +static struct vgacon_scrollback_info *vgacon_scrollback_cur; > > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > > +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; > > +#else > > +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; > > +#endif > > > > -static void vgacon_scrollback_reset(size_t reset_size) > > +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) > > { > > - if (vgacon_scrollback.data && reset_size > 0) > > - memset(vgacon_scrollback.data, 0, reset_size); > > + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; > > + > > + if (scrollback->data && reset_size > 0) > > + memset(scrollback->data, 0, reset_size); > > > > - vgacon_scrollback.cnt = 0; > > - vgacon_scrollback.tail = 0; > > - vgacon_scrollback.cur = 0; > > + scrollback->cnt = 0; > > + scrollback->tail = 0; > > + scrollback->cur = 0; > > } > > > > -static void vgacon_scrollback_init(int pitch) > > +static void vgacon_scrollback_init(int vc_num) > > { > > - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; > > - > > - if (vgacon_scrollback.data) { > > - vgacon_scrollback.cnt = 0; > > - vgacon_scrollback.tail = 0; > > - vgacon_scrollback.cur = 0; > > - vgacon_scrollback.rows = rows - 1; > > - vgacon_scrollback.size = rows * pitch; > > + int pitch = vga_video_num_columns * 2; > > + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > > + int rows = size / pitch; > > + void *data; > > + > > + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, > > + GFP_NOWAIT); > > + > > + vgacon_scrollbacks[vc_num].data = data; > > + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; > > + > > + vgacon_scrollback_cur->rows = rows - 1; > > + vgacon_scrollback_cur->size = rows * pitch; > > + > > + vgacon_scrollback_reset(vc_num, size); > > +} > > + > > +static void vgacon_scrollback_switch(int vc_num) > > +{ > > +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > > + vc_num = 0; > > +#endif > > + > > + if (!vgacon_scrollbacks[vc_num].data) { > > + vgacon_scrollback_init(vc_num); > > + } else { > > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > > + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; > > +#else > > + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > > + > > + vgacon_scrollback_reset(vc_num, size); > > +#endif > > } > > } > > > > static void vgacon_scrollback_startup(void) > > { > > - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, > > - 1024, GFP_NOWAIT); > > - vgacon_scrollback_init(vga_video_num_columns * 2); > > + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; > > + vgacon_scrollback_init(0); > > } > > > > static void vgacon_scrollback_update(struct vc_data *c, int t, int count) > > { > > void *p; > > > > - if (!vgacon_scrollback.size || c->vc_num != fg_console) > > + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || > > + c->vc_num != fg_console) > > return; > > > > p = (void *) (c->vc_origin + t * c->vc_size_row); > > > > while (count--) { > > - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, > > + scr_memcpyw(vgacon_scrollback_cur->data + > > + vgacon_scrollback_cur->tail, > > p, c->vc_size_row); > > - vgacon_scrollback.cnt++; > > + > > + vgacon_scrollback_cur->cnt++; > > p += c->vc_size_row; > > - vgacon_scrollback.tail += c->vc_size_row; > > + vgacon_scrollback_cur->tail += c->vc_size_row; > > > > - if (vgacon_scrollback.tail >= vgacon_scrollback.size) > > - vgacon_scrollback.tail = 0; > > + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) > > + vgacon_scrollback_cur->tail = 0; > > > > - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) > > - vgacon_scrollback.cnt = vgacon_scrollback.rows; > > + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) > > + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; > > > > - vgacon_scrollback.cur = vgacon_scrollback.cnt; > > + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; > > } > > } > > > > static void vgacon_restore_screen(struct vc_data *c) > > { > > - vgacon_scrollback.save = 0; > > + vgacon_scrollback_cur->save = 0; > > > > - if (!vga_is_gfx && !vgacon_scrollback.restore) { > > + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { > > scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, > > c->vc_screenbuf_size > vga_vram_size ? > > vga_vram_size : c->vc_screenbuf_size); > > - vgacon_scrollback.restore = 1; > > - vgacon_scrollback.cur = vgacon_scrollback.cnt; > > + vgacon_scrollback_cur->restore = 1; > > + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; > > } > > } > > > > @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) > > return; > > } > > > > - if (!vgacon_scrollback.data) > > + if (!vgacon_scrollback_cur->data) > > return; > > > > - if (!vgacon_scrollback.save) { > > + if (!vgacon_scrollback_cur->save) { > > vgacon_cursor(c, CM_ERASE); > > vgacon_save_screen(c); > > - vgacon_scrollback.save = 1; > > + vgacon_scrollback_cur->save = 1; > > } > > > > - vgacon_scrollback.restore = 0; > > - start = vgacon_scrollback.cur + lines; > > + vgacon_scrollback_cur->restore = 0; > > + start = vgacon_scrollback_cur->cur + lines; > > end = start + abs(lines); > > > > if (start < 0) > > start = 0; > > > > - if (start > vgacon_scrollback.cnt) > > - start = vgacon_scrollback.cnt; > > + if (start > vgacon_scrollback_cur->cnt) > > + start = vgacon_scrollback_cur->cnt; > > > > if (end < 0) > > end = 0; > > > > - if (end > vgacon_scrollback.cnt) > > - end = vgacon_scrollback.cnt; > > + if (end > vgacon_scrollback_cur->cnt) > > + end = vgacon_scrollback_cur->cnt; > > > > - vgacon_scrollback.cur = start; > > + vgacon_scrollback_cur->cur = start; > > count = end - start; > > - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * > > - c->vc_size_row); > > + soff = vgacon_scrollback_cur->tail - > > + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); > > soff -= count * c->vc_size_row; > > > > if (soff < 0) > > - soff += vgacon_scrollback.size; > > + soff += vgacon_scrollback_cur->size; > > > > - count = vgacon_scrollback.cnt - start; > > + count = vgacon_scrollback_cur->cnt - start; > > > > if (count > c->vc_rows) > > count = c->vc_rows; > > @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) > > > > count *= c->vc_size_row; > > /* how much memory to end of buffer left? */ > > - copysize = min(count, vgacon_scrollback.size - soff); > > - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); > > + copysize = min(count, vgacon_scrollback_cur->size - soff); > > + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); > > d += copysize; > > count -= copysize; > > > > if (count) { > > - scr_memcpyw(d, vgacon_scrollback.data, count); > > + scr_memcpyw(d, vgacon_scrollback_cur->data, count); > > d += count; > > } > > > > @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) > > { > > size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > > > > - if (c->vc_num == fg_console) > > - vgacon_scrollback_reset(size); > > + vgacon_scrollback_reset(c->vc_num, size); > > } > > #else > > #define vgacon_scrollback_startup(...) do { } while (0) > > #define vgacon_scrollback_init(...) do { } while (0) > > #define vgacon_scrollback_update(...) do { } while (0) > > +#define vgacon_scrollback_switch(...) do { } while (0) > > > > static void vgacon_restore_screen(struct vc_data *c) > > { > > @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) > > vgacon_doresize(c, c->vc_cols, c->vc_rows); > > } > > > > - vgacon_scrollback_init(c->vc_size_row); > > + vgacon_scrollback_switch(c->vc_num); > > return 0; /* Redrawing not needed */ > > } ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz @ 2017-01-10 17:31 ` Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 0/4] " Manuel Schölling ` (4 subsequent siblings) 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-10 17:31 UTC (permalink / raw) To: Bartlomiej Zolnierkiewicz Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev Hi Bartlomiej, First of all thank you for you feedback! On Tue, 2017-01-10 at 17:44 +0100, Bartlomiej Zolnierkiewicz wrote: > On Tuesday, January 10, 2017 05:22:22 PM Bartlomiej Zolnierkiewicz > wrote: > > > > Hi, > > > > The patchset generally looks fine to me but I have a question > > regarding new VGACON_SOFT_SCROLLBACK_PERSISTENT config option. > > > > Since the code size impact to support the persistent scrollback > > feature is minimal wouldn't it be better to always include it? > > > > The feature would be disabled by default and could be enabled > > by using the new kernel command line parameter (you may also add > > a new config option for enabling it by default if desired). > > Something like: > > #ifdef VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT > static bool scrollback_persistent = 1; > #else > static bool scrollback_persistent; > #endif > > module_param_named(scrollback_persistent, scrollback_persistent, > bool, 0); > MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback > feature"); > > and then use scrollback_persistent variable in > vgacon_scrollback_switch() > to control the actual behavior instead of ifdefs. Sounds pretty good to me. You are right: The code size impact is rather small. I will apply your suggestions and send you another patch as soon as I find the time to implement it (should be any time this week). Thanks again! Manuel > Best regards, > -- > Bartlomiej Zolnierkiewicz > Samsung R&D Institute Poland > Samsung Electronics > > > Best regards, > > -- > > Bartlomiej Zolnierkiewicz > > Samsung R&D Institute Poland > > Samsung Electronics > > > > On Thursday, January 05, 2017 12:33:20 PM Manuel Schölling wrote: > > > Add a scrollback buffers for each VGA console. The benefit is > > > that > > > the scrollback history is not flushed when switching between > > > consoles > > > but is persistent. > > > The buffers are allocated on demand when a new console is opened. > > > > > > This breaks tools like clear_console that rely on flushing the > > > scrollback history by switching back and forth between consoles > > > which is why this feature is disabled by default. > > > Use the escape sequence \e[3J instead for flushing the buffer. > > > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > > > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > > > Tested-by: Adam Borowski <kilobyte@angband.pl> > > > --- > > > drivers/video/console/Kconfig | 25 +++++++- > > > drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++- > > > -------------- > > > 2 files changed, 111 insertions(+), 56 deletions(-) > > > > > > diff --git a/drivers/video/console/Kconfig > > > b/drivers/video/console/Kconfig > > > index c3f1fb9ee820..f500e58f7636 100644 > > > --- a/drivers/video/console/Kconfig > > > +++ b/drivers/video/console/Kconfig > > > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE > > > range 1 1024 > > > default "64" > > > help > > > - Enter the amount of System RAM to allocate for the > > > scrollback > > > - buffer. Each 64KB will give you approximately 16 80x25 > > > - screenfuls of scrollback buffer > > > + Enter the amount of System RAM to allocate for > > > scrollback > > > + buffers of VGA consoles. Each 64KB will give you > > > approximately > > > + 16 80x25 screenfuls of scrollback buffer. > > > + > > > +config VGACON_SOFT_SCROLLBACK_PERSISTENT > > > + bool "Persistent Scrollback History for each console" > > > + depends on VGACON_SOFT_SCROLLBACK > > > + default n > > > + help > > > + Say Y here if the scrollback history should persist > > > when switching > > > + between consoles. Otherwise, the scrollback history > > > will be flushed > > > + each time the console is switched. > > > + > > > + This feature might break your tool of choice to flush > > > the scrollback > > > + buffer, e.g. clear(1) will work fine but Debian's > > > clear_console(1) > > > + will be broken, which might cause security issues. > > > + You can use the escape sequence \e[3J instead if this > > > feature is > > > + activated. > > > + > > > + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is > > > taken for each > > > + created tty device. > > > + So if you use a RAM-constrained system, say N here. > > > > > > config MDA_CONSOLE > > > depends on !M68K && !PARISC && ISA > > > diff --git a/drivers/video/console/vgacon.c > > > b/drivers/video/console/vgacon.c > > > index 9a7c2bbc5326..ca23d222e029 100644 > > > --- a/drivers/video/console/vgacon.c > > > +++ b/drivers/video/console/vgacon.c > > > @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct > > > vc_data *c) > > > > > > #ifdef CONFIG_VGACON_SOFT_SCROLLBACK > > > /* software scrollback */ > > > -static struct vgacon_scrollback_info { > > > +struct vgacon_scrollback_info { > > > void *data; > > > int tail; > > > int size; > > > @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { > > > int cur; > > > int save; > > > int restore; > > > -} vgacon_scrollback; > > > +}; > > > + > > > +static struct vgacon_scrollback_info *vgacon_scrollback_cur; > > > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > > > +static struct vgacon_scrollback_info > > > vgacon_scrollbacks[MAX_NR_CONSOLES]; > > > +#else > > > +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; > > > +#endif > > > > > > -static void vgacon_scrollback_reset(size_t reset_size) > > > +static void vgacon_scrollback_reset(int vc_num, size_t > > > reset_size) > > > { > > > - if (vgacon_scrollback.data && reset_size > 0) > > > - memset(vgacon_scrollback.data, 0, reset_size); > > > + struct vgacon_scrollback_info *scrollback = > > > &vgacon_scrollbacks[vc_num]; > > > + > > > + if (scrollback->data && reset_size > 0) > > > + memset(scrollback->data, 0, reset_size); > > > > > > - vgacon_scrollback.cnt = 0; > > > - vgacon_scrollback.tail = 0; > > > - vgacon_scrollback.cur = 0; > > > + scrollback->cnt = 0; > > > + scrollback->tail = 0; > > > + scrollback->cur = 0; > > > } > > > > > > -static void vgacon_scrollback_init(int pitch) > > > +static void vgacon_scrollback_init(int vc_num) > > > { > > > - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * > > > 1024/pitch; > > > - > > > - if (vgacon_scrollback.data) { > > > - vgacon_scrollback.cnt = 0; > > > - vgacon_scrollback.tail = 0; > > > - vgacon_scrollback.cur = 0; > > > - vgacon_scrollback.rows = rows - 1; > > > - vgacon_scrollback.size = rows * pitch; > > > + int pitch = vga_video_num_columns * 2; > > > + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > > > + int rows = size / pitch; > > > + void *data; > > > + > > > + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, > > > 1024, > > > + GFP_NOWAIT); > > > + > > > + vgacon_scrollbacks[vc_num].data = data; > > > + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; > > > + > > > + vgacon_scrollback_cur->rows = rows - 1; > > > + vgacon_scrollback_cur->size = rows * pitch; > > > + > > > + vgacon_scrollback_reset(vc_num, size); > > > +} > > > + > > > +static void vgacon_scrollback_switch(int vc_num) > > > +{ > > > +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > > > + vc_num = 0; > > > +#endif > > > + > > > + if (!vgacon_scrollbacks[vc_num].data) { > > > + vgacon_scrollback_init(vc_num); > > > + } else { > > > +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT > > > + vgacon_scrollback_cur = > > > &vgacon_scrollbacks[vc_num]; > > > +#else > > > + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE > > > * 1024; > > > + > > > + vgacon_scrollback_reset(vc_num, size); > > > +#endif > > > } > > > } > > > > > > static void vgacon_scrollback_startup(void) > > > { > > > - vgacon_scrollback.data = > > > kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, > > > - 1024, GFP_NOWAIT); > > > - vgacon_scrollback_init(vga_video_num_columns * 2); > > > + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; > > > + vgacon_scrollback_init(0); > > > } > > > > > > static void vgacon_scrollback_update(struct vc_data *c, int t, > > > int count) > > > { > > > void *p; > > > > > > - if (!vgacon_scrollback.size || c->vc_num != fg_console) > > > + if (!vgacon_scrollback_cur->data || > > > !vgacon_scrollback_cur->size || > > > + c->vc_num != fg_console) > > > return; > > > > > > p = (void *) (c->vc_origin + t * c->vc_size_row); > > > > > > while (count--) { > > > - scr_memcpyw(vgacon_scrollback.data + > > > vgacon_scrollback.tail, > > > + scr_memcpyw(vgacon_scrollback_cur->data + > > > + vgacon_scrollback_cur->tail, > > > p, c->vc_size_row); > > > - vgacon_scrollback.cnt++; > > > + > > > + vgacon_scrollback_cur->cnt++; > > > p += c->vc_size_row; > > > - vgacon_scrollback.tail += c->vc_size_row; > > > + vgacon_scrollback_cur->tail += c->vc_size_row; > > > > > > - if (vgacon_scrollback.tail >= > > > vgacon_scrollback.size) > > > - vgacon_scrollback.tail = 0; > > > + if (vgacon_scrollback_cur->tail >= > > > vgacon_scrollback_cur->size) > > > + vgacon_scrollback_cur->tail = 0; > > > > > > - if (vgacon_scrollback.cnt > > > > vgacon_scrollback.rows) > > > - vgacon_scrollback.cnt = > > > vgacon_scrollback.rows; > > > + if (vgacon_scrollback_cur->cnt > > > > vgacon_scrollback_cur->rows) > > > + vgacon_scrollback_cur->cnt = > > > vgacon_scrollback_cur->rows; > > > > > > - vgacon_scrollback.cur = vgacon_scrollback.cnt; > > > + vgacon_scrollback_cur->cur = > > > vgacon_scrollback_cur->cnt; > > > } > > > } > > > > > > static void vgacon_restore_screen(struct vc_data *c) > > > { > > > - vgacon_scrollback.save = 0; > > > + vgacon_scrollback_cur->save = 0; > > > > > > - if (!vga_is_gfx && !vgacon_scrollback.restore) { > > > + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { > > > scr_memcpyw((u16 *) c->vc_origin, (u16 *) c- > > > >vc_screenbuf, > > > c->vc_screenbuf_size > vga_vram_size > > > ? > > > vga_vram_size : c- > > > >vc_screenbuf_size); > > > - vgacon_scrollback.restore = 1; > > > - vgacon_scrollback.cur = vgacon_scrollback.cnt; > > > + vgacon_scrollback_cur->restore = 1; > > > + vgacon_scrollback_cur->cur = > > > vgacon_scrollback_cur->cnt; > > > } > > > } > > > > > > @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct > > > vc_data *c, int lines) > > > return; > > > } > > > > > > - if (!vgacon_scrollback.data) > > > + if (!vgacon_scrollback_cur->data) > > > return; > > > > > > - if (!vgacon_scrollback.save) { > > > + if (!vgacon_scrollback_cur->save) { > > > vgacon_cursor(c, CM_ERASE); > > > vgacon_save_screen(c); > > > - vgacon_scrollback.save = 1; > > > + vgacon_scrollback_cur->save = 1; > > > } > > > > > > - vgacon_scrollback.restore = 0; > > > - start = vgacon_scrollback.cur + lines; > > > + vgacon_scrollback_cur->restore = 0; > > > + start = vgacon_scrollback_cur->cur + lines; > > > end = start + abs(lines); > > > > > > if (start < 0) > > > start = 0; > > > > > > - if (start > vgacon_scrollback.cnt) > > > - start = vgacon_scrollback.cnt; > > > + if (start > vgacon_scrollback_cur->cnt) > > > + start = vgacon_scrollback_cur->cnt; > > > > > > if (end < 0) > > > end = 0; > > > > > > - if (end > vgacon_scrollback.cnt) > > > - end = vgacon_scrollback.cnt; > > > + if (end > vgacon_scrollback_cur->cnt) > > > + end = vgacon_scrollback_cur->cnt; > > > > > > - vgacon_scrollback.cur = start; > > > + vgacon_scrollback_cur->cur = start; > > > count = end - start; > > > - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt > > > - end) * > > > - c->vc_size_row); > > > + soff = vgacon_scrollback_cur->tail - > > > + ((vgacon_scrollback_cur->cnt - end) * c- > > > >vc_size_row); > > > soff -= count * c->vc_size_row; > > > > > > if (soff < 0) > > > - soff += vgacon_scrollback.size; > > > + soff += vgacon_scrollback_cur->size; > > > > > > - count = vgacon_scrollback.cnt - start; > > > + count = vgacon_scrollback_cur->cnt - start; > > > > > > if (count > c->vc_rows) > > > count = c->vc_rows; > > > @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct > > > vc_data *c, int lines) > > > > > > count *= c->vc_size_row; > > > /* how much memory to end of buffer left? */ > > > - copysize = min(count, vgacon_scrollback.size - > > > soff); > > > - scr_memcpyw(d, vgacon_scrollback.data + soff, > > > copysize); > > > + copysize = min(count, vgacon_scrollback_cur- > > > >size - soff); > > > + scr_memcpyw(d, vgacon_scrollback_cur->data + > > > soff, copysize); > > > d += copysize; > > > count -= copysize; > > > > > > if (count) { > > > - scr_memcpyw(d, vgacon_scrollback.data, > > > count); > > > + scr_memcpyw(d, vgacon_scrollback_cur- > > > >data, count); > > > d += count; > > > } > > > > > > @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct > > > vc_data *c) > > > { > > > size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; > > > > > > - if (c->vc_num == fg_console) > > > - vgacon_scrollback_reset(size); > > > + vgacon_scrollback_reset(c->vc_num, size); > > > } > > > #else > > > #define vgacon_scrollback_startup(...) do { } while (0) > > > #define vgacon_scrollback_init(...) do { } while (0) > > > #define vgacon_scrollback_update(...) do { } while (0) > > > +#define vgacon_scrollback_switch(...) do { } while (0) > > > > > > static void vgacon_restore_screen(struct vc_data *c) > > > { > > > @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) > > > vgacon_doresize(c, c->vc_cols, c- > > > >vc_rows); > > > } > > > > > > - vgacon_scrollback_init(c->vc_size_row); > > > + vgacon_scrollback_switch(c->vc_num); > > > return 0; /* Redrawing not needed */ > > > } > > ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v9 0/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz 2017-01-10 17:31 ` Manuel Schölling @ 2017-01-10 21:28 ` Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 1/4] console: Move scrollback data into its own struct Manuel Schölling ` (3 subsequent siblings) 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling -- Changes in v9: - Make persistent scrollback feature a boot parameter Changes in v8: - Add Reviewed-by/Tested-By statements Changes in v7: - Add new callback to consw struct for flushing video console driver's scrollback buffer. Fixes issues with escape sequence '\e[3J' reported by Adam Borowski (kilobyte@angband.pl). - Fix style issues Changes in v6: - Change of check if feature is enabled in vgacon_scrollback_switch() Changes in v5: - Clearify documentation - Skip superfluous array initialization - Disable scrollback if buffer allocation fails - Refactor vgacon_switch_scrollback() - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch() - Add check for fg_console in vgacon_scrollback_update Changes in v4.1: - Fix compiler error Changes in v4: - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to VGACON_SOFT_SCROLLBACK_PERSISTENT - Split into two patches - Rework documentation - Remove cosmetic changes in comments (postponed) Changes in v3: - Add config option for this feature - Fallback to old scrollback buffer if kcalloc() fails - Remove ioctl() call again and add documentation about existing escape sequence to flush the scrollback buffer Changes in v2: - Add ioctl() call to flush scrollback buffer - (Patch v2 was not labeled as such, sorry) Manuel Schölling (3): console: Move scrollback data into its own struct console: Add callback to flush scrollback buffer to consw struct console: Add persistent scrollback buffers for all VGA consoles drivers/tty/vt/vt.c | 9 +++ drivers/video/console/Kconfig | 25 ++++++- drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++------------- include/linux/console.h | 4 + 4 files changed, 148 insertions(+), 55 deletions(-) -- 2.11.0 ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v9 1/4] console: Move scrollback data into its own struct 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz 2017-01-10 17:31 ` Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 0/4] " Manuel Schölling @ 2017-01-10 21:28 ` Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling ` (2 subsequent siblings) 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a56232b7c..48b97648d4af 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; +static struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollback; static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; + if (vgacon_scrollback.data) { + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; + vgacon_scrollback.rows = rows - 1; + vgacon_scrollback.size = rows * pitch; } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, + 1024, GFP_NOWAIT); vgacon_scrollback_init(vga_video_num_columns * 2); } @@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + if (!vgacon_scrollback.size || c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + vgacon_scrollback.cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + vgacon_scrollback.tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (vgacon_scrollback.tail >= vgacon_scrollback.size) + vgacon_scrollback.tail = 0; - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; + if (vgacon_scrollback.cnt > vgacon_scrollback.rows) + vgacon_scrollback.cnt = vgacon_scrollback.rows; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback_save = 0; + vgacon_scrollback.save = 0; - if (!vga_is_gfx && !vgacon_scrollback_restore) { + if (!vga_is_gfx && !vgacon_scrollback.restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.restore = 1; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } @@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback) + if (!vgacon_scrollback.data) return; - if (!vgacon_scrollback_save) { + if (!vgacon_scrollback.save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback_save = 1; + vgacon_scrollback.save = 1; } - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; + vgacon_scrollback.restore = 0; + start = vgacon_scrollback.cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; + if (start > vgacon_scrollback.cnt) + start = vgacon_scrollback.cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; + if (end > vgacon_scrollback.cnt) + end = vgacon_scrollback.cnt; - vgacon_scrollback_cur = start; + vgacon_scrollback.cur = start; count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback_size; + soff += vgacon_scrollback.size; - count = vgacon_scrollback_cnt - start; + count = vgacon_scrollback.cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); + copysize = min(count, vgacon_scrollback.size - soff); + scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback, count); + scr_memcpyw(d, vgacon_scrollback.data, count); d += count; } -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz ` (2 preceding siblings ...) 2017-01-10 21:28 ` [PATCH v9 1/4] console: Move scrollback data into its own struct Manuel Schölling @ 2017-01-10 21:28 ` Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling This new callback is in preparation for persistent scrollback buffer support for VGA consoles. With a single scrollback buffer for all consoles, we could flush the buffer just by invocating consw->con_switch(). But when each VGA console has its own scrollback buffer, we need a new callback to tell the video console driver which buffer to flush. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/tty/vt/vt.c | 9 +++++++++ drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++- include/linux/console.h | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4c10a9df3b91..9d3ce505e7ab 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc) vc->vc_sw->con_save_screen(vc); } +static void flush_scrollback(struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + if (vc->vc_sw->con_flush_scrollback) + vc->vc_sw->con_flush_scrollback(vc); +} + /* * Redrawing of screen */ @@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar) case 3: /* erase scroll-back buffer (and whole display) */ scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, vc->vc_screenbuf_size); + flush_scrollback(vc); set_origin(vc); if (con_is_visible(vc)) update_screen(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 48b97648d4af..9a7c2bbc5326 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -173,6 +173,16 @@ static struct vgacon_scrollback_info { int restore; } vgacon_scrollback; +static void vgacon_scrollback_reset(size_t reset_size) +{ + if (vgacon_scrollback.data && reset_size > 0) + memset(vgacon_scrollback.data, 0, reset_size); + + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; +} + static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; @@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) } else vgacon_cursor(c, CM_MOVE); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + if (c->vc_num == fg_console) + vgacon_scrollback_reset(size); +} #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) @@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_vram_size); vga_set_mem_top(c); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ +} #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ static const char *vgacon_startup(void) @@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, return true; } - /* * The console `switch' structure for the VGA based console */ @@ -1362,6 +1383,7 @@ const struct consw vga_con = { .con_save_screen = vgacon_save_screen, .con_build_attr = vgacon_build_attr, .con_invert_region = vgacon_invert_region, + .con_flush_scrollback = vgacon_flush_scrollback, }; EXPORT_SYMBOL(vga_con); diff --git a/include/linux/console.h b/include/linux/console.h index 9c26c6685587..5949d1855589 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -73,6 +73,10 @@ struct consw { u16 *(*con_screen_pos)(struct vc_data *, int); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); /* + * Flush the video console driver's scrollback buffer + */ + void (*con_flush_scrollback)(struct vc_data *); + /* * Prepare the console for the debugger. This includes, but is not * limited to, unblanking the console, loading an appropriate * palette, and allowing debugger generated output. -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz ` (3 preceding siblings ...) 2017-01-10 21:28 ` [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling @ 2017-01-10 21:28 ` Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 5 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling Add a scrollback buffers for each VGA console. The benefit is that the scrollback history is not flushed when switching between consoles but is persistent. The buffers are allocated on demand when a new console is opened. This breaks tools like clear_console that rely on flushing the scrollback history by switching back and forth between consoles which is why this feature is disabled by default. Use the escape sequence \e[3J instead for flushing the buffer. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/Kconfig | 25 +++++++- drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index c3f1fb9ee820..f500e58f7636 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE range 1 1024 default "64" help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer + Enter the amount of System RAM to allocate for scrollback + buffers of VGA consoles. Each 64KB will give you approximately + 16 80x25 screenfuls of scrollback buffer. + +config VGACON_SOFT_SCROLLBACK_PERSISTENT + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if the scrollback history should persist when switching + between consoles. Otherwise, the scrollback history will be flushed + each time the console is switched. + + This feature might break your tool of choice to flush the scrollback + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) + will be broken, which might cause security issues. + You can use the escape sequence \e[3J instead if this feature is + activated. + + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each + created tty device. + So if you use a RAM-constrained system, say N here. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9a7c2bbc5326..ca23d222e029 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static struct vgacon_scrollback_info { +struct vgacon_scrollback_info { void *data; int tail; int size; @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { int cur; int save; int restore; -} vgacon_scrollback; +}; + +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; +#else +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; +#endif -static void vgacon_scrollback_reset(size_t reset_size) +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { - if (vgacon_scrollback.data && reset_size > 0) - memset(vgacon_scrollback.data, 0, reset_size); + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; + + if (scrollback->data && reset_size > 0) + memset(scrollback->data, 0, reset_size); - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; + scrollback->cnt = 0; + scrollback->tail = 0; + scrollback->cur = 0; } -static void vgacon_scrollback_init(int pitch) +static void vgacon_scrollback_init(int vc_num) { - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback.data) { - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; - vgacon_scrollback.rows = rows - 1; - vgacon_scrollback.size = rows * pitch; + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size / pitch; + void *data; + + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, + GFP_NOWAIT); + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + + vgacon_scrollback_cur->rows = rows - 1; + vgacon_scrollback_cur->size = rows * pitch; + + vgacon_scrollback_reset(vc_num, size); +} + +static void vgacon_scrollback_switch(int vc_num) +{ +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vc_num = 0; +#endif + + if (!vgacon_scrollbacks[vc_num].data) { + vgacon_scrollback_init(vc_num); + } else { +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + vgacon_scrollback_reset(vc_num, size); +#endif } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, - 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback.size || c->vc_num != fg_console) + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || + c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, + scr_memcpyw(vgacon_scrollback_cur->data + + vgacon_scrollback_cur->tail, p, c->vc_size_row); - vgacon_scrollback.cnt++; + + vgacon_scrollback_cur->cnt++; p += c->vc_size_row; - vgacon_scrollback.tail += c->vc_size_row; + vgacon_scrollback_cur->tail += c->vc_size_row; - if (vgacon_scrollback.tail >= vgacon_scrollback.size) - vgacon_scrollback.tail = 0; + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) + vgacon_scrollback_cur->tail = 0; - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) - vgacon_scrollback.cnt = vgacon_scrollback.rows; + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback.save = 0; + vgacon_scrollback_cur->save = 0; - if (!vga_is_gfx && !vgacon_scrollback.restore) { + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback.restore = 1; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->restore = 1; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback.data) + if (!vgacon_scrollback_cur->data) return; - if (!vgacon_scrollback.save) { + if (!vgacon_scrollback_cur->save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback.save = 1; + vgacon_scrollback_cur->save = 1; } - vgacon_scrollback.restore = 0; - start = vgacon_scrollback.cur + lines; + vgacon_scrollback_cur->restore = 0; + start = vgacon_scrollback_cur->cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback.cnt) - start = vgacon_scrollback.cnt; + if (start > vgacon_scrollback_cur->cnt) + start = vgacon_scrollback_cur->cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback.cnt) - end = vgacon_scrollback.cnt; + if (end > vgacon_scrollback_cur->cnt) + end = vgacon_scrollback_cur->cnt; - vgacon_scrollback.cur = start; + vgacon_scrollback_cur->cur = start; count = end - start; - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * - c->vc_size_row); + soff = vgacon_scrollback_cur->tail - + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback.size; + soff += vgacon_scrollback_cur->size; - count = vgacon_scrollback.cnt - start; + count = vgacon_scrollback_cur->cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback.size - soff); - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); + copysize = min(count, vgacon_scrollback_cur->size - soff); + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback.data, count); + scr_memcpyw(d, vgacon_scrollback_cur->data, count); d += count; } @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) { size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - if (c->vc_num == fg_console) - vgacon_scrollback_reset(size); + vgacon_scrollback_reset(c->vc_num, size); } #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) #define vgacon_scrollback_update(...) do { } while (0) +#define vgacon_scrollback_switch(...) do { } while (0) static void vgacon_restore_screen(struct vc_data *c) { @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); + vgacon_scrollback_switch(c->vc_num); return 0; /* Redrawing not needed */ } -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz ` (4 preceding siblings ...) 2017-01-10 21:28 ` [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2017-01-10 21:28 ` Manuel Schölling 2017-01-10 22:58 ` Adam Borowski ` (2 more replies) 5 siblings, 3 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-10 21:28 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling The impact of the persistent scrollback feature on the code size is rather small, so the config option is removed. The feature stays disabled by default and can be enabled by using the boot command line parameter 'vgacon.scrollback_persistent=1' or by setting VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/video/console/Kconfig | 12 +++++++----- drivers/video/console/vgacon.c | 25 ++++++++++++------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index f500e58f7636..5b71bd905a60 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -47,14 +47,16 @@ config VGACON_SOFT_SCROLLBACK_SIZE buffers of VGA consoles. Each 64KB will give you approximately 16 80x25 screenfuls of scrollback buffer. -config VGACON_SOFT_SCROLLBACK_PERSISTENT - bool "Persistent Scrollback History for each console" +config VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT + bool "Persistent Scrollback History for each console by default" depends on VGACON_SOFT_SCROLLBACK default n help - Say Y here if the scrollback history should persist when switching - between consoles. Otherwise, the scrollback history will be flushed - each time the console is switched. + Say Y here if the scrollback history should persist by default when + switching between consoles. Otherwise, the scrollback history will be + flushed each time the console is switched. This feature can also be + enabled using the boot command line parameter + 'vgacon.scrollback_persistent=1'. This feature might break your tool of choice to flush the scrollback buffer, e.g. clear(1) will work fine but Debian's clear_console(1) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index ca23d222e029..45a76972495b 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -174,11 +174,9 @@ struct vgacon_scrollback_info { }; static struct vgacon_scrollback_info *vgacon_scrollback_cur; -#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; -#else -static struct vgacon_scrollback_info vgacon_scrollbacks[1]; -#endif +static bool scrollback_persistent = \ + IS_ENABLED(CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT); static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { @@ -213,20 +211,19 @@ static void vgacon_scrollback_init(int vc_num) static void vgacon_scrollback_switch(int vc_num) { -#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT - vc_num = 0; -#endif + if (!scrollback_persistent) + vc_num = 0; if (!vgacon_scrollbacks[vc_num].data) { vgacon_scrollback_init(vc_num); } else { -#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT - vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; -#else - size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + if (scrollback_persistent) { + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + } else { + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - vgacon_scrollback_reset(vc_num, size); -#endif + vgacon_scrollback_reset(vc_num, size); + } } } @@ -1423,4 +1420,6 @@ const struct consw vga_con = { }; EXPORT_SYMBOL(vga_con); +module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles"); MODULE_LICENSE("GPL"); -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-01-10 21:28 ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling @ 2017-01-10 22:58 ` Adam Borowski 2017-01-11 21:41 ` Manuel Schölling 2017-01-13 20:00 ` Manuel Schölling 2017-01-11 13:32 ` kbuild test robot 2017-02-02 20:07 ` [PATCH v9 " Paul Gortmaker 2 siblings, 2 replies; 49+ messages in thread From: Adam Borowski @ 2017-01-10 22:58 UTC (permalink / raw) To: Manuel Schölling Cc: gregkh, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote: > The impact of the persistent scrollback feature on the code size is > rather small, so the config option is removed. The feature stays > disabled by default and can be enabled by using the boot command line > parameter 'vgacon.scrollback_persistent=1' or by setting > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > +module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles"); A command-line knob settable by the end-user is something more persistent than a config option. As you're going to extend this code beyond vgacon in the near future, perhaps it'd be better to have a shared setting for all console drivers? Meow! -- Autotools hint: to do a zx-spectrum build on a pdp11 host, type: ./configure --host=zx-spectrum --build=pdp11 ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-01-10 22:58 ` Adam Borowski @ 2017-01-11 21:41 ` Manuel Schölling 2017-01-13 20:00 ` Manuel Schölling 1 sibling, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-11 21:41 UTC (permalink / raw) To: Adam Borowski Cc: gregkh, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Tue, 2017-01-10 at 23:58 +0100, Adam Borowski wrote: > On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote: > > The impact of the persistent scrollback feature on the code size is > > rather small, so the config option is removed. The feature stays > > disabled by default and can be enabled by using the boot command > > line > > parameter 'vgacon.scrollback_persistent=1' or by setting > > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > > +module_param_named(scrollback_persistent, scrollback_persistent, > > bool, 0000); > > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent > > scrollback for all vga consoles"); > > A command-line knob settable by the end-user is something more > persistent > than a config option. As you're going to extend this code beyond > vgacon in > the near future, perhaps it'd be better to have a shared setting for > all > console drivers? Probably a good idea, but I'm struggling with the implementation a bit: I tried to run if (strstr(boot_command_line, "nopersistentscrollback")) {...} in vgacon_scrollback_startup() but I am getting WARNING: modpost: Found 2 section mismatch(es). when compiling. Probably because vgacon_scrollback_startup() is executed after init. I tried to find another way to implement a boot cmd line parameter but had no luck. If you/somebody could point me in the right direction, it would be very much appreciated. Thanks! Manuel ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-01-10 22:58 ` Adam Borowski 2017-01-11 21:41 ` Manuel Schölling @ 2017-01-13 20:00 ` Manuel Schölling 2017-01-14 7:26 ` Greg KH 1 sibling, 1 reply; 49+ messages in thread From: Manuel Schölling @ 2017-01-13 20:00 UTC (permalink / raw) To: Adam Borowski Cc: gregkh, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Tue, 2017-01-10 at 23:58 +0100, Adam Borowski wrote: > On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote: > > The impact of the persistent scrollback feature on the code size is > > rather small, so the config option is removed. The feature stays > > disabled by default and can be enabled by using the boot command > > line > > parameter 'vgacon.scrollback_persistent=1' or by setting > > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > > +module_param_named(scrollback_persistent, scrollback_persistent, > > bool, 0000); > > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent > > scrollback for all vga consoles"); > > A command-line knob settable by the end-user is something more > persistent > than a config option. As you're going to extend this code beyond > vgacon in > the near future, perhaps it'd be better to have a shared setting for > all > console drivers? According to the guys at #kernelnewbies on IRC everybody hates new command line options. I'd rather stick to the module parameter for now and maybe introduce a new cmd line option later, once this feature has been implemented in several console drivers. Bye, Manuel ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-01-13 20:00 ` Manuel Schölling @ 2017-01-14 7:26 ` Greg KH 0 siblings, 0 replies; 49+ messages in thread From: Greg KH @ 2017-01-14 7:26 UTC (permalink / raw) To: Manuel Schölling Cc: Adam Borowski, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Fri, Jan 13, 2017 at 09:00:34PM +0100, Manuel Schölling wrote: > On Tue, 2017-01-10 at 23:58 +0100, Adam Borowski wrote: > > On Tue, Jan 10, 2017 at 10:28:38PM +0100, Manuel Schölling wrote: > > > The impact of the persistent scrollback feature on the code size is > > > rather small, so the config option is removed. The feature stays > > > disabled by default and can be enabled by using the boot command > > > line > > > parameter 'vgacon.scrollback_persistent=1' or by setting > > > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. > > > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > > > +module_param_named(scrollback_persistent, scrollback_persistent, > > > bool, 0000); > > > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent > > > scrollback for all vga consoles"); > > > > A command-line knob settable by the end-user is something more > > persistent > > than a config option. As you're going to extend this code beyond > > vgacon in > > the near future, perhaps it'd be better to have a shared setting for > > all > > console drivers? > According to the guys at #kernelnewbies on IRC everybody hates new > command line options. That was me, you can use my name here :) > I'd rather stick to the module parameter for now and maybe introduce a > new cmd line option later, once this feature has been implemented in > several console drivers. Yes, that should be fine. thanks, greg k-h ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-01-10 21:28 ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 2017-01-10 22:58 ` Adam Borowski @ 2017-01-11 13:32 ` kbuild test robot 2017-01-13 20:07 ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling ` (4 more replies) 2017-02-02 20:07 ` [PATCH v9 " Paul Gortmaker 2 siblings, 5 replies; 49+ messages in thread From: kbuild test robot @ 2017-01-11 13:32 UTC (permalink / raw) To: Manuel Schölling Cc: kbuild-all, gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling [-- Attachment #1: Type: text/plain, Size: 3974 bytes --] Hi Manuel, [auto build test ERROR on linus/master] [also build test ERROR on v4.10-rc3 next-20170111] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Manuel-Sch-lling/console-Add-persistent-scrollback-buffers-for-all-VGA-consoles/20170111-203640 config: i386-randconfig-x018-201702 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): In file included from include/linux/module.h:18:0, from drivers/video/console/vgacon.c:36: drivers/video/console/vgacon.c: In function '__check_scrollback_persistent': >> drivers/video/console/vgacon.c:1423:43: error: 'scrollback_persistent' undeclared (first use in this function) module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); ^ include/linux/moduleparam.h:344:68: note: in definition of macro '__param_check' static inline type __always_unused *__check_##name(void) { return(p); } ^ include/linux/moduleparam.h:146:2: note: in expansion of macro 'param_check_bool' param_check_##type(name, &(value)); \ ^~~~~~~~~~~~ >> drivers/video/console/vgacon.c:1423:1: note: in expansion of macro 'module_param_named' module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); ^~~~~~~~~~~~~~~~~~ drivers/video/console/vgacon.c:1423:43: note: each undeclared identifier is reported only once for each function it appears in module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); ^ include/linux/moduleparam.h:344:68: note: in definition of macro '__param_check' static inline type __always_unused *__check_##name(void) { return(p); } ^ include/linux/moduleparam.h:146:2: note: in expansion of macro 'param_check_bool' param_check_##type(name, &(value)); \ ^~~~~~~~~~~~ >> drivers/video/console/vgacon.c:1423:1: note: in expansion of macro 'module_param_named' module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); ^~~~~~~~~~~~~~~~~~ drivers/video/console/vgacon.c: At top level: >> drivers/video/console/vgacon.c:1423:43: error: 'scrollback_persistent' undeclared here (not in a function) module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); ^ include/linux/moduleparam.h:225:54: note: in definition of macro '__module_param_call' VERIFY_OCTAL_PERMISSIONS(perm), level, flags, { arg } } ^~~ include/linux/moduleparam.h:147:2: note: in expansion of macro 'module_param_cb' module_param_cb(name, ¶m_ops_##type, &value, perm); \ ^~~~~~~~~~~~~~~ >> drivers/video/console/vgacon.c:1423:1: note: in expansion of macro 'module_param_named' module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); ^~~~~~~~~~~~~~~~~~ vim +/scrollback_persistent +1423 drivers/video/console/vgacon.c 1417 .con_build_attr = vgacon_build_attr, 1418 .con_invert_region = vgacon_invert_region, 1419 .con_flush_scrollback = vgacon_flush_scrollback, 1420 }; 1421 EXPORT_SYMBOL(vga_con); 1422 > 1423 module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); 1424 MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles"); 1425 MODULE_LICENSE("GPL"); --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 27586 bytes --] ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-11 13:32 ` kbuild test robot @ 2017-01-13 20:07 ` Manuel Schölling 2017-01-25 10:55 ` Greg KH 2017-01-13 20:07 ` [PATCH v10 1/4] console: Move scrollback data into its own struct Manuel Schölling ` (3 subsequent siblings) 4 siblings, 1 reply; 49+ messages in thread From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling Changes in v10: - Fix compilation error if CONFIG_VGACON_SOFT_SCROLLBACK=n Changes in v9: - Make persistent scrollback feature a boot parameter Changes in v8: - Add Reviewed-by/Tested-By statements Changes in v7: - Add new callback to consw struct for flushing video console driver's scrollback buffer. Fixes issues with escape sequence '\e[3J' reported by Adam Borowski (kilobyte@angband.pl). - Fix style issues Changes in v6: - Change of check if feature is enabled in vgacon_scrollback_switch() Changes in v5: - Clearify documentation - Skip superfluous array initialization - Disable scrollback if buffer allocation fails - Refactor vgacon_switch_scrollback() - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch() - Add check for fg_console in vgacon_scrollback_update Changes in v4.1: - Fix compiler error Changes in v4: - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to VGACON_SOFT_SCROLLBACK_PERSISTENT - Split into two patches - Rework documentation - Remove cosmetic changes in comments (postponed) Changes in v3: - Add config option for this feature - Fallback to old scrollback buffer if kcalloc() fails - Remove ioctl() call again and add documentation about existing escape sequence to flush the scrollback buffer Changes in v2: - Add ioctl() call to flush scrollback buffer - (Patch v2 was not labeled as such, sorry) Manuel Schölling (4): console: Move scrollback data into its own struct console: Add callback to flush scrollback buffer to consw struct console: Add persistent scrollback buffers for all VGA consoles console: Make persistent scrollback a boot parameter drivers/tty/vt/vt.c | 9 +++ drivers/video/console/Kconfig | 27 ++++++- drivers/video/console/vgacon.c | 164 ++++++++++++++++++++++++++++------------- include/linux/console.h | 4 + 4 files changed, 149 insertions(+), 55 deletions(-) -- 2.11.0 ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-13 20:07 ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2017-01-25 10:55 ` Greg KH 0 siblings, 0 replies; 49+ messages in thread From: Greg KH @ 2017-01-25 10:55 UTC (permalink / raw) To: Manuel Schölling Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Fri, Jan 13, 2017 at 09:07:54PM +0100, Manuel Schölling wrote: > Changes in v10: > - Fix compilation error if CONFIG_VGACON_SOFT_SCROLLBACK=n All now applied to my tty-testing branch, let's see what the 0-day bot has to say about this :) thanks for the persistence. greg k-h ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v10 1/4] console: Move scrollback data into its own struct 2017-01-11 13:32 ` kbuild test robot 2017-01-13 20:07 ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2017-01-13 20:07 ` Manuel Schölling 2017-01-13 20:07 ` [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling ` (2 subsequent siblings) 4 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a56232b7c..48b97648d4af 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; +static struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollback; static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; + if (vgacon_scrollback.data) { + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; + vgacon_scrollback.rows = rows - 1; + vgacon_scrollback.size = rows * pitch; } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, + 1024, GFP_NOWAIT); vgacon_scrollback_init(vga_video_num_columns * 2); } @@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + if (!vgacon_scrollback.size || c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + vgacon_scrollback.cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + vgacon_scrollback.tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (vgacon_scrollback.tail >= vgacon_scrollback.size) + vgacon_scrollback.tail = 0; - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; + if (vgacon_scrollback.cnt > vgacon_scrollback.rows) + vgacon_scrollback.cnt = vgacon_scrollback.rows; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback_save = 0; + vgacon_scrollback.save = 0; - if (!vga_is_gfx && !vgacon_scrollback_restore) { + if (!vga_is_gfx && !vgacon_scrollback.restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.restore = 1; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } @@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback) + if (!vgacon_scrollback.data) return; - if (!vgacon_scrollback_save) { + if (!vgacon_scrollback.save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback_save = 1; + vgacon_scrollback.save = 1; } - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; + vgacon_scrollback.restore = 0; + start = vgacon_scrollback.cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; + if (start > vgacon_scrollback.cnt) + start = vgacon_scrollback.cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; + if (end > vgacon_scrollback.cnt) + end = vgacon_scrollback.cnt; - vgacon_scrollback_cur = start; + vgacon_scrollback.cur = start; count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback_size; + soff += vgacon_scrollback.size; - count = vgacon_scrollback_cnt - start; + count = vgacon_scrollback.cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); + copysize = min(count, vgacon_scrollback.size - soff); + scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback, count); + scr_memcpyw(d, vgacon_scrollback.data, count); d += count; } -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct 2017-01-11 13:32 ` kbuild test robot 2017-01-13 20:07 ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-13 20:07 ` [PATCH v10 1/4] console: Move scrollback data into its own struct Manuel Schölling @ 2017-01-13 20:07 ` Manuel Schölling 2017-01-13 20:07 ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-13 20:07 ` [PATCH v10 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 4 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling This new callback is in preparation for persistent scrollback buffer support for VGA consoles. With a single scrollback buffer for all consoles, we could flush the buffer just by invocating consw->con_switch(). But when each VGA console has its own scrollback buffer, we need a new callback to tell the video console driver which buffer to flush. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/tty/vt/vt.c | 9 +++++++++ drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++- include/linux/console.h | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4c10a9df3b91..9d3ce505e7ab 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc) vc->vc_sw->con_save_screen(vc); } +static void flush_scrollback(struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + if (vc->vc_sw->con_flush_scrollback) + vc->vc_sw->con_flush_scrollback(vc); +} + /* * Redrawing of screen */ @@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar) case 3: /* erase scroll-back buffer (and whole display) */ scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, vc->vc_screenbuf_size); + flush_scrollback(vc); set_origin(vc); if (con_is_visible(vc)) update_screen(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 48b97648d4af..9a7c2bbc5326 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -173,6 +173,16 @@ static struct vgacon_scrollback_info { int restore; } vgacon_scrollback; +static void vgacon_scrollback_reset(size_t reset_size) +{ + if (vgacon_scrollback.data && reset_size > 0) + memset(vgacon_scrollback.data, 0, reset_size); + + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; +} + static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; @@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) } else vgacon_cursor(c, CM_MOVE); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + if (c->vc_num == fg_console) + vgacon_scrollback_reset(size); +} #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) @@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_vram_size); vga_set_mem_top(c); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ +} #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ static const char *vgacon_startup(void) @@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, return true; } - /* * The console `switch' structure for the VGA based console */ @@ -1362,6 +1383,7 @@ const struct consw vga_con = { .con_save_screen = vgacon_save_screen, .con_build_attr = vgacon_build_attr, .con_invert_region = vgacon_invert_region, + .con_flush_scrollback = vgacon_flush_scrollback, }; EXPORT_SYMBOL(vga_con); diff --git a/include/linux/console.h b/include/linux/console.h index 9c26c6685587..5949d1855589 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -73,6 +73,10 @@ struct consw { u16 *(*con_screen_pos)(struct vc_data *, int); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); /* + * Flush the video console driver's scrollback buffer + */ + void (*con_flush_scrollback)(struct vc_data *); + /* * Prepare the console for the debugger. This includes, but is not * limited to, unblanking the console, loading an appropriate * palette, and allowing debugger generated output. -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-11 13:32 ` kbuild test robot ` (2 preceding siblings ...) 2017-01-13 20:07 ` [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling @ 2017-01-13 20:07 ` Manuel Schölling 2017-01-19 13:23 ` Greg KH 2017-01-13 20:07 ` [PATCH v10 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 4 siblings, 1 reply; 49+ messages in thread From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling Add a scrollback buffers for each VGA console. The benefit is that the scrollback history is not flushed when switching between consoles but is persistent. The buffers are allocated on demand when a new console is opened. This breaks tools like clear_console that rely on flushing the scrollback history by switching back and forth between consoles which is why this feature is disabled by default. Use the escape sequence \e[3J instead for flushing the buffer. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/Kconfig | 25 +++++++- drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index c3f1fb9ee820..f500e58f7636 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE range 1 1024 default "64" help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer + Enter the amount of System RAM to allocate for scrollback + buffers of VGA consoles. Each 64KB will give you approximately + 16 80x25 screenfuls of scrollback buffer. + +config VGACON_SOFT_SCROLLBACK_PERSISTENT + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if the scrollback history should persist when switching + between consoles. Otherwise, the scrollback history will be flushed + each time the console is switched. + + This feature might break your tool of choice to flush the scrollback + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) + will be broken, which might cause security issues. + You can use the escape sequence \e[3J instead if this feature is + activated. + + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each + created tty device. + So if you use a RAM-constrained system, say N here. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9a7c2bbc5326..ca23d222e029 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static struct vgacon_scrollback_info { +struct vgacon_scrollback_info { void *data; int tail; int size; @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { int cur; int save; int restore; -} vgacon_scrollback; +}; + +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; +#else +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; +#endif -static void vgacon_scrollback_reset(size_t reset_size) +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { - if (vgacon_scrollback.data && reset_size > 0) - memset(vgacon_scrollback.data, 0, reset_size); + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; + + if (scrollback->data && reset_size > 0) + memset(scrollback->data, 0, reset_size); - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; + scrollback->cnt = 0; + scrollback->tail = 0; + scrollback->cur = 0; } -static void vgacon_scrollback_init(int pitch) +static void vgacon_scrollback_init(int vc_num) { - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback.data) { - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; - vgacon_scrollback.rows = rows - 1; - vgacon_scrollback.size = rows * pitch; + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size / pitch; + void *data; + + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, + GFP_NOWAIT); + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + + vgacon_scrollback_cur->rows = rows - 1; + vgacon_scrollback_cur->size = rows * pitch; + + vgacon_scrollback_reset(vc_num, size); +} + +static void vgacon_scrollback_switch(int vc_num) +{ +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vc_num = 0; +#endif + + if (!vgacon_scrollbacks[vc_num].data) { + vgacon_scrollback_init(vc_num); + } else { +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + vgacon_scrollback_reset(vc_num, size); +#endif } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, - 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback.size || c->vc_num != fg_console) + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || + c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, + scr_memcpyw(vgacon_scrollback_cur->data + + vgacon_scrollback_cur->tail, p, c->vc_size_row); - vgacon_scrollback.cnt++; + + vgacon_scrollback_cur->cnt++; p += c->vc_size_row; - vgacon_scrollback.tail += c->vc_size_row; + vgacon_scrollback_cur->tail += c->vc_size_row; - if (vgacon_scrollback.tail >= vgacon_scrollback.size) - vgacon_scrollback.tail = 0; + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) + vgacon_scrollback_cur->tail = 0; - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) - vgacon_scrollback.cnt = vgacon_scrollback.rows; + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback.save = 0; + vgacon_scrollback_cur->save = 0; - if (!vga_is_gfx && !vgacon_scrollback.restore) { + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback.restore = 1; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->restore = 1; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback.data) + if (!vgacon_scrollback_cur->data) return; - if (!vgacon_scrollback.save) { + if (!vgacon_scrollback_cur->save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback.save = 1; + vgacon_scrollback_cur->save = 1; } - vgacon_scrollback.restore = 0; - start = vgacon_scrollback.cur + lines; + vgacon_scrollback_cur->restore = 0; + start = vgacon_scrollback_cur->cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback.cnt) - start = vgacon_scrollback.cnt; + if (start > vgacon_scrollback_cur->cnt) + start = vgacon_scrollback_cur->cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback.cnt) - end = vgacon_scrollback.cnt; + if (end > vgacon_scrollback_cur->cnt) + end = vgacon_scrollback_cur->cnt; - vgacon_scrollback.cur = start; + vgacon_scrollback_cur->cur = start; count = end - start; - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * - c->vc_size_row); + soff = vgacon_scrollback_cur->tail - + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback.size; + soff += vgacon_scrollback_cur->size; - count = vgacon_scrollback.cnt - start; + count = vgacon_scrollback_cur->cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback.size - soff); - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); + copysize = min(count, vgacon_scrollback_cur->size - soff); + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback.data, count); + scr_memcpyw(d, vgacon_scrollback_cur->data, count); d += count; } @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) { size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - if (c->vc_num == fg_console) - vgacon_scrollback_reset(size); + vgacon_scrollback_reset(c->vc_num, size); } #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) #define vgacon_scrollback_update(...) do { } while (0) +#define vgacon_scrollback_switch(...) do { } while (0) static void vgacon_restore_screen(struct vc_data *c) { @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); + vgacon_scrollback_switch(c->vc_num); return 0; /* Redrawing not needed */ } -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-13 20:07 ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2017-01-19 13:23 ` Greg KH 2017-01-19 16:12 ` Manuel Schölling 0 siblings, 1 reply; 49+ messages in thread From: Greg KH @ 2017-01-19 13:23 UTC (permalink / raw) To: Manuel Schölling Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote: > Add a scrollback buffers for each VGA console. The benefit is that > the scrollback history is not flushed when switching between consoles > but is persistent. > The buffers are allocated on demand when a new console is opened. > > This breaks tools like clear_console that rely on flushing the > scrollback history by switching back and forth between consoles > which is why this feature is disabled by default. > Use the escape sequence \e[3J instead for flushing the buffer. > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > Tested-by: Adam Borowski <kilobyte@angband.pl> > --- > drivers/video/console/Kconfig | 25 +++++++- > drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- > 2 files changed, 111 insertions(+), 56 deletions(-) > > diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig > index c3f1fb9ee820..f500e58f7636 100644 > --- a/drivers/video/console/Kconfig > +++ b/drivers/video/console/Kconfig > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE > range 1 1024 > default "64" > help > - Enter the amount of System RAM to allocate for the scrollback > - buffer. Each 64KB will give you approximately 16 80x25 > - screenfuls of scrollback buffer > + Enter the amount of System RAM to allocate for scrollback > + buffers of VGA consoles. Each 64KB will give you approximately > + 16 80x25 screenfuls of scrollback buffer. > + > +config VGACON_SOFT_SCROLLBACK_PERSISTENT > + bool "Persistent Scrollback History for each console" > + depends on VGACON_SOFT_SCROLLBACK > + default n > + help > + Say Y here if the scrollback history should persist when switching > + between consoles. Otherwise, the scrollback history will be flushed > + each time the console is switched. > + > + This feature might break your tool of choice to flush the scrollback > + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) > + will be broken, which might cause security issues. > + You can use the escape sequence \e[3J instead if this feature is > + activated. This issue is the one that makes me the most worried. Why doesn't clear_console() work anymore? Why doesn't it use \e[3J ? thanks, greg k-h ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-19 13:23 ` Greg KH @ 2017-01-19 16:12 ` Manuel Schölling 2017-01-19 16:33 ` Greg KH 2017-01-19 17:20 ` Adam Borowski 0 siblings, 2 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-19 16:12 UTC (permalink / raw) To: Greg KH Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote: > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote: > > Add a scrollback buffers for each VGA console. The benefit is that > > the scrollback history is not flushed when switching between > > consoles > > but is persistent. > > The buffers are allocated on demand when a new console is opened. > > > > This breaks tools like clear_console that rely on flushing the > > scrollback history by switching back and forth between consoles > > which is why this feature is disabled by default. > > Use the escape sequence \e[3J instead for flushing the buffer. > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > > Tested-by: Adam Borowski <kilobyte@angband.pl> > > --- > > drivers/video/console/Kconfig | 25 +++++++- > > drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--- > > ------------ > > 2 files changed, 111 insertions(+), 56 deletions(-) > > > > diff --git a/drivers/video/console/Kconfig > > b/drivers/video/console/Kconfig > > index c3f1fb9ee820..f500e58f7636 100644 > > --- a/drivers/video/console/Kconfig > > +++ b/drivers/video/console/Kconfig > > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE > > range 1 1024 > > default "64" > > help > > - Enter the amount of System RAM to allocate for the > > scrollback > > - buffer. Each 64KB will give you approximately 16 80x25 > > - screenfuls of scrollback buffer > > + Enter the amount of System RAM to allocate for > > scrollback > > + buffers of VGA consoles. Each 64KB will give you > > approximately > > + 16 80x25 screenfuls of scrollback buffer. > > + > > +config VGACON_SOFT_SCROLLBACK_PERSISTENT > > + bool "Persistent Scrollback History for each console" > > + depends on VGACON_SOFT_SCROLLBACK > > + default n > > + help > > + Say Y here if the scrollback history should persist when > > switching > > + between consoles. Otherwise, the scrollback history will > > be flushed > > + each time the console is switched. > > + > > + This feature might break your tool of choice to flush > > the scrollback > > + buffer, e.g. clear(1) will work fine but Debian's > > clear_console(1) > > + will be broken, which might cause security issues. > > + You can use the escape sequence \e[3J instead if this > > feature is > > + activated. > > This issue is the one that makes me the most worried. Why doesn't > clear_console() work anymore? Why doesn't it use \e[3J ? Well, clear_console() just switches from one console to another and back again. It just assumes that the scrollback buffer is flushed when switching. My plan is to make a patch for clear_console() as soon as these patches are in the kernel - it's chicken-and-egg problem. Bye, Manuel ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-19 16:12 ` Manuel Schölling @ 2017-01-19 16:33 ` Greg KH 2017-01-19 23:04 ` Adam Borowski 2017-01-19 17:20 ` Adam Borowski 1 sibling, 1 reply; 49+ messages in thread From: Greg KH @ 2017-01-19 16:33 UTC (permalink / raw) To: Manuel Schölling Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote: > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote: > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote: > > > Add a scrollback buffers for each VGA console. The benefit is that > > > the scrollback history is not flushed when switching between > > > consoles > > > but is persistent. > > > The buffers are allocated on demand when a new console is opened. > > > > > > This breaks tools like clear_console that rely on flushing the > > > scrollback history by switching back and forth between consoles > > > which is why this feature is disabled by default. > > > Use the escape sequence \e[3J instead for flushing the buffer. > > > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > > Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> > > > Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> > > > Tested-by: Adam Borowski <kilobyte@angband.pl> > > > --- > > > drivers/video/console/Kconfig | 25 +++++++- > > > drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--- > > > ------------ > > > 2 files changed, 111 insertions(+), 56 deletions(-) > > > > > > diff --git a/drivers/video/console/Kconfig > > > b/drivers/video/console/Kconfig > > > index c3f1fb9ee820..f500e58f7636 100644 > > > --- a/drivers/video/console/Kconfig > > > +++ b/drivers/video/console/Kconfig > > > @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE > > > range 1 1024 > > > default "64" > > > help > > > - Enter the amount of System RAM to allocate for the > > > scrollback > > > - buffer. Each 64KB will give you approximately 16 80x25 > > > - screenfuls of scrollback buffer > > > + Enter the amount of System RAM to allocate for > > > scrollback > > > + buffers of VGA consoles. Each 64KB will give you > > > approximately > > > + 16 80x25 screenfuls of scrollback buffer. > > > + > > > +config VGACON_SOFT_SCROLLBACK_PERSISTENT > > > + bool "Persistent Scrollback History for each console" > > > + depends on VGACON_SOFT_SCROLLBACK > > > + default n > > > + help > > > + Say Y here if the scrollback history should persist when > > > switching > > > + between consoles. Otherwise, the scrollback history will > > > be flushed > > > + each time the console is switched. > > > + > > > + This feature might break your tool of choice to flush > > > the scrollback > > > + buffer, e.g. clear(1) will work fine but Debian's > > > clear_console(1) > > > + will be broken, which might cause security issues. > > > + You can use the escape sequence \e[3J instead if this > > > feature is > > > + activated. > > > > This issue is the one that makes me the most worried. Why doesn't > > clear_console() work anymore? Why doesn't it use \e[3J ? > > Well, clear_console() just switches from one console to another and > back again. It just assumes that the scrollback buffer is flushed when > switching. > My plan is to make a patch for clear_console() as soon as these patches > are in the kernel - it's chicken-and-egg problem. I'd recommend that patch get to clear_console() first, having it use the new escape sequence, if it isn't supported, shouldn't cause any problems, right? thanks, greg k-h ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-19 16:33 ` Greg KH @ 2017-01-19 23:04 ` Adam Borowski 2017-01-20 13:16 ` Adam Borowski 0 siblings, 1 reply; 49+ messages in thread From: Adam Borowski @ 2017-01-19 23:04 UTC (permalink / raw) To: Greg KH, Matthias Klose, 845177 Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote: > On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote: > > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote: > > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote: > > > > + This feature might break your tool of choice to flush > > > > the scrollback > > > > + buffer, e.g. clear(1) will work fine but Debian's > > > > clear_console(1) > > > > + will be broken, which might cause security issues. > > > > + You can use the escape sequence \e[3J instead if this > > > > feature is > > > > + activated. > > > > > > This issue is the one that makes me the most worried. Why doesn't > > > clear_console() work anymore? Why doesn't it use \e[3J ? > > > > Well, clear_console() just switches from one console to another and > > back again. It just assumes that the scrollback buffer is flushed when > > switching. > > My plan is to make a patch for clear_console() as soon as these patches > > are in the kernel - it's chicken-and-egg problem. > > I'd recommend that patch get to clear_console() first, having it use the > new escape sequence, if it isn't supported, shouldn't cause any > problems, right? In that case, we need to hurry -- the last day for any non-serious fixes in Debian is Jan 26, after that it'll be frozen for months, and any subsequent changes won't get to stable users for around two years. doko: would you consider, pretty please with a cherry on top, applying the patch I've sent to this bug? The privacy/security issue is pretty minor and applies only to a tiny fraction of users, but I understand why Greg is reluctant. Manuel's scrollback changes won't go to 4.9, and won't be enabled by default for the time being, but using a newer kernel on old userspace is something really widespread, be it via bpo, containers on an updated host, etc. Meow! -- Autotools hint: to do a zx-spectrum build on a pdp11 host, type: ./configure --host=zx-spectrum --build=pdp11 ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-19 23:04 ` Adam Borowski @ 2017-01-20 13:16 ` Adam Borowski 2017-01-20 13:31 ` Greg KH 0 siblings, 1 reply; 49+ messages in thread From: Adam Borowski @ 2017-01-20 13:16 UTC (permalink / raw) To: Greg KH Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Fri, Jan 20, 2017 at 12:04:12AM +0100, Adam Borowski wrote: > On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote: > > On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote: > > > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote: > > > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote: > > > > > + This feature might break your tool of choice to flush > > > > > the scrollback > > > > > + buffer, e.g. clear(1) will work fine but Debian's > > > > > clear_console(1) > > > > > + will be broken, which might cause security issues. > > > > > + You can use the escape sequence \e[3J instead if this > > > > > feature is > > > > > + activated. > > > > I'd recommend that patch get to clear_console() first, having it use the > > new escape sequence, if it isn't supported, shouldn't cause any > > problems, right? > > doko: would you consider, pretty please with a cherry on top, applying the > patch I've sent to this bug? The privacy/security issue is pretty minor and > applies only to a tiny fraction of users, but I understand why Greg is > reluctant. # Subject: Bug#845177 closed by Matthias Klose <doko@debian.org> # # This is an automatic notification regarding your Bug report # which was filed against the bash package: # # #845177: clear_console: assumes VT switch clears scrollback # # It has been closed by Matthias Klose <doko@debian.org>. [...] # Changes: # * clear_console: Securely erase the current console. Closes: #845177. -- Autotools hint: to do a zx-spectrum build on a pdp11 host, type: ./configure --host=zx-spectrum --build=pdp11 ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-20 13:16 ` Adam Borowski @ 2017-01-20 13:31 ` Greg KH 2017-01-20 14:27 ` Adam Borowski 0 siblings, 1 reply; 49+ messages in thread From: Greg KH @ 2017-01-20 13:31 UTC (permalink / raw) To: Adam Borowski Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Fri, Jan 20, 2017 at 02:16:11PM +0100, Adam Borowski wrote: > On Fri, Jan 20, 2017 at 12:04:12AM +0100, Adam Borowski wrote: > > On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote: > > > On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote: > > > > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote: > > > > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote: > > > > > > + This feature might break your tool of choice to flush > > > > > > the scrollback > > > > > > + buffer, e.g. clear(1) will work fine but Debian's > > > > > > clear_console(1) > > > > > > + will be broken, which might cause security issues. > > > > > > + You can use the escape sequence \e[3J instead if this > > > > > > feature is > > > > > > + activated. > > > > > > I'd recommend that patch get to clear_console() first, having it use the > > > new escape sequence, if it isn't supported, shouldn't cause any > > > problems, right? > > > > doko: would you consider, pretty please with a cherry on top, applying the > > patch I've sent to this bug? The privacy/security issue is pretty minor and > > applies only to a tiny fraction of users, but I understand why Greg is > > reluctant. > > # Subject: Bug#845177 closed by Matthias Klose <doko@debian.org> > # > # This is an automatic notification regarding your Bug report > # which was filed against the bash package: > # > # #845177: clear_console: assumes VT switch clears scrollback > # > # It has been closed by Matthias Klose <doko@debian.org>. > [...] > # Changes: > # * clear_console: Securely erase the current console. Closes: #845177. This means it was accepted? Or rejected? confused, greg k-h ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-20 13:31 ` Greg KH @ 2017-01-20 14:27 ` Adam Borowski 0 siblings, 0 replies; 49+ messages in thread From: Adam Borowski @ 2017-01-20 14:27 UTC (permalink / raw) To: Greg KH Cc: Manuel Schölling, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Fri, Jan 20, 2017 at 02:31:56PM +0100, Greg KH wrote: > On Fri, Jan 20, 2017 at 02:16:11PM +0100, Adam Borowski wrote: > > On Fri, Jan 20, 2017 at 12:04:12AM +0100, Adam Borowski wrote: > > > On Thu, Jan 19, 2017 at 05:33:14PM +0100, Greg KH wrote: > > > > I'd recommend that patch get to clear_console() first, having it use the > > > > new escape sequence, if it isn't supported, shouldn't cause any > > > > problems, right? > > > > # Subject: Bug#845177 closed by Matthias Klose <doko@debian.org> > > # > > # This is an automatic notification regarding your Bug report > > # which was filed against the bash package: > > # > > # #845177: clear_console: assumes VT switch clears scrollback > > # > > # It has been closed by Matthias Klose <doko@debian.org>. > > [...] > > # Changes: > > # * clear_console: Securely erase the current console. Closes: #845177. > > This means it was accepted? Or rejected? Accepted. It's in unstable (or will be in the next mirror pulse), we're at the fastest possible moment to get stuff to the next stable release -- it'll be in Stretch (about to freeze). Ubuntu migration is currently open so it'll get there soon, in time for Zesty (17.04). Other Debian derivatives likewise pull at their own pace. Most distributions unrelated to Debian don't seem to ship clear_console but I have no real idea: just checked Fedora 25, it doesn't have it in the default install at least. Meow! -- Autotools hint: to do a zx-spectrum build on a pdp11 host, type: ./configure --host=zx-spectrum --build=pdp11 ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles 2017-01-19 16:12 ` Manuel Schölling 2017-01-19 16:33 ` Greg KH @ 2017-01-19 17:20 ` Adam Borowski 1 sibling, 0 replies; 49+ messages in thread From: Adam Borowski @ 2017-01-19 17:20 UTC (permalink / raw) To: Manuel Schölling Cc: Greg KH, jslaby, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev On Thu, Jan 19, 2017 at 05:12:15PM +0100, Manuel Schölling wrote: > On Thu, 2017-01-19 at 14:23 +0100, Greg KH wrote: > > On Fri, Jan 13, 2017 at 09:07:57PM +0100, Manuel Schölling wrote: > > > Add a scrollback buffers for each VGA console. The benefit is that > > > the scrollback history is not flushed when switching between consoles > > > but is persistent. The buffers are allocated on demand when a new > > > console is opened. > > > > > > This breaks tools like clear_console that rely on flushing the > > > scrollback history by switching back and forth between consoles > > > which is why this feature is disabled by default. > > > Use the escape sequence \e[3J instead for flushing the buffer. > > > > This issue is the one that makes me the most worried. Why doesn't > > clear_console() work anymore? Why doesn't it use \e[3J ? > > Well, clear_console() just switches from one console to another and > back again. It just assumes that the scrollback buffer is flushed when > switching. > My plan is to make a patch for clear_console() as soon as these patches > are in the kernel - it's chicken-and-egg problem. No need to wait, \e[3J is supported since Linux 2.6.39; the problem I spotted was that a previous version of your patch would break that. It is also safe to output that sequence to a terminal unconditionally: I've tested a number of terminals, they all either support it (most X terminals, our console) or silently ignore it. We can't, though, rely on terminfo to do so: it knows about this capability (which it calls "E3") for TERM=linux only since very recently. The TERM variable is also unreliable: it fails to carry over a serial link while blindly printing \e[3J works. As for patching clear_console, https://bugs.debian.org/845177 has a minimal fix; although for all setups supported by Debian that program could be be better replaced with just "printf '\e[3J\e[2J'" which would make it work on strictly more terminals than current code does. Same for distributions which copied clear_console (it originates from Ubuntu, maintained in Debian since then). Meow! -- Autotools hint: to do a zx-spectrum build on a pdp11 host, type: ./configure --host=zx-spectrum --build=pdp11 ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH v10 4/4] console: Make persistent scrollback a boot parameter 2017-01-11 13:32 ` kbuild test robot ` (3 preceding siblings ...) 2017-01-13 20:07 ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2017-01-13 20:07 ` Manuel Schölling 4 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-13 20:07 UTC (permalink / raw) To: gregkh Cc: jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, akpm, paul.burton, daniel.vetter, tj, hdegoede, linux-kernel, linux-fbdev, Manuel Schölling The impact of the persistent scrollback feature on the code size is rather small, so the config option is removed. The feature stays disabled by default and can be enabled by using the boot command line parameter 'vgacon.scrollback_persistent=1' or by setting VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> --- drivers/video/console/Kconfig | 12 +++++++----- drivers/video/console/vgacon.c | 25 ++++++++++++------------- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index f500e58f7636..5b71bd905a60 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -47,14 +47,16 @@ config VGACON_SOFT_SCROLLBACK_SIZE buffers of VGA consoles. Each 64KB will give you approximately 16 80x25 screenfuls of scrollback buffer. -config VGACON_SOFT_SCROLLBACK_PERSISTENT - bool "Persistent Scrollback History for each console" +config VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT + bool "Persistent Scrollback History for each console by default" depends on VGACON_SOFT_SCROLLBACK default n help - Say Y here if the scrollback history should persist when switching - between consoles. Otherwise, the scrollback history will be flushed - each time the console is switched. + Say Y here if the scrollback history should persist by default when + switching between consoles. Otherwise, the scrollback history will be + flushed each time the console is switched. This feature can also be + enabled using the boot command line parameter + 'vgacon.scrollback_persistent=1'. This feature might break your tool of choice to flush the scrollback buffer, e.g. clear(1) will work fine but Debian's clear_console(1) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index ca23d222e029..dc06cb6a15dc 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -174,11 +174,11 @@ struct vgacon_scrollback_info { }; static struct vgacon_scrollback_info *vgacon_scrollback_cur; -#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; -#else -static struct vgacon_scrollback_info vgacon_scrollbacks[1]; -#endif +static bool scrollback_persistent = \ + IS_ENABLED(CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT); +module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles"); static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { @@ -213,20 +213,19 @@ static void vgacon_scrollback_init(int vc_num) static void vgacon_scrollback_switch(int vc_num) { -#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT - vc_num = 0; -#endif + if (!scrollback_persistent) + vc_num = 0; if (!vgacon_scrollbacks[vc_num].data) { vgacon_scrollback_init(vc_num); } else { -#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT - vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; -#else - size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + if (scrollback_persistent) { + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + } else { + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - vgacon_scrollback_reset(vc_num, size); -#endif + vgacon_scrollback_reset(vc_num, size); + } } } -- 2.11.0 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-01-10 21:28 ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 2017-01-10 22:58 ` Adam Borowski 2017-01-11 13:32 ` kbuild test robot @ 2017-02-02 20:07 ` Paul Gortmaker 2017-02-03 16:04 ` Manuel Schölling 2 siblings, 1 reply; 49+ messages in thread From: Paul Gortmaker @ 2017-02-02 20:07 UTC (permalink / raw) To: Manuel Schölling Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, Andrew Morton, paul.burton, daniel.vetter, tj, hdegoede, LKML, linux-fbdev On Tue, Jan 10, 2017 at 4:28 PM, Manuel Schölling <manuel.schoelling@gmx.de> wrote: > The impact of the persistent scrollback feature on the code size is > rather small, so the config option is removed. The feature stays > disabled by default and can be enabled by using the boot command line > parameter 'vgacon.scrollback_persistent=1' or by setting > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > --- [...] > +module_param_named(scrollback_persistent, scrollback_persistent, bool, 0000); > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent scrollback for all vga consoles"); Since this hasn't got widespread deployment yet and only exists in Greg's tree, can we please fix the above to use setup_param or similar, since there is nothing modular about this code at all. Thanks. Paul. ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-02-02 20:07 ` [PATCH v9 " Paul Gortmaker @ 2017-02-03 16:04 ` Manuel Schölling 2017-02-03 16:45 ` Adam Borowski 0 siblings, 1 reply; 49+ messages in thread From: Manuel Schölling @ 2017-02-03 16:04 UTC (permalink / raw) To: Paul Gortmaker Cc: gregkh, jslaby, kilobyte, lkml14, rdunlap, shorne, andrey_utkin, Andrew Morton, paul.burton, daniel.vetter, tj, hdegoede, LKML, linux-fbdev Hi Paul, On Thu, 2017-02-02 at 15:07 -0500, Paul Gortmaker wrote: > On Tue, Jan 10, 2017 at 4:28 PM, Manuel Schölling > <manuel.schoelling@gmx.de> wrote: > > The impact of the persistent scrollback feature on the code size is > > rather small, so the config option is removed. The feature stays > > disabled by default and can be enabled by using the boot command > > line > > parameter 'vgacon.scrollback_persistent=1' or by setting > > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. > > > > Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> > > Suggested-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> > > --- > > [...] > > > +module_param_named(scrollback_persistent, scrollback_persistent, > > bool, 0000); > > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent > > scrollback for all vga consoles"); > > Since this hasn't got widespread deployment yet and only exists > in Greg's tree, can we please fix the above to use setup_param or > similar, since there is nothing modular about this code at all. Not sure what you mean here. If this is not the right may to declare it I'd be more than happy to change this. But I could not find any function/macro named setup_param [1]. It would be great if you could give me a hint what function to use here! Have a great weekend! Manuel [1] http://lxr.free-electrons.com/ident?i=setup_param ^ permalink raw reply [flat|nested] 49+ messages in thread
* Re: [PATCH v9 4/4] console: Make persistent scrollback a boot parameter 2017-02-03 16:04 ` Manuel Schölling @ 2017-02-03 16:45 ` Adam Borowski 0 siblings, 0 replies; 49+ messages in thread From: Adam Borowski @ 2017-02-03 16:45 UTC (permalink / raw) To: Manuel Schölling Cc: Paul Gortmaker, gregkh, jslaby, lkml14, rdunlap, shorne, andrey_utkin, Andrew Morton, paul.burton, daniel.vetter, tj, hdegoede, LKML, linux-fbdev On Fri, Feb 03, 2017 at 05:04:15PM +0100, Manuel Schölling wrote: > On Thu, 2017-02-02 at 15:07 -0500, Paul Gortmaker wrote: > > On Tue, Jan 10, 2017 at 4:28 PM, Manuel Schölling > > <manuel.schoelling@gmx.de> wrote: > > > The impact of the persistent scrollback feature on the code size is > > > rather small, so the config option is removed. The feature stays > > > disabled by default and can be enabled by using the boot command > > > line > > > parameter 'vgacon.scrollback_persistent=1' or by setting > > > VGACON_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT=y. > > > > [...] > > > > > +module_param_named(scrollback_persistent, scrollback_persistent, > > > bool, 0000); > > > +MODULE_PARM_DESC(scrollback_persistent, "Enable persistent > > > scrollback for all vga consoles"); > > > > Since this hasn't got widespread deployment yet and only exists > > in Greg's tree, can we please fix the above to use setup_param or > > similar, since there is nothing modular about this code at all. > Not sure what you mean here. > If this is not the right may to declare it I'd be more than happy to > change this. But I could not find any function/macro named setup_param > [1]. > It would be great if you could give me a hint what function to use > here! > > [1] http://lxr.free-electrons.com/ident?i=setup_param That shows only exact matches. You want "git grep setup_param", which shows __setup_param() plus some unrelated stuff. I see only four uses in the kernel, but that's enough to see how to use it. Meow! -- Autotools hint: to do a zx-spectrum build on a pdp11 host, type: ./configure --host=zx-spectrum --build=pdp11 ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles 2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling ` (4 preceding siblings ...) 2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling @ 2017-01-02 14:27 ` Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling ` (2 more replies) 5 siblings, 3 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> -- Changes in v7: - Add new callback to consw struct for flushing video console driver's scrollback buffer. Fixes issues with escape sequence '\e[3J' reported by Adam Borowski (kilobyte@angband.pl). - Fix style issues Changes in v6: - Change of check if feature is enabled in vgacon_scrollback_switch() Changes in v5: - Clearify documentation - Skip superfluous array initialization - Disable scrollback if buffer allocation fails - Refactor vgacon_switch_scrollback() - Rename vgacon_switch_scrollback() to vgacon_scrollback_switch() - Add check for fg_console in vgacon_scrollback_update Changes in v4.1: - Fix compiler error Changes in v4: - Rename from VGACON_SOFT_SCROLLBACK_FOR_EACH_CONSOLE to VGACON_SOFT_SCROLLBACK_PERSISTENT - Split into two patches - Rework documentation - Remove cosmetic changes in comments (postponed) Changes in v3: - Add config option for this feature - Fallback to old scrollback buffer if kcalloc() fails - Remove ioctl() call again and add documentation about existing escape sequence to flush the scrollback buffer Changes in v2: - Add ioctl() call to flush scrollback buffer - (Patch v2 was not labeled as such, sorry) Manuel Schölling (3): console: Move scrollback data into its own struct console: Add callback to flush scrollback buffer to consw struct console: Add persistent scrollback buffers for all VGA consoles drivers/tty/vt/vt.c | 9 +++ drivers/video/console/Kconfig | 25 ++++++- drivers/video/console/vgacon.c | 165 ++++++++++++++++++++++++++++------------- include/linux/console.h | 4 + 4 files changed, 148 insertions(+), 55 deletions(-) -- 2.1.4 ^ permalink raw reply [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct 2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling @ 2017-01-02 14:27 ` Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel This refactoring is in preparation for persistent scrollback support for VGA console. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/vgacon.c | 91 ++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 44 deletions(-) diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index c22a562..48b9764 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,31 +162,34 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static void *vgacon_scrollback; -static int vgacon_scrollback_tail; -static int vgacon_scrollback_size; -static int vgacon_scrollback_rows; -static int vgacon_scrollback_cnt; -static int vgacon_scrollback_cur; -static int vgacon_scrollback_save; -static int vgacon_scrollback_restore; +static struct vgacon_scrollback_info { + void *data; + int tail; + int size; + int rows; + int cnt; + int cur; + int save; + int restore; +} vgacon_scrollback; static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - if (vgacon_scrollback) { - vgacon_scrollback_cnt = 0; - vgacon_scrollback_tail = 0; - vgacon_scrollback_cur = 0; - vgacon_scrollback_rows = rows - 1; - vgacon_scrollback_size = rows * pitch; + if (vgacon_scrollback.data) { + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; + vgacon_scrollback.rows = rows - 1; + vgacon_scrollback.size = rows * pitch; } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, GFP_NOWAIT); + vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, + 1024, GFP_NOWAIT); vgacon_scrollback_init(vga_video_num_columns * 2); } @@ -194,38 +197,38 @@ static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback_size || c->vc_num != fg_console) + if (!vgacon_scrollback.size || c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback + vgacon_scrollback_tail, + scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, p, c->vc_size_row); - vgacon_scrollback_cnt++; + vgacon_scrollback.cnt++; p += c->vc_size_row; - vgacon_scrollback_tail += c->vc_size_row; + vgacon_scrollback.tail += c->vc_size_row; - if (vgacon_scrollback_tail >= vgacon_scrollback_size) - vgacon_scrollback_tail = 0; + if (vgacon_scrollback.tail >= vgacon_scrollback.size) + vgacon_scrollback.tail = 0; - if (vgacon_scrollback_cnt > vgacon_scrollback_rows) - vgacon_scrollback_cnt = vgacon_scrollback_rows; + if (vgacon_scrollback.cnt > vgacon_scrollback.rows) + vgacon_scrollback.cnt = vgacon_scrollback.rows; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback_save = 0; + vgacon_scrollback.save = 0; - if (!vga_is_gfx && !vgacon_scrollback_restore) { + if (!vga_is_gfx && !vgacon_scrollback.restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback_restore = 1; - vgacon_scrollback_cur = vgacon_scrollback_cnt; + vgacon_scrollback.restore = 1; + vgacon_scrollback.cur = vgacon_scrollback.cnt; } } @@ -239,41 +242,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback) + if (!vgacon_scrollback.data) return; - if (!vgacon_scrollback_save) { + if (!vgacon_scrollback.save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback_save = 1; + vgacon_scrollback.save = 1; } - vgacon_scrollback_restore = 0; - start = vgacon_scrollback_cur + lines; + vgacon_scrollback.restore = 0; + start = vgacon_scrollback.cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback_cnt) - start = vgacon_scrollback_cnt; + if (start > vgacon_scrollback.cnt) + start = vgacon_scrollback.cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback_cnt) - end = vgacon_scrollback_cnt; + if (end > vgacon_scrollback.cnt) + end = vgacon_scrollback.cnt; - vgacon_scrollback_cur = start; + vgacon_scrollback.cur = start; count = end - start; - soff = vgacon_scrollback_tail - ((vgacon_scrollback_cnt - end) * + soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback_size; + soff += vgacon_scrollback.size; - count = vgacon_scrollback_cnt - start; + count = vgacon_scrollback.cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -287,13 +290,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback_size - soff); - scr_memcpyw(d, vgacon_scrollback + soff, copysize); + copysize = min(count, vgacon_scrollback.size - soff); + scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback, count); + scr_memcpyw(d, vgacon_scrollback.data, count); d += count; } -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct 2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling @ 2017-01-02 14:27 ` Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel This new callback is in preparation for persistent scrollback buffer support for VGA consoles. With a single scrollback buffer for all consoles, we could flush the buffer just by invocating consw->con_switch(). But when each VGA console has its own scrollback buffer, we need a new callback to tell the video console driver which buffer to flush. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/tty/vt/vt.c | 9 +++++++++ drivers/video/console/vgacon.c | 24 +++++++++++++++++++++++- include/linux/console.h | 4 ++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c index 4c10a9d..9d3ce50 100644 --- a/drivers/tty/vt/vt.c +++ b/drivers/tty/vt/vt.c @@ -625,6 +625,14 @@ static void save_screen(struct vc_data *vc) vc->vc_sw->con_save_screen(vc); } +static void flush_scrollback(struct vc_data *vc) +{ + WARN_CONSOLE_UNLOCKED(); + + if (vc->vc_sw->con_flush_scrollback) + vc->vc_sw->con_flush_scrollback(vc); +} + /* * Redrawing of screen */ @@ -1171,6 +1179,7 @@ static void csi_J(struct vc_data *vc, int vpar) case 3: /* erase scroll-back buffer (and whole display) */ scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char, vc->vc_screenbuf_size); + flush_scrollback(vc); set_origin(vc); if (con_is_visible(vc)) update_screen(vc); diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 48b9764..9a7c2bb 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -173,6 +173,16 @@ static struct vgacon_scrollback_info { int restore; } vgacon_scrollback; +static void vgacon_scrollback_reset(size_t reset_size) +{ + if (vgacon_scrollback.data && reset_size > 0) + memset(vgacon_scrollback.data, 0, reset_size); + + vgacon_scrollback.cnt = 0; + vgacon_scrollback.tail = 0; + vgacon_scrollback.cur = 0; +} + static void vgacon_scrollback_init(int pitch) { int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; @@ -305,6 +315,14 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) } else vgacon_cursor(c, CM_MOVE); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + if (c->vc_num == fg_console) + vgacon_scrollback_reset(size); +} #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) @@ -322,6 +340,10 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) vga_vram_size); vga_set_mem_top(c); } + +static void vgacon_flush_scrollback(struct vc_data *c) +{ +} #endif /* CONFIG_VGACON_SOFT_SCROLLBACK */ static const char *vgacon_startup(void) @@ -1329,7 +1351,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b, return true; } - /* * The console `switch' structure for the VGA based console */ @@ -1362,6 +1383,7 @@ const struct consw vga_con = { .con_save_screen = vgacon_save_screen, .con_build_attr = vgacon_build_attr, .con_invert_region = vgacon_invert_region, + .con_flush_scrollback = vgacon_flush_scrollback, }; EXPORT_SYMBOL(vga_con); diff --git a/include/linux/console.h b/include/linux/console.h index 9c26c66..5949d18 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -73,6 +73,10 @@ struct consw { u16 *(*con_screen_pos)(struct vc_data *, int); unsigned long (*con_getxy)(struct vc_data *, unsigned long, int *, int *); /* + * Flush the video console driver's scrollback buffer + */ + void (*con_flush_scrollback)(struct vc_data *); + /* * Prepare the console for the debugger. This includes, but is not * limited to, unblanking the console, loading an appropriate * palette, and allowing debugger generated output. -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
* [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles 2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling @ 2017-01-02 14:27 ` Manuel Schölling 2 siblings, 0 replies; 49+ messages in thread From: Manuel Schölling @ 2017-01-02 14:27 UTC (permalink / raw) To: plagnioj, tomi.valkeinen Cc: manuel.schoelling, jslaby, gregkh, andrey_utkin, kilobyte, linux-fbdev, linux-kernel Add a scrollback buffers for each VGA console. The benefit is that the scrollback history is not flushed when switching between consoles but is persistent. The buffers are allocated on demand when a new console is opened. This breaks tools like clear_console that rely on flushing the scrollback history by switching back and forth between consoles which is why this feature is disabled by default. Use the escape sequence \e[3J instead for flushing the buffer. Signed-off-by: Manuel Schölling <manuel.schoelling@gmx.de> Reviewed-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Andrey Utkin <andrey_utkin@fastmail.com> Tested-by: Adam Borowski <kilobyte@angband.pl> --- drivers/video/console/Kconfig | 25 +++++++- drivers/video/console/vgacon.c | 142 ++++++++++++++++++++++++++--------------- 2 files changed, 111 insertions(+), 56 deletions(-) diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 38da6e2..c5742d2 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -43,9 +43,28 @@ config VGACON_SOFT_SCROLLBACK_SIZE range 1 1024 default "64" help - Enter the amount of System RAM to allocate for the scrollback - buffer. Each 64KB will give you approximately 16 80x25 - screenfuls of scrollback buffer + Enter the amount of System RAM to allocate for scrollback + buffers of VGA consoles. Each 64KB will give you approximately + 16 80x25 screenfuls of scrollback buffer. + +config VGACON_SOFT_SCROLLBACK_PERSISTENT + bool "Persistent Scrollback History for each console" + depends on VGACON_SOFT_SCROLLBACK + default n + help + Say Y here if the scrollback history should persist when switching + between consoles. Otherwise, the scrollback history will be flushed + each time the console is switched. + + This feature might break your tool of choice to flush the scrollback + buffer, e.g. clear(1) will work fine but Debian's clear_console(1) + will be broken, which might cause security issues. + You can use the escape sequence \e[3J instead if this feature is + activated. + + Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each + created tty device. + So if you use a RAM-constrained system, say N here. config MDA_CONSOLE depends on !M68K && !PARISC && ISA diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index 9a7c2bb..ca23d22 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c @@ -162,7 +162,7 @@ static inline void vga_set_mem_top(struct vc_data *c) #ifdef CONFIG_VGACON_SOFT_SCROLLBACK /* software scrollback */ -static struct vgacon_scrollback_info { +struct vgacon_scrollback_info { void *data; int tail; int size; @@ -171,74 +171,110 @@ static struct vgacon_scrollback_info { int cur; int save; int restore; -} vgacon_scrollback; +}; + +static struct vgacon_scrollback_info *vgacon_scrollback_cur; +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT +static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES]; +#else +static struct vgacon_scrollback_info vgacon_scrollbacks[1]; +#endif -static void vgacon_scrollback_reset(size_t reset_size) +static void vgacon_scrollback_reset(int vc_num, size_t reset_size) { - if (vgacon_scrollback.data && reset_size > 0) - memset(vgacon_scrollback.data, 0, reset_size); + struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num]; + + if (scrollback->data && reset_size > 0) + memset(scrollback->data, 0, reset_size); - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; + scrollback->cnt = 0; + scrollback->tail = 0; + scrollback->cur = 0; } -static void vgacon_scrollback_init(int pitch) +static void vgacon_scrollback_init(int vc_num) { - int rows = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024/pitch; - - if (vgacon_scrollback.data) { - vgacon_scrollback.cnt = 0; - vgacon_scrollback.tail = 0; - vgacon_scrollback.cur = 0; - vgacon_scrollback.rows = rows - 1; - vgacon_scrollback.size = rows * pitch; + int pitch = vga_video_num_columns * 2; + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + int rows = size / pitch; + void *data; + + data = kmalloc_array(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, 1024, + GFP_NOWAIT); + + vgacon_scrollbacks[vc_num].data = data; + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; + + vgacon_scrollback_cur->rows = rows - 1; + vgacon_scrollback_cur->size = rows * pitch; + + vgacon_scrollback_reset(vc_num, size); +} + +static void vgacon_scrollback_switch(int vc_num) +{ +#ifndef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vc_num = 0; +#endif + + if (!vgacon_scrollbacks[vc_num].data) { + vgacon_scrollback_init(vc_num); + } else { +#ifdef CONFIG_VGACON_SOFT_SCROLLBACK_PERSISTENT + vgacon_scrollback_cur = &vgacon_scrollbacks[vc_num]; +#else + size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; + + vgacon_scrollback_reset(vc_num, size); +#endif } } static void vgacon_scrollback_startup(void) { - vgacon_scrollback.data = kcalloc(CONFIG_VGACON_SOFT_SCROLLBACK_SIZE, - 1024, GFP_NOWAIT); - vgacon_scrollback_init(vga_video_num_columns * 2); + vgacon_scrollback_cur = &vgacon_scrollbacks[0]; + vgacon_scrollback_init(0); } static void vgacon_scrollback_update(struct vc_data *c, int t, int count) { void *p; - if (!vgacon_scrollback.size || c->vc_num != fg_console) + if (!vgacon_scrollback_cur->data || !vgacon_scrollback_cur->size || + c->vc_num != fg_console) return; p = (void *) (c->vc_origin + t * c->vc_size_row); while (count--) { - scr_memcpyw(vgacon_scrollback.data + vgacon_scrollback.tail, + scr_memcpyw(vgacon_scrollback_cur->data + + vgacon_scrollback_cur->tail, p, c->vc_size_row); - vgacon_scrollback.cnt++; + + vgacon_scrollback_cur->cnt++; p += c->vc_size_row; - vgacon_scrollback.tail += c->vc_size_row; + vgacon_scrollback_cur->tail += c->vc_size_row; - if (vgacon_scrollback.tail >= vgacon_scrollback.size) - vgacon_scrollback.tail = 0; + if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size) + vgacon_scrollback_cur->tail = 0; - if (vgacon_scrollback.cnt > vgacon_scrollback.rows) - vgacon_scrollback.cnt = vgacon_scrollback.rows; + if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows) + vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } static void vgacon_restore_screen(struct vc_data *c) { - vgacon_scrollback.save = 0; + vgacon_scrollback_cur->save = 0; - if (!vga_is_gfx && !vgacon_scrollback.restore) { + if (!vga_is_gfx && !vgacon_scrollback_cur->restore) { scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - vgacon_scrollback.restore = 1; - vgacon_scrollback.cur = vgacon_scrollback.cnt; + vgacon_scrollback_cur->restore = 1; + vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt; } } @@ -252,41 +288,41 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) return; } - if (!vgacon_scrollback.data) + if (!vgacon_scrollback_cur->data) return; - if (!vgacon_scrollback.save) { + if (!vgacon_scrollback_cur->save) { vgacon_cursor(c, CM_ERASE); vgacon_save_screen(c); - vgacon_scrollback.save = 1; + vgacon_scrollback_cur->save = 1; } - vgacon_scrollback.restore = 0; - start = vgacon_scrollback.cur + lines; + vgacon_scrollback_cur->restore = 0; + start = vgacon_scrollback_cur->cur + lines; end = start + abs(lines); if (start < 0) start = 0; - if (start > vgacon_scrollback.cnt) - start = vgacon_scrollback.cnt; + if (start > vgacon_scrollback_cur->cnt) + start = vgacon_scrollback_cur->cnt; if (end < 0) end = 0; - if (end > vgacon_scrollback.cnt) - end = vgacon_scrollback.cnt; + if (end > vgacon_scrollback_cur->cnt) + end = vgacon_scrollback_cur->cnt; - vgacon_scrollback.cur = start; + vgacon_scrollback_cur->cur = start; count = end - start; - soff = vgacon_scrollback.tail - ((vgacon_scrollback.cnt - end) * - c->vc_size_row); + soff = vgacon_scrollback_cur->tail - + ((vgacon_scrollback_cur->cnt - end) * c->vc_size_row); soff -= count * c->vc_size_row; if (soff < 0) - soff += vgacon_scrollback.size; + soff += vgacon_scrollback_cur->size; - count = vgacon_scrollback.cnt - start; + count = vgacon_scrollback_cur->cnt - start; if (count > c->vc_rows) count = c->vc_rows; @@ -300,13 +336,13 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines) count *= c->vc_size_row; /* how much memory to end of buffer left? */ - copysize = min(count, vgacon_scrollback.size - soff); - scr_memcpyw(d, vgacon_scrollback.data + soff, copysize); + copysize = min(count, vgacon_scrollback_cur->size - soff); + scr_memcpyw(d, vgacon_scrollback_cur->data + soff, copysize); d += copysize; count -= copysize; if (count) { - scr_memcpyw(d, vgacon_scrollback.data, count); + scr_memcpyw(d, vgacon_scrollback_cur->data, count); d += count; } @@ -320,13 +356,13 @@ static void vgacon_flush_scrollback(struct vc_data *c) { size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024; - if (c->vc_num == fg_console) - vgacon_scrollback_reset(size); + vgacon_scrollback_reset(c->vc_num, size); } #else #define vgacon_scrollback_startup(...) do { } while (0) #define vgacon_scrollback_init(...) do { } while (0) #define vgacon_scrollback_update(...) do { } while (0) +#define vgacon_scrollback_switch(...) do { } while (0) static void vgacon_restore_screen(struct vc_data *c) { @@ -805,7 +841,7 @@ static int vgacon_switch(struct vc_data *c) vgacon_doresize(c, c->vc_cols, c->vc_rows); } - vgacon_scrollback_init(c->vc_size_row); + vgacon_scrollback_switch(c->vc_num); return 0; /* Redrawing not needed */ } -- 2.1.4 ^ permalink raw reply related [flat|nested] 49+ messages in thread
end of thread, other threads:[~2017-02-03 16:46 UTC | newest] Thread overview: 49+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-12-04 10:53 [PATCH v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 1/3] console: Move scrollback data into its own struct Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2016-12-04 10:53 ` [PATCH v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2016-12-06 10:02 ` [PATCH v7 0/3] " Greg KH 2016-12-06 16:32 ` Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND " Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2016-12-21 16:37 ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-04 13:54 ` [PATCH RESEND v7 0/3] " Andrey Utkin 2017-01-05 11:33 ` [PATCH v8 " Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 1/3] console: Move scrollback data into its own struct Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2017-01-05 11:33 ` [PATCH v8 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling [not found] ` <CGME20170110162224epcas1p2095912fa6b73a1457fa86396149e78e9@epcas1p2.samsung.com> 2017-01-10 16:22 ` Bartlomiej Zolnierkiewicz [not found] ` <CGME20170110164435epcas1p314efb9c6ea3ffb971fce06f3bfaec736@epcas1p3.samsung.com> 2017-01-10 16:44 ` Bartlomiej Zolnierkiewicz 2017-01-10 17:31 ` Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 0/4] " Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 1/4] console: Move scrollback data into its own struct Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-10 21:28 ` [PATCH v9 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 2017-01-10 22:58 ` Adam Borowski 2017-01-11 21:41 ` Manuel Schölling 2017-01-13 20:00 ` Manuel Schölling 2017-01-14 7:26 ` Greg KH 2017-01-11 13:32 ` kbuild test robot 2017-01-13 20:07 ` [PATCH v10 0/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-25 10:55 ` Greg KH 2017-01-13 20:07 ` [PATCH v10 1/4] console: Move scrollback data into its own struct Manuel Schölling 2017-01-13 20:07 ` [PATCH v10 2/4] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2017-01-13 20:07 ` [PATCH v10 3/4] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-19 13:23 ` Greg KH 2017-01-19 16:12 ` Manuel Schölling 2017-01-19 16:33 ` Greg KH 2017-01-19 23:04 ` Adam Borowski 2017-01-20 13:16 ` Adam Borowski 2017-01-20 13:31 ` Greg KH 2017-01-20 14:27 ` Adam Borowski 2017-01-19 17:20 ` Adam Borowski 2017-01-13 20:07 ` [PATCH v10 4/4] console: Make persistent scrollback a boot parameter Manuel Schölling 2017-02-02 20:07 ` [PATCH v9 " Paul Gortmaker 2017-02-03 16:04 ` Manuel Schölling 2017-02-03 16:45 ` Adam Borowski 2017-01-02 14:27 ` [PATCH RESEND v7 0/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 1/3] console: Move scrollback data into its own struct Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 2/3] console: Add callback to flush scrollback buffer to consw struct Manuel Schölling 2017-01-02 14:27 ` [PATCH RESEND v7 3/3] console: Add persistent scrollback buffers for all VGA consoles Manuel Schölling
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).