Linux Serial subsystem development
 help / color / mirror / Atom feed
* [PATCH 0/5] fbcon,vgacon,vt: Share helpers for text cursors
@ 2026-09-11  9:25 Thomas Zimmermann
  2026-09-11  9:25 ` [PATCH 1/5] vt: Add cursor-size helpers Thomas Zimmermann
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2026-09-11  9:25 UTC (permalink / raw)
  To: deller, gregkh, jirislaby, simona
  Cc: linux-fbdev, dri-devel, linux-serial, sashiko-reviews,
	Thomas Zimmermann

VT consoles fbcon and vgacon implement various cursor sizes (i.e.,
underline, block, half-block, etc). Share related code and harmonize
the look and behaviour.

In patches 1 to 3, move VT cursor-size calculations to the VT subsystem
and use the new helpers from vgacon. Replace similar code in the console.
The new helpers also take VT's default cursor size into account. Fbcon
will be updated in patch 5. Other consoles (newport_con, sticon) don't
support cursor sizes, so leave them as-is. 

Fbcon implments a custom helper that creates a cursor glyph for the
given cursor size. In patches 4 and 5, move the code into the font
library and update fbcon to use the new helper. The cursor-glyph shape
rendering is tried to font in use. Hence move them next to each other.
Also update fbcon to use the shared cursor-size helpers.

Tested with fbcon under bochs (qemu) and with vgacon on an old SiS
6202 VGA card.

Thomas Zimmermann (5):
  vt: Add cursor-size helpers
  vgacon: Remove trailing whitespaces
  vgacon: Use vt_font_cursor_{start,end}()
  lib/fonts: Add font_glyph_cursor() helper
  fbcon: Replace fbcon_fill_cursor_mask() with fbcon_cursor_glyph()

 drivers/tty/vt/vt.c                  | 90 ++++++++++++++++++++++++++++
 drivers/video/console/vgacon.c       | 46 ++++----------
 drivers/video/fbdev/core/bitblit.c   |  3 +-
 drivers/video/fbdev/core/fbcon.c     | 44 ++++----------
 drivers/video/fbdev/core/fbcon.h     |  2 +-
 drivers/video/fbdev/core/fbcon_ccw.c |  3 +-
 drivers/video/fbdev/core/fbcon_cw.c  |  3 +-
 drivers/video/fbdev/core/fbcon_ud.c  |  3 +-
 include/linux/console_struct.h       |  2 +
 include/linux/font.h                 |  4 ++
 lib/fonts/Makefile                   |  3 +-
 lib/fonts/font_cursor.c              | 56 +++++++++++++++++
 12 files changed, 180 insertions(+), 79 deletions(-)
 create mode 100644 lib/fonts/font_cursor.c


base-commit: cf3f6830cd1a44f792534b4f5695c5ca7a69943d
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: a5a973e527c88a5b47053d7a72aefe0b550197cb
prerequisite-patch-id: b9adc9622920a3e70168e672c2c92795b3e3a106
prerequisite-patch-id: 5030de433a01c2e99056cadb676a8e2ba35f055a
prerequisite-patch-id: 6f645bbd39e5c6af230c94ecaf78db518a8e2e10
-- 
2.55.0


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH 1/5] vt: Add cursor-size helpers
  2026-09-11  9:25 [PATCH 0/5] fbcon,vgacon,vt: Share helpers for text cursors Thomas Zimmermann
@ 2026-09-11  9:25 ` Thomas Zimmermann
  2026-09-11  9:55   ` sashiko-bot
  2026-09-12 19:01   ` Helge Deller
  2026-09-11  9:25 ` [PATCH 2/5] vgacon: Remove trailing whitespaces Thomas Zimmermann
                   ` (3 subsequent siblings)
  4 siblings, 2 replies; 12+ messages in thread
From: Thomas Zimmermann @ 2026-09-11  9:25 UTC (permalink / raw)
  To: deller, gregkh, jirislaby, simona
  Cc: linux-fbdev, dri-devel, linux-serial, sashiko-reviews,
	Thomas Zimmermann

Cursors in the VT subsystem are blocks within a character cell that are
filled with the foreground color. The new helpers vc_font_cursor_start()
and vc_font_cursor_end() return the scanlines in which the cursor block
starts rsp. ends. This is compatible with VGA hardware

In terms of cursor design, the new cursor-size helpers follow established
styles in fbcon. The only exception is in underline cursors for fonts with
a size larger than 10. The underlining dash is now one pixel closer to
the font-glyph data, so that the cursor looks less detached. This follows
the style used by vgacon.

Similar code in vgacon and fbcon ignores the cursor's default size stored
in vt.cur_default. The consoles default to full-block cursors, while vt
defaults to underline cursors. The new helper fall back to cur_default and
then underline cursors; in this order.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/tty/vt/vt.c            | 90 ++++++++++++++++++++++++++++++++++
 include/linux/console_struct.h |  2 +
 2 files changed, 92 insertions(+)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8f467b22b799..87c4bc2ef495 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -264,6 +264,96 @@ unsigned int vc_font_size(const struct vc_font *font)
 }
 EXPORT_SYMBOL_GPL(vc_font_size);
 
+static unsigned int vc_cursor_start(unsigned int height, unsigned int cursor_size)
+{
+retry:
+	switch (cursor_size) {
+	case CUR_NONE:
+		return height;
+	case CUR_UNDERLINE:
+		if (height < 10)
+			return height - 1;
+		else
+			return height - 3;
+	case CUR_LOWER_THIRD:
+		return height - height / 3;
+	case CUR_LOWER_HALF:
+		return height - height / 2;
+	case CUR_TWO_THIRDS:
+		return height - (height * 2) / 3;
+	case CUR_BLOCK:
+		return 0;
+	default:
+		pr_warn_once("Unknown cursor %u\n", cursor_size);
+		if (cursor_size != CUR_SIZE(cur_default))
+			cursor_size = CUR_SIZE(cur_default);
+		else
+			cursor_size = CUR_UNDERLINE;
+		goto retry;
+	}
+}
+
+/**
+ * vc_font_cursor_start - Calculates the cursor's first scanline within a glyph
+ * @font: The VC font
+ * @cursor_type: The type of cursor pattern
+ *
+ * The parameter @font is an initialized font. The argument in @cursor_type
+ * is one of the CUR_ constants, as stored in struct @vc_data.vc_cursor_type. For
+ * unknown values, the helper draws an underline dash.
+ *
+ * Returns:
+ * The index of the cursor's first scanline within the glyph
+ */
+unsigned int vc_font_cursor_start(const struct vc_font *font, unsigned int cursor_type)
+{
+	return vc_cursor_start(font->height, CUR_SIZE(cursor_type));
+}
+EXPORT_SYMBOL_GPL(vc_font_cursor_start);
+
+static unsigned int vc_cursor_end(unsigned int height, unsigned int cursor_size)
+{
+retry:
+	switch (cursor_size) {
+	case CUR_UNDERLINE:
+		if (height < 10)
+			return height;
+		else
+			return height - 1;
+	case CUR_NONE:
+	case CUR_LOWER_THIRD:
+	case CUR_LOWER_HALF:
+	case CUR_TWO_THIRDS:
+	case CUR_BLOCK:
+		return height;
+	default:
+		pr_warn_once("Unknown cursor %u\n", cursor_size);
+		if (cursor_size != CUR_SIZE(cur_default))
+			cursor_size = CUR_SIZE(cur_default);
+		else
+			cursor_size = CUR_UNDERLINE;
+		goto retry;
+	}
+}
+
+/**
+ * vc_font_cursor_end - Calculates the first scanline after the cursor within a glyph
+ * @font: The VC font
+ * @cursor_type: The type of cursor pattern
+ *
+ * The parameter @font is an initialized font. The argument in @cursor_type
+ * is one of the CUR_ constants, as stored in struct @vc_data.vc_cursor_type. For
+ * unknown values, the helper draws an underline dash.
+ *
+ * Returns:
+ * The index of the first scanline after the cursor within the glyph
+ */
+unsigned int vc_font_cursor_end(const struct vc_font *font, unsigned int cursor_type)
+{
+	return vc_cursor_end(font->height, CUR_SIZE(cursor_type));
+}
+EXPORT_SYMBOL_GPL(vc_font_cursor_end);
+
 /*
  * /sys/class/tty/tty0/
  *
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index fe915afdece5..6f30f209e1b0 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -84,6 +84,8 @@ struct vc_font {
 
 unsigned int vc_font_pitch(const struct vc_font *font);
 unsigned int vc_font_size(const struct vc_font *font);
+unsigned int vc_font_cursor_start(const struct vc_font *font, unsigned int cursor_type);
+unsigned int vc_font_cursor_end(const struct vc_font *font, unsigned int cursor_type);
 
 /*
  * Example: vc_data of a console that was scrolled 3 lines down.
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 2/5] vgacon: Remove trailing whitespaces
  2026-09-11  9:25 [PATCH 0/5] fbcon,vgacon,vt: Share helpers for text cursors Thomas Zimmermann
  2026-09-11  9:25 ` [PATCH 1/5] vt: Add cursor-size helpers Thomas Zimmermann
@ 2026-09-11  9:25 ` Thomas Zimmermann
  2026-09-11  9:46   ` sashiko-bot
  2026-09-11  9:25 ` [PATCH 3/5] vgacon: Use vt_font_cursor_{start,end}() Thomas Zimmermann
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Thomas Zimmermann @ 2026-09-11  9:25 UTC (permalink / raw)
  To: deller, gregkh, jirislaby, simona
  Cc: linux-fbdev, dri-devel, linux-serial, sashiko-reviews,
	Thomas Zimmermann

Fix coding style.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/video/console/vgacon.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 37bd18730fe0..536e7fe4d142 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -881,14 +881,14 @@ static int vgacon_do_font_op(struct vgastate *state, char *arg, int set,
 	/* First, the Sequencer */
 	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x1);
 	/* CPU writes only to map 2 */
-	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x04);	
+	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x04);
 	/* Sequential addressing */
-	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x07);	
+	vga_wseq(state->vgabase, VGA_SEQ_MEMORY_MODE, 0x07);
 	/* Clear synchronous reset */
 	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x03);
 
 	/* Now, the graphics controller, select map 2 */
-	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x02);		
+	vga_wgfx(state->vgabase, VGA_GFX_PLANE_READ, 0x02);
 	/* disable odd-even addressing */
 	vga_wgfx(state->vgabase, VGA_GFX_MODE, 0x00);
 	/* map start at A000:0000 */
@@ -930,7 +930,7 @@ static int vgacon_do_font_op(struct vgastate *state, char *arg, int set,
 
 	raw_spin_lock_irq(&vga_lock);
 	/* First, the sequencer, Synchronous reset */
-	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01);	
+	vga_wseq(state->vgabase, VGA_SEQ_RESET, 0x01);
 	/* CPU writes to maps 0 and 1 */
 	vga_wseq(state->vgabase, VGA_SEQ_PLANE_WRITE, 0x03);
 	/* odd-even addressing */
@@ -959,7 +959,7 @@ static int vgacon_do_font_op(struct vgastate *state, char *arg, int set,
 		/* Wilton (1987) mentions the following; I don't know what
 		   it means, but it works, and it appears necessary */
 		inb_p(video_port_status);
-		vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);	
+		vga_wattr(state->vgabase, VGA_AR_ENABLE_DISPLAY, 0);
 		clear_attribs = true;
 	}
 	raw_spin_unlock_irq(&vga_lock);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 3/5] vgacon: Use vt_font_cursor_{start,end}()
  2026-09-11  9:25 [PATCH 0/5] fbcon,vgacon,vt: Share helpers for text cursors Thomas Zimmermann
  2026-09-11  9:25 ` [PATCH 1/5] vt: Add cursor-size helpers Thomas Zimmermann
  2026-09-11  9:25 ` [PATCH 2/5] vgacon: Remove trailing whitespaces Thomas Zimmermann
@ 2026-09-11  9:25 ` Thomas Zimmermann
  2026-09-11  9:58   ` sashiko-bot
  2026-09-11  9:25 ` [PATCH 4/5] lib/fonts: Add font_glyph_cursor() helper Thomas Zimmermann
  2026-09-11  9:25 ` [PATCH 5/5] fbcon: Replace fbcon_fill_cursor_mask() with fbcon_cursor_glyph() Thomas Zimmermann
  4 siblings, 1 reply; 12+ messages in thread
From: Thomas Zimmermann @ 2026-09-11  9:25 UTC (permalink / raw)
  To: deller, gregkh, jirislaby, simona
  Cc: linux-fbdev, dri-devel, linux-serial, sashiko-reviews,
	Thomas Zimmermann

Replace vgacon's custom cursor metrics with the shared helpers
vc_font_cursor_start() and vc_font_cursor_end(). Note that the
_end() function returns the index of the scanline below the cursor,
while VGA hardware expects the cursor's final scanline. Hence vgacon
subtracts 1 from the end value.

The cursor shapes remain mostly unchanged, except that non-underline
cursors now also use the glyph's top-most and bottom-most scanline.
This follows the style used by fbcon.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/video/console/vgacon.c | 36 ++++++----------------------------
 1 file changed, 6 insertions(+), 30 deletions(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 536e7fe4d142..b16ddb1b09a7 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -36,6 +36,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/fs.h>
+#include <linux/font.h>
 #include <linux/kernel.h>
 #include <linux/console.h>
 #include <linux/string.h>
@@ -505,18 +506,18 @@ static void vgacon_set_cursor_size(int from, int to)
 
 static void vgacon_cursor(struct vc_data *c, bool enable)
 {
-	unsigned int c_height;
+	unsigned int c_type;
 
 	if (c->vc_mode != KD_TEXT)
 		return;
 
 	vgacon_restore_screen(c);
 
-	c_height = c->vc_cell_height;
+	c_type = c->vc_cursor_type;
 
 	write_vga(14, (c->vc_pos - vga_vram_base) / 2);
 
-	if (!enable) {
+	if (!enable || CUR_SIZE(c_type) == CUR_NONE) {
 	        if (vga_video_type >= VIDEO_TYPE_VGAC)
 			vgacon_set_cursor_size(31, 30);
 		else
@@ -524,33 +525,8 @@ static void vgacon_cursor(struct vc_data *c, bool enable)
 		return;
 	}
 
-	switch (CUR_SIZE(c->vc_cursor_type)) {
-	case CUR_UNDERLINE:
-		vgacon_set_cursor_size(c_height - (c_height < 10 ? 2 : 3),
-				       c_height - (c_height < 10 ? 1 : 2));
-		break;
-	case CUR_TWO_THIRDS:
-		vgacon_set_cursor_size(c_height / 3,
-				       c_height - (c_height < 10 ? 1 : 2));
-		break;
-	case CUR_LOWER_THIRD:
-		vgacon_set_cursor_size(c_height * 2 / 3,
-				       c_height - (c_height < 10 ? 1 : 2));
-		break;
-	case CUR_LOWER_HALF:
-		vgacon_set_cursor_size(c_height / 2,
-				       c_height - (c_height < 10 ? 1 : 2));
-		break;
-	case CUR_NONE:
-		if (vga_video_type >= VIDEO_TYPE_VGAC)
-			vgacon_set_cursor_size(31, 30);
-		else
-			vgacon_set_cursor_size(31, 31);
-		break;
-	default:
-		vgacon_set_cursor_size(1, c_height);
-		break;
-	}
+	vgacon_set_cursor_size(vc_font_cursor_start(&c->vc_font, c_type),
+			       vc_font_cursor_end(&c->vc_font, c_type) - 1);
 }
 
 static void vgacon_doresize(struct vc_data *c,
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 4/5] lib/fonts: Add font_glyph_cursor() helper
  2026-09-11  9:25 [PATCH 0/5] fbcon,vgacon,vt: Share helpers for text cursors Thomas Zimmermann
                   ` (2 preceding siblings ...)
  2026-09-11  9:25 ` [PATCH 3/5] vgacon: Use vt_font_cursor_{start,end}() Thomas Zimmermann
@ 2026-09-11  9:25 ` Thomas Zimmermann
  2026-09-11  9:52   ` sashiko-bot
  2026-09-11  9:25 ` [PATCH 5/5] fbcon: Replace fbcon_fill_cursor_mask() with fbcon_cursor_glyph() Thomas Zimmermann
  4 siblings, 1 reply; 12+ messages in thread
From: Thomas Zimmermann @ 2026-09-11  9:25 UTC (permalink / raw)
  To: deller, gregkh, jirislaby, simona
  Cc: linux-fbdev, dri-devel, linux-serial, sashiko-reviews,
	Thomas Zimmermann

The new helper font_glyph_cursor() fills a glyph with a cursor pattern.
As with the font_glyph_rotate_*() helpers, the caller has to provide the
output memory.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 include/linux/font.h    |  4 +++
 lib/fonts/Makefile      |  3 ++-
 lib/fonts/font_cursor.c | 56 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 62 insertions(+), 1 deletion(-)
 create mode 100644 lib/fonts/font_cursor.c

diff --git a/include/linux/font.h b/include/linux/font.h
index 5e1cf9830084..be1a26ff8ae9 100644
--- a/include/linux/font.h
+++ b/include/linux/font.h
@@ -109,6 +109,10 @@ const unsigned char *font_data_glyph_buf(font_data_t *fd,
 bool font_data_is_equal(font_data_t *lhs, font_data_t *rhs);
 int font_data_export(font_data_t *fd, struct console_font *font, unsigned int vpitch);
 
+/* font_cursor.c */
+void font_glyph_cursor(unsigned int width, unsigned int height,
+		       unsigned int from, unsigned int to, unsigned char *out);
+
 /* font_rotate.c */
 void font_glyph_rotate_90(const unsigned char *glyph, unsigned int width, unsigned int height,
 			  unsigned char *out);
diff --git a/lib/fonts/Makefile b/lib/fonts/Makefile
index 7202a70a56ef..bc08bf8ea3f8 100644
--- a/lib/fonts/Makefile
+++ b/lib/fonts/Makefile
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0
 # Font handling
 
-font-y := fonts.o
+font-y := fonts.o \
+	  font_cursor.o
 font-$(CONFIG_FRAMEBUFFER_CONSOLE_ROTATION) += font_rotate.o
 
 # Built-in fonts; sorted by Family-Size in ascending order
diff --git a/lib/fonts/font_cursor.c b/lib/fonts/font_cursor.c
new file mode 100644
index 000000000000..7f4d587669aa
--- /dev/null
+++ b/lib/fonts/font_cursor.c
@@ -0,0 +1,56 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bug.h>
+#include <linux/export.h>
+#include <linux/string.h>
+
+#include "font.h"
+
+/**
+ * font_glyph_cursor - Create a cursor glyph
+ * @width: The glyph width in bits per scanline
+ * @height: The number of scanlines in the glyph
+ * @start: The first scanline of the cursor block
+ * @end: The first scanline after the cursor block
+ * @out: The cursor-glyph bitmap
+ *
+ * The parameters @width and @height refer to the glyph size. The caller
+ * has to provide the output buffer @out of sufficient size to hold the
+ * cursor glyph. The arguments in @start and @end describe the number of
+ * scanlines occupied by the cursor block; counting from the top of the
+ * glyph. The helper fills these scanlines with a pattern and clears the
+ * remaining scanlines.
+ */
+void font_glyph_cursor(unsigned int width, unsigned int height,
+		       unsigned int start, unsigned int end, unsigned char *out)
+{
+	unsigned int pitch = font_glyph_pitch(width);
+	const unsigned char *out_end = out + height * pitch;
+	unsigned int size;
+
+	if (WARN_ON_ONCE(start > height))
+		start = height;
+	if (WARN_ON_ONCE(end > height))
+		end = height;
+
+	if (end < start)
+		end = start;
+
+	/* clear scanlines before cursor block */
+	size = start * pitch;
+	memset(out, 0x00, size);
+	out += size;
+
+	/* set cursor block */
+	size = (end - start) * pitch;
+	memset(out, 0xff, size);
+	out += size;
+
+	/* clear scanlines below cursor block */
+	size = (height - end) * pitch;
+	memset(out, 0x00, size);
+	out += size;
+
+	WARN_ON_ONCE(out != out_end);
+}
+EXPORT_SYMBOL_GPL(font_glyph_cursor);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH 5/5] fbcon: Replace fbcon_fill_cursor_mask() with fbcon_cursor_glyph()
  2026-09-11  9:25 [PATCH 0/5] fbcon,vgacon,vt: Share helpers for text cursors Thomas Zimmermann
                   ` (3 preceding siblings ...)
  2026-09-11  9:25 ` [PATCH 4/5] lib/fonts: Add font_glyph_cursor() helper Thomas Zimmermann
@ 2026-09-11  9:25 ` Thomas Zimmermann
  2026-09-11  9:50   ` sashiko-bot
  4 siblings, 1 reply; 12+ messages in thread
From: Thomas Zimmermann @ 2026-09-11  9:25 UTC (permalink / raw)
  To: deller, gregkh, jirislaby, simona
  Cc: linux-fbdev, dri-devel, linux-serial, sashiko-reviews,
	Thomas Zimmermann

The kernel's font library provides font_glyph_cursor() to create cursor
glyphs. Replace fbcon's fbcon_fill_cursor_mask() with a new helper that
uses font_glyph_cursor().

The cursor shapes remain mostly unchanged. The only exception is in
underline cursors for fonts with a size larger than 10. The underlining
dash is now one pixel closer to the font-glyph data, so that the cursor
looks less detached. This follows the style used by vgacon.

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
---
 drivers/video/fbdev/core/bitblit.c   |  3 +-
 drivers/video/fbdev/core/fbcon.c     | 44 +++++++---------------------
 drivers/video/fbdev/core/fbcon.h     |  2 +-
 drivers/video/fbdev/core/fbcon_ccw.c |  3 +-
 drivers/video/fbdev/core/fbcon_cw.c  |  3 +-
 drivers/video/fbdev/core/fbcon_ud.c  |  3 +-
 6 files changed, 15 insertions(+), 43 deletions(-)

diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index 39f44258d793..03b3b18e1fe9 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -334,11 +334,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    vc->vc_cursor_type != par->p->cursor_shape ||
 	    par->cursor_state.mask == NULL ||
 	    par->cursor_reset) {
-		unsigned char *mask = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
+		unsigned char *mask = fbcon_cursor_glyph(&vc->vc_font, vc->vc_cursor_type);
 
 		if (!mask)
 			return;
-		fbcon_fill_cursor_mask(par, vc, mask);
 
 		kfree(par->cursor_state.mask);
 		par->cursor_state.mask = (const char *)mask;
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 23b3c536d53d..53de2d982692 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -445,44 +445,20 @@ static void fbcon_del_cursor_work(struct fb_info *info)
 	cancel_delayed_work_sync(&par->cursor_work);
 }
 
-void fbcon_fill_cursor_mask(struct fbcon_par *par, struct vc_data *vc, unsigned char *mask)
+unsigned char *fbcon_cursor_glyph(const struct vc_font *font, unsigned int cursor_type)
 {
-	static const unsigned int pattern = 0xffffffff;
-	unsigned int pitch = vc_font_pitch(&vc->vc_font);
-	unsigned int cur_height, size;
+	unsigned int height = font->height;
+	unsigned char *glyph;
 
-	switch (CUR_SIZE(vc->vc_cursor_type)) {
-	case CUR_NONE:
-		cur_height = 0;
-		break;
-	case CUR_UNDERLINE:
-		if (vc->vc_font.height < 10)
-			cur_height = 1;
-		else
-			cur_height = 2;
-		break;
-	case CUR_LOWER_THIRD:
-		cur_height = vc->vc_font.height / 3;
-		break;
-	case CUR_LOWER_HALF:
-		cur_height = vc->vc_font.height / 2;
-		break;
-	case CUR_TWO_THIRDS:
-		cur_height = (vc->vc_font.height * 2) / 3;
-		break;
-	case CUR_BLOCK:
-	default:
-		cur_height = vc->vc_font.height;
-		break;
-	}
+	glyph = kmalloc_array(height, vc_font_pitch(font), GFP_ATOMIC);
+	if (!glyph)
+		return NULL;
 
-	size = (vc->vc_font.height - cur_height) * pitch;
-	while (size--)
-		*mask++ = (unsigned char)~pattern;
+	font_glyph_cursor(font->width, height,
+			  vc_font_cursor_start(font, cursor_type),
+			  vc_font_cursor_end(font, cursor_type), glyph);
 
-	size = cur_height * pitch;
-	while (size--)
-		*mask++ = (unsigned char)pattern;
+	return glyph;
 }
 
 #ifndef MODULE
diff --git a/drivers/video/fbdev/core/fbcon.h b/drivers/video/fbdev/core/fbcon.h
index 407d207b14f1..054cf66b15fa 100644
--- a/drivers/video/fbdev/core/fbcon.h
+++ b/drivers/video/fbdev/core/fbcon.h
@@ -202,7 +202,7 @@ extern void fbcon_set_tileops(struct vc_data *vc, struct fb_info *info);
 extern void fbcon_set_bitops_ur(struct fbcon_par *par);
 extern int  soft_cursor(struct fb_info *info, struct fb_cursor *cursor);
 
-void fbcon_fill_cursor_mask(struct fbcon_par *par, struct vc_data *vc, unsigned char *mask);
+unsigned char *fbcon_cursor_glyph(const struct vc_font *font, unsigned int cursor_type);
 
 #define FBCON_ATTRIBUTE_UNDERLINE 1
 #define FBCON_ATTRIBUTE_REVERSE   2
diff --git a/drivers/video/fbdev/core/fbcon_ccw.c b/drivers/video/fbdev/core/fbcon_ccw.c
index 33f02d579e02..9a9839631cc5 100644
--- a/drivers/video/fbdev/core/fbcon_ccw.c
+++ b/drivers/video/fbdev/core/fbcon_ccw.c
@@ -298,10 +298,9 @@ static void ccw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    par->cursor_reset) {
 		unsigned char *tmp, *mask;
 
-		tmp = kmalloc_array(vc->vc_font.height, vc_font_pitch(&vc->vc_font), GFP_ATOMIC);
+		tmp = fbcon_cursor_glyph(&vc->vc_font, vc->vc_cursor_type);
 		if (!tmp)
 			return;
-		fbcon_fill_cursor_mask(par, vc, tmp);
 
 		mask = kmalloc_array(vc->vc_font.width, w, GFP_ATOMIC);
 		if (!mask) {
diff --git a/drivers/video/fbdev/core/fbcon_cw.c b/drivers/video/fbdev/core/fbcon_cw.c
index bde820967eb9..4cb20337cf79 100644
--- a/drivers/video/fbdev/core/fbcon_cw.c
+++ b/drivers/video/fbdev/core/fbcon_cw.c
@@ -281,10 +281,9 @@ static void cw_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    par->cursor_reset) {
 		unsigned char *tmp, *mask;
 
-		tmp = kmalloc_array(vc->vc_font.height, vc_font_pitch(&vc->vc_font), GFP_ATOMIC);
+		tmp = fbcon_cursor_glyph(&vc->vc_font, vc->vc_cursor_type);
 		if (!tmp)
 			return;
-		fbcon_fill_cursor_mask(par, vc, tmp);
 
 		mask = kmalloc_array(vc->vc_font.width, w, GFP_ATOMIC);
 		if (!mask) {
diff --git a/drivers/video/fbdev/core/fbcon_ud.c b/drivers/video/fbdev/core/fbcon_ud.c
index eaf08999e249..ac22b9846b79 100644
--- a/drivers/video/fbdev/core/fbcon_ud.c
+++ b/drivers/video/fbdev/core/fbcon_ud.c
@@ -328,10 +328,9 @@ static void ud_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
 	    par->cursor_reset) {
 		unsigned char *tmp, *mask;
 
-		tmp = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
+		tmp = fbcon_cursor_glyph(&vc->vc_font, vc->vc_cursor_type);
 		if (!tmp)
 			return;
-		fbcon_fill_cursor_mask(par, vc, tmp);
 
 		mask = kmalloc_array(vc->vc_font.height, w, GFP_ATOMIC);
 		if (!mask) {
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH 2/5] vgacon: Remove trailing whitespaces
  2026-09-11  9:25 ` [PATCH 2/5] vgacon: Remove trailing whitespaces Thomas Zimmermann
@ 2026-09-11  9:46   ` sashiko-bot
  0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-11  9:46 UTC (permalink / raw)
  To: Thomas Zimmermann; +Cc: linux-serial, dri-devel

> Fix coding style.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260911094518.78093-1-tzimmermann@suse.de?part=2


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 5/5] fbcon: Replace fbcon_fill_cursor_mask() with fbcon_cursor_glyph()
  2026-09-11  9:25 ` [PATCH 5/5] fbcon: Replace fbcon_fill_cursor_mask() with fbcon_cursor_glyph() Thomas Zimmermann
@ 2026-09-11  9:50   ` sashiko-bot
  0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-11  9:50 UTC (permalink / raw)
  To: Thomas Zimmermann; +Cc: linux-serial, dri-devel

> The kernel's font library provides font_glyph_cursor() to create cursor
> glyphs. Replace fbcon's fbcon_fill_cursor_mask() with a new helper that
> uses font_glyph_cursor().
> 
> The cursor shapes remain mostly unchanged. The only exception is in
> underline cursors for fonts with a size larger than 10. The underlining
> dash is now one pixel closer to the font-glyph data, so that the cursor
> looks less detached. This follows the style used by vgacon.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260911094518.78093-1-tzimmermann@suse.de?part=5


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 4/5] lib/fonts: Add font_glyph_cursor() helper
  2026-09-11  9:25 ` [PATCH 4/5] lib/fonts: Add font_glyph_cursor() helper Thomas Zimmermann
@ 2026-09-11  9:52   ` sashiko-bot
  0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-11  9:52 UTC (permalink / raw)
  To: Thomas Zimmermann; +Cc: linux-serial, dri-devel

> The new helper font_glyph_cursor() fills a glyph with a cursor pattern.
> As with the font_glyph_rotate_*() helpers, the caller has to provide the
> output memory.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>

Sashiko has reviewed this patch and found no issues. It looks great!

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260911094518.78093-1-tzimmermann@suse.de?part=4


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/5] vt: Add cursor-size helpers
  2026-09-11  9:25 ` [PATCH 1/5] vt: Add cursor-size helpers Thomas Zimmermann
@ 2026-09-11  9:55   ` sashiko-bot
  2026-09-12 19:01   ` Helge Deller
  1 sibling, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-11  9:55 UTC (permalink / raw)
  To: Thomas Zimmermann; +Cc: dri-devel, linux-serial

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Unprotected concurrent access to the `cur_default` module parameter creates a TOCTOU race that can lead to an infinite loop.
- [Low] The kerneldoc comments inaccurately describe the fallback behavior for unknown cursor types.
--

commit 79b9bf7bbf256d349ee59d8fded428600a818ace
Author: Thomas Zimmermann <tzimmermann@suse.de>

vt: Add cursor-size helpers
    
Cursors in the VT subsystem are blocks within a character cell that are
filled with the foreground color. The new helpers vc_font_cursor_start()
and vc_font_cursor_end() return the scanlines in which the cursor block
starts rsp. ends. This is compatible with VGA hardware

> diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
> index 8f467b22b799e..87c4bc2ef4950 100644
> --- a/drivers/tty/vt/vt.c
> +++ b/drivers/tty/vt/vt.c
> @@ -264,6 +264,96 @@ unsigned int vc_font_size(const struct vc_font *font)
>  }
>  EXPORT_SYMBOL_GPL(vc_font_size);
>  
> +static unsigned int vc_cursor_start(unsigned int height, unsigned int cursor_size)
> +{
> +retry:
> +	switch (cursor_size) {
[ ... ]
> +	default:
> +		pr_warn_once("Unknown cursor %u\n", cursor_size);
> +		if (cursor_size != CUR_SIZE(cur_default))
> +			cursor_size = CUR_SIZE(cur_default);
> +		else
> +			cursor_size = CUR_UNDERLINE;
> +		goto retry;
> +	}
> +}

[Severity: Medium]
Is there a risk of an infinite loop here due to a data race on cur_default?

Since cur_default is a module parameter that can be modified concurrently,
reading it twice without READ_ONCE() inside vc_cursor_start() allows the
compiler to emit multiple memory reads.

If a concurrent thread modifies the parameter between unknown cursor sizes
(for example, switching between 7 and 8) while this function executes,
could this Time-Of-Check to Time-Of-Use race continuously trigger the goto
retry and cause a soft lockup?

> +/**
> + * vc_font_cursor_start - Calculates the cursor's first scanline within a glyph
> + * @font: The VC font
> + * @cursor_type: The type of cursor pattern
> + *
> + * The parameter @font is an initialized font. The argument in @cursor_type
> + * is one of the CUR_ constants, as stored in struct @vc_data.vc_cursor_type. For
> + * unknown values, the helper draws an underline dash.

[Severity: Low]
Does this kerneldoc accurately describe the fallback behavior?

The documentation for vc_font_cursor_start() promises an unconditional
fallback to an underline dash for unknown values, but the actual code
implementation first falls back to cur_default.

Should the documentation be updated to clarify that it first tries to use
cur_default before falling back to an underline dash?

> + *
> + * Returns:
> + * The index of the cursor's first scanline within the glyph
> + */
> +unsigned int vc_font_cursor_start(const struct vc_font *font, unsigned int cursor_type)
> +{
[ ... ]
> +static unsigned int vc_cursor_end(unsigned int height, unsigned int cursor_size)
> +{
> +retry:
> +	switch (cursor_size) {
[ ... ]
> +	default:
> +		pr_warn_once("Unknown cursor %u\n", cursor_size);
> +		if (cursor_size != CUR_SIZE(cur_default))
> +			cursor_size = CUR_SIZE(cur_default);
> +		else
> +			cursor_size = CUR_UNDERLINE;
> +		goto retry;
> +	}
> +}

[Severity: Medium]
Can this identical fallback logic also result in a soft lockup?

Just like in vc_cursor_start(), the unprotected concurrent access to
cur_default in vc_cursor_end() could potentially trap a thread in an
infinite goto retry loop if the module parameter is modified at the exact
right time.

> +/**
> + * vc_font_cursor_end - Calculates the first scanline after the cursor within a glyph
> + * @font: The VC font
> + * @cursor_type: The type of cursor pattern
> + *
> + * The parameter @font is an initialized font. The argument in @cursor_type
> + * is one of the CUR_ constants, as stored in struct @vc_data.vc_cursor_type. For
> + * unknown values, the helper draws an underline dash.

[Severity: Low]
Is this comment also missing the cur_default fallback behavior?

Similar to vc_font_cursor_start(), the comment for vc_font_cursor_end()
states it draws an underline dash for unknown values, but the code first
relies on cur_default.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260911094518.78093-1-tzimmermann@suse.de?part=1

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 3/5] vgacon: Use vt_font_cursor_{start,end}()
  2026-09-11  9:25 ` [PATCH 3/5] vgacon: Use vt_font_cursor_{start,end}() Thomas Zimmermann
@ 2026-09-11  9:58   ` sashiko-bot
  0 siblings, 0 replies; 12+ messages in thread
From: sashiko-bot @ 2026-09-11  9:58 UTC (permalink / raw)
  To: Thomas Zimmermann; +Cc: dri-devel, linux-serial

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Cursor bounds are calculated using `vc_font.height` instead of `vc_cell_height`, breaking hardware cursors when the text cell height is overridden.
--

commit 25f4b9b96dc26e69ace4c42e72c99970c3c5fcf1
Author: Thomas Zimmermann <tzimmermann@suse.de>

vgacon: Use vt_font_cursor_{start,end}()

This commit replaces vgacon's custom cursor size calculations with the shared
helpers vc_font_cursor_start() and vc_font_cursor_end(). It subtracts one
from the end value to account for VGA hardware expectations.

> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index 536e7fe4d1426..b16ddb1b09a70 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c

[ ... ]

> @@ -524,33 +525,8 @@ static void vgacon_cursor(struct vc_data *c, bool enable)
>  		return;
>  	}
>  
> -	switch (CUR_SIZE(c->vc_cursor_type)) {

[ ... ]

> -	default:
> -		vgacon_set_cursor_size(1, c_height);
> -		break;
> -	}
> +	vgacon_set_cursor_size(vc_font_cursor_start(&c->vc_font, c_type),
> +			       vc_font_cursor_end(&c->vc_font, c_type) - 1);

[Severity: High]
Does this code break the hardware cursor when the character cell height is
dynamically overridden?

If a user space utility like SVGATextMode calls the VT_RESIZEX ioctl with a
smaller v_clin, c->vc_cell_height is updated while c->vc_font.height remains
unchanged. 

By computing the cursor bounds using the static font height via the shared
helpers instead of the active character cell height, it seems the programmed
start scanline could exceed the maximum scanline of the character cell
(VGA_CRTC_MAX_SCAN). 

Since the hardware scanline counter resets before reaching the programmed cursor
start line, would this cause the hardware cursor to become completely invisible?

>  }
>  
>  static void vgacon_doresize(struct vc_data *c,

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260911094518.78093-1-tzimmermann@suse.de?part=3

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH 1/5] vt: Add cursor-size helpers
  2026-09-11  9:25 ` [PATCH 1/5] vt: Add cursor-size helpers Thomas Zimmermann
  2026-09-11  9:55   ` sashiko-bot
@ 2026-09-12 19:01   ` Helge Deller
  1 sibling, 0 replies; 12+ messages in thread
From: Helge Deller @ 2026-09-12 19:01 UTC (permalink / raw)
  To: Thomas Zimmermann, gregkh, jirislaby, simona
  Cc: linux-fbdev, dri-devel, linux-serial, sashiko-reviews

On 9/11/26 11:25, Thomas Zimmermann wrote:
> Cursors in the VT subsystem are blocks within a character cell that are
> filled with the foreground color. The new helpers vc_font_cursor_start()
> and vc_font_cursor_end() return the scanlines in which the cursor block
> starts rsp. ends. This is compatible with VGA hardware
> 
> In terms of cursor design, the new cursor-size helpers follow established
> styles in fbcon. The only exception is in underline cursors for fonts with
> a size larger than 10. The underlining dash is now one pixel closer to
> the font-glyph data, so that the cursor looks less detached. This follows
> the style used by vgacon.
> 
> Similar code in vgacon and fbcon ignores the cursor's default size stored
> in vt.cur_default. The consoles default to full-block cursors, while vt
> defaults to underline cursors. The new helper fall back to cur_default and
> then underline cursors; in this order.
> 
> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> ---
>   drivers/tty/vt/vt.c            | 90 ++++++++++++++++++++++++++++++++++
>   include/linux/console_struct.h |  2 +
>   2 files changed, 92 insertions(+)
You may add
Reviewed-by: Helge Deller <deller@gmx.de>
to the whole series.

Thanks!
Helge

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-09-12 19:01 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-11  9:25 [PATCH 0/5] fbcon,vgacon,vt: Share helpers for text cursors Thomas Zimmermann
2026-09-11  9:25 ` [PATCH 1/5] vt: Add cursor-size helpers Thomas Zimmermann
2026-09-11  9:55   ` sashiko-bot
2026-09-12 19:01   ` Helge Deller
2026-09-11  9:25 ` [PATCH 2/5] vgacon: Remove trailing whitespaces Thomas Zimmermann
2026-09-11  9:46   ` sashiko-bot
2026-09-11  9:25 ` [PATCH 3/5] vgacon: Use vt_font_cursor_{start,end}() Thomas Zimmermann
2026-09-11  9:58   ` sashiko-bot
2026-09-11  9:25 ` [PATCH 4/5] lib/fonts: Add font_glyph_cursor() helper Thomas Zimmermann
2026-09-11  9:52   ` sashiko-bot
2026-09-11  9:25 ` [PATCH 5/5] fbcon: Replace fbcon_fill_cursor_mask() with fbcon_cursor_glyph() Thomas Zimmermann
2026-09-11  9:50   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox