vgacon: remove software scrollback support

Yunhai Zhang recently fixed a VGA software scrollback bug in commit
ebfdfeeae8 ("vgacon: Fix for missing check in scrollback handling"),
but that then made people look more closely at some of this code, and
there were more problems on the vgacon side, but also the fbcon software
scrollback.

We don't really have anybody who maintains this code - probably because
nobody actually _uses_ it any more.  Sure, people still use both VGA and
the framebuffer consoles, but they are no longer the main user
interfaces to the kernel, and haven't been for decades, so these kinds
of extra features end up bitrotting and not really being used.

So rather than try to maintain a likely unused set of code, I'll just
aggressively remove it, and see if anybody even notices.  Maybe there
are people who haven't jumped on the whole GUI badnwagon yet, and think
it's just a fad.  And maybe those people use the scrollback code.

If that turns out to be the case, we can resurrect this again, once
we've found the sucker^Wmaintainer for it who actually uses it.

Reported-by: NopNop Nop <nopitydays@gmail.com>
Tested-by: Willy Tarreau <w@1wt.eu>
Cc: 张云海 <zhangyunhai@nsfocus.com>
Acked-by: Andy Lutomirski <luto@amacapital.net>
Acked-by: Willy Tarreau <w@1wt.eu>
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2020-09-09 14:53:50 -07:00
parent 06a0df4d1b
commit 973c096f6a
6 changed files with 1 additions and 270 deletions

View File

@ -108,7 +108,6 @@ CONFIG_FB_NVIDIA=y
CONFIG_FB_NVIDIA_I2C=y CONFIG_FB_NVIDIA_I2C=y
CONFIG_FB_RADEON=y CONFIG_FB_RADEON=y
# CONFIG_LCD_CLASS_DEVICE is not set # CONFIG_LCD_CLASS_DEVICE is not set
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_LOGO=y CONFIG_LOGO=y
CONFIG_SOUND=y CONFIG_SOUND=y
CONFIG_SND=y CONFIG_SND=y

View File

@ -743,7 +743,6 @@ CONFIG_FB_TRIDENT=m
CONFIG_FB_SM501=m CONFIG_FB_SM501=m
CONFIG_FB_IBM_GXT4500=y CONFIG_FB_IBM_GXT4500=y
CONFIG_LCD_PLATFORM=m CONFIG_LCD_PLATFORM=m
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
CONFIG_LOGO=y CONFIG_LOGO=y

View File

@ -186,7 +186,6 @@ CONFIG_DRM_I915=y
CONFIG_FB_MODE_HELPERS=y CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y CONFIG_FB_TILEBLITTING=y
CONFIG_FB_EFI=y CONFIG_FB_EFI=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_LOGO=y CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_VGA16 is not set

View File

@ -181,7 +181,6 @@ CONFIG_DRM_I915=y
CONFIG_FB_MODE_HELPERS=y CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_TILEBLITTING=y CONFIG_FB_TILEBLITTING=y
CONFIG_FB_EFI=y CONFIG_FB_EFI=y
CONFIG_VGACON_SOFT_SCROLLBACK=y
CONFIG_LOGO=y CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set # CONFIG_LOGO_LINUX_VGA16 is not set

View File

@ -22,52 +22,6 @@ config VGA_CONSOLE
Say Y. Say Y.
config VGACON_SOFT_SCROLLBACK
bool "Enable Scrollback Buffer in System RAM"
depends on VGA_CONSOLE
default n
help
The scrollback buffer of the standard VGA console is located in
the VGA RAM. The size of this RAM is fixed and is quite small.
If you require a larger scrollback buffer, this can be placed in
System RAM which is dynamically allocated during initialization.
Placing the scrollback buffer in System RAM will slightly slow
down the console.
If you want this feature, say 'Y' here and enter the amount of
RAM to allocate for this buffer. If unsure, say 'N'.
config VGACON_SOFT_SCROLLBACK_SIZE
int "Scrollback Buffer Size (in KB)"
depends on VGACON_SOFT_SCROLLBACK
range 1 1024
default "64"
help
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_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 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)
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 config MDA_CONSOLE
depends on !M68K && !PARISC && ISA depends on !M68K && !PARISC && ISA
tristate "MDA text console (dual-headed)" tristate "MDA text console (dual-headed)"

View File

@ -165,214 +165,6 @@ static inline void vga_set_mem_top(struct vc_data *c)
write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2); write_vga(12, (c->vc_visible_origin - vga_vram_base) / 2);
} }
#ifdef CONFIG_VGACON_SOFT_SCROLLBACK
/* software scrollback */
struct vgacon_scrollback_info {
void *data;
int tail;
int size;
int rows;
int cnt;
int cur;
int save;
int restore;
};
static struct vgacon_scrollback_info *vgacon_scrollback_cur;
static struct vgacon_scrollback_info vgacon_scrollbacks[MAX_NR_CONSOLES];
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)
{
struct vgacon_scrollback_info *scrollback = &vgacon_scrollbacks[vc_num];
if (scrollback->data && reset_size > 0)
memset(scrollback->data, 0, reset_size);
scrollback->cnt = 0;
scrollback->tail = 0;
scrollback->cur = 0;
}
static void vgacon_scrollback_init(int vc_num)
{
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)
{
if (!scrollback_persistent)
vc_num = 0;
if (!vgacon_scrollbacks[vc_num].data) {
vgacon_scrollback_init(vc_num);
} else {
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);
}
}
}
static void vgacon_scrollback_startup(void)
{
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_cur->data || !vgacon_scrollback_cur->size ||
c->vc_num != fg_console)
return;
p = (void *) (c->vc_origin + t * c->vc_size_row);
while (count--) {
if ((vgacon_scrollback_cur->tail + c->vc_size_row) >
vgacon_scrollback_cur->size)
vgacon_scrollback_cur->tail = 0;
scr_memcpyw(vgacon_scrollback_cur->data +
vgacon_scrollback_cur->tail,
p, c->vc_size_row);
vgacon_scrollback_cur->cnt++;
p += c->vc_size_row;
vgacon_scrollback_cur->tail += c->vc_size_row;
if (vgacon_scrollback_cur->tail >= vgacon_scrollback_cur->size)
vgacon_scrollback_cur->tail = 0;
if (vgacon_scrollback_cur->cnt > vgacon_scrollback_cur->rows)
vgacon_scrollback_cur->cnt = vgacon_scrollback_cur->rows;
vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
}
}
static void vgacon_restore_screen(struct vc_data *c)
{
c->vc_origin = c->vc_visible_origin;
vgacon_scrollback_cur->save = 0;
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_cur->restore = 1;
vgacon_scrollback_cur->cur = vgacon_scrollback_cur->cnt;
}
}
static void vgacon_scrolldelta(struct vc_data *c, int lines)
{
int start, end, count, soff;
if (!lines) {
vgacon_restore_screen(c);
return;
}
if (!vgacon_scrollback_cur->data)
return;
if (!vgacon_scrollback_cur->save) {
vgacon_cursor(c, CM_ERASE);
vgacon_save_screen(c);
c->vc_origin = (unsigned long)c->vc_screenbuf;
vgacon_scrollback_cur->save = 1;
}
vgacon_scrollback_cur->restore = 0;
start = vgacon_scrollback_cur->cur + lines;
end = start + abs(lines);
if (start < 0)
start = 0;
if (start > vgacon_scrollback_cur->cnt)
start = vgacon_scrollback_cur->cnt;
if (end < 0)
end = 0;
if (end > vgacon_scrollback_cur->cnt)
end = vgacon_scrollback_cur->cnt;
vgacon_scrollback_cur->cur = start;
count = end - start;
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_cur->size;
count = vgacon_scrollback_cur->cnt - start;
if (count > c->vc_rows)
count = c->vc_rows;
if (count) {
int copysize;
int diff = c->vc_rows - count;
void *d = (void *) c->vc_visible_origin;
void *s = (void *) c->vc_screenbuf;
count *= c->vc_size_row;
/* how much memory to end of buffer left? */
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_cur->data, count);
d += count;
}
if (diff)
scr_memcpyw(d, s, diff * c->vc_size_row);
} else
vgacon_cursor(c, CM_MOVE);
}
static void vgacon_flush_scrollback(struct vc_data *c)
{
size_t size = CONFIG_VGACON_SOFT_SCROLLBACK_SIZE * 1024;
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) static void vgacon_restore_screen(struct vc_data *c)
{ {
if (c->vc_origin != c->vc_visible_origin) if (c->vc_origin != c->vc_visible_origin)
@ -386,11 +178,6 @@ static void vgacon_scrolldelta(struct vc_data *c, int lines)
vga_set_mem_top(c); 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) static const char *vgacon_startup(void)
{ {
const char *display_desc = NULL; const char *display_desc = NULL;
@ -573,10 +360,7 @@ static const char *vgacon_startup(void)
vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH; vgacon_xres = screen_info.orig_video_cols * VGA_FONTWIDTH;
vgacon_yres = vga_scan_lines; vgacon_yres = vga_scan_lines;
if (!vga_init_done) { vga_init_done = true;
vgacon_scrollback_startup();
vga_init_done = true;
}
return display_desc; return display_desc;
} }
@ -869,7 +653,6 @@ static int vgacon_switch(struct vc_data *c)
vgacon_doresize(c, c->vc_cols, c->vc_rows); vgacon_doresize(c, c->vc_cols, c->vc_rows);
} }
vgacon_scrollback_switch(c->vc_num);
return 0; /* Redrawing not needed */ return 0; /* Redrawing not needed */
} }
@ -1386,7 +1169,6 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
oldo = c->vc_origin; oldo = c->vc_origin;
delta = lines * c->vc_size_row; delta = lines * c->vc_size_row;
if (dir == SM_UP) { if (dir == SM_UP) {
vgacon_scrollback_update(c, t, lines);
if (c->vc_scr_end + delta >= vga_vram_end) { if (c->vc_scr_end + delta >= vga_vram_end) {
scr_memcpyw((u16 *) vga_vram_base, scr_memcpyw((u16 *) vga_vram_base,
(u16 *) (oldo + delta), (u16 *) (oldo + delta),
@ -1450,7 +1232,6 @@ const struct consw vga_con = {
.con_save_screen = vgacon_save_screen, .con_save_screen = vgacon_save_screen,
.con_build_attr = vgacon_build_attr, .con_build_attr = vgacon_build_attr,
.con_invert_region = vgacon_invert_region, .con_invert_region = vgacon_invert_region,
.con_flush_scrollback = vgacon_flush_scrollback,
}; };
EXPORT_SYMBOL(vga_con); EXPORT_SYMBOL(vga_con);