vt: Store font in struct vc_font

Replace struct console_font with struct vc_font for the type of the
vc_font field of struct vc_data. Struct console_font is UAPI, which
prevents further changes. Hence a new data type is required.

Struct console_font has a documented vertical pitch of 32 bytes. This
is not the case after the font data has been loaded into the kernel.
Changing the type of vc_font addresses this inconsistency.

The font data is now declared as constant, as it might come from the
kernel's read-only section. There's some fallout throughout the console
code where non-const variables refer to it. Fix them. A later update
will declare the font data to a dedicated data type.

v3:
- fix typos

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>
This commit is contained in:
Thomas Zimmermann
2026-03-09 15:14:45 +01:00
committed by Helge Deller
parent 982f8b002a
commit 61912c607f
4 changed files with 36 additions and 12 deletions

View File

@@ -22,8 +22,7 @@
/*
* Accelerated handlers.
*/
static void update_attr(u8 *dst, u8 *src, int attribute,
struct vc_data *vc)
static void update_attr(u8 *dst, const u8 *src, int attribute, struct vc_data *vc)
{
int i, offset = (vc->vc_font.height < 10) ? 1 : 2;
int width = DIV_ROUND_UP(vc->vc_font.width, 8);
@@ -81,7 +80,7 @@ static inline void bit_putcs_aligned(struct vc_data *vc, struct fb_info *info,
u16 charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
unsigned int charcnt = vc->vc_font.charcount;
u32 idx = vc->vc_font.width >> 3;
u8 *src;
const u8 *src;
while (cnt--) {
u16 ch = scr_readw(s++) & charmask;
@@ -120,7 +119,7 @@ static inline void bit_putcs_unaligned(struct vc_data *vc,
u32 shift_low = 0, mod = vc->vc_font.width % 8;
u32 shift_high = 8;
u32 idx = vc->vc_font.width >> 3;
u8 *src;
const u8 *src;
while (cnt--) {
u16 ch = scr_readw(s++) & charmask;
@@ -267,7 +266,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
int y = real_y(par->p, vc->state.y);
int attribute, use_sw = vc->vc_cursor_type & CUR_SW;
int err = 1;
char *src;
const u8 *src;
cursor.set = 0;
@@ -278,7 +277,7 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,
attribute = get_attribute(info, c);
src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height));
if (par->cursor_state.image.data != src ||
if (par->cursor_state.image.data != (const char *)src ||
par->cursor_reset) {
par->cursor_state.image.data = src;
cursor.set |= FB_CUR_SETIMAGE;

View File

@@ -2286,7 +2286,7 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank,
static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch)
{
u8 *fontdata = vc->vc_font.data;
const u8 *fontdata = vc->vc_font.data;
u8 *data = font->data;
int i, j;
@@ -2417,7 +2417,7 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
struct fbcon_par *par = info->fbcon_par;
struct fbcon_display *p = &fb_display[vc->vc_num];
int resize, ret, old_userfont, old_width, old_height, old_charcount;
u8 *old_data = vc->vc_font.data;
const u8 *old_data = vc->vc_font.data;
resize = (w != vc->vc_font.width) || (h != vc->vc_font.height);
vc->vc_font.data = (void *)(p->fontdata = data);

View File

@@ -82,8 +82,8 @@ struct fbcon_par {
int rotate;
int cur_rotate;
char *cursor_data;
u8 *fontbuffer;
u8 *fontdata;
u8 *fontbuffer;
const u8 *fontdata;
u8 *cursor_src;
u32 cursor_size;
u32 fd_size;

View File

@@ -13,8 +13,9 @@
#ifndef _LINUX_CONSOLE_STRUCT_H
#define _LINUX_CONSOLE_STRUCT_H
#include <linux/wait.h>
#include <linux/math.h>
#include <linux/vt.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
struct uni_pagedict;
@@ -58,6 +59,30 @@ struct vc_state {
bool reverse;
};
/**
* struct vc_font - Describes a font
* @width: The width of a single glyph in bits
* @height: The height of a single glyph in scanlines
* @charcount: The number of glyphs in the font
* @data: The raw font data
*
* Font data is organized as an array of glyphs. Each glyph is a bitmap with
* set bits indicating the foreground color. Unset bits indicate background
* color. The fields @width and @height store a single glyph's number of
* horizontal bits and vertical scanlines. If width is not a multiple of 8,
* there are trailing bits to fill up the byte. These bits should not be drawn.
*
* The field @data points to the first glyph's first byte. The value @charcount
* gives the number of glyphs in the font. There are no empty scanlines between
* two adjacent glyphs.
*/
struct vc_font {
unsigned int width;
unsigned int height;
unsigned int charcount;
const unsigned char *data;
};
/*
* Example: vc_data of a console that was scrolled 3 lines down.
*
@@ -122,7 +147,7 @@ struct vc_data {
unsigned long vc_pos; /* Cursor address */
/* fonts */
unsigned short vc_hi_font_mask; /* [#] Attribute set for upper 256 chars of font or 0 if not supported */
struct console_font vc_font; /* Current VC font set */
struct vc_font vc_font; /* Current VC font set */
unsigned short vc_video_erase_char; /* Background erase character */
/* VT terminal data */
unsigned int vc_state; /* Escape sequence parser state */