Skip to content

Commit

Permalink
VT: Bump font size limitation to 64x128 pixels
Browse files Browse the repository at this point in the history
This moves 32x32 font size limitation checking down to drivers, so that
fbcon can allow large fonts.

We still keep a limitation to 64x128 pixels so as to have a simple bounded
allocation for con_font_get and in the userland kbd tool. That glyph size
will however be enough to have 128x36 characters on a "16/9 8K display".

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Link: https://lore.kernel.org/r/20230119151935.112415738@ens-lyon.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
sthibaul authored and gregkh committed Jan 19, 2023
1 parent 24d6938 commit 05e2600
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 13 deletions.
28 changes: 16 additions & 12 deletions drivers/tty/vt/vt.c
Original file line number Diff line number Diff line change
Expand Up @@ -4523,17 +4523,20 @@ void reset_palette(struct vc_data *vc)
/*
* Font switching
*
* Currently we only support fonts up to 32 pixels wide, at a maximum height
* of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints,
* depending on width) reserved for each character which is kinda wasty, but
* this is done in order to maintain compatibility with the EGA/VGA fonts. It
* is up to the actual low-level console-driver convert data into its favorite
* format (maybe we should add a `fontoffset' field to the `display'
* structure so we won't have to convert the fontdata all the time.
* Currently we only support fonts up to 128 pixels wide, at a maximum height
* of 128 pixels. Userspace fontdata may have to be stored with 32 bytes
* (shorts/ints, depending on width) reserved for each character which is
* kinda wasty, but this is done in order to maintain compatibility with the
* EGA/VGA fonts. It is up to the actual low-level console-driver convert data
* into its favorite format (maybe we should add a `fontoffset' field to the
* `display' structure so we won't have to convert the fontdata all the time.
* /Jes
*/

#define max_font_size 65536
#define max_font_width 64
#define max_font_height 128
#define max_font_glyphs 512
#define max_font_size (max_font_glyphs*max_font_width*max_font_height)

static int con_font_get(struct vc_data *vc, struct console_font_op *op)
{
Expand All @@ -4543,7 +4546,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32;

if (op->data) {
font.data = kmalloc(max_font_size, GFP_KERNEL);
font.data = kvmalloc(max_font_size, GFP_KERNEL);
if (!font.data)
return -ENOMEM;
} else
Expand Down Expand Up @@ -4578,7 +4581,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
rc = -EFAULT;

out:
kfree(font.data);
kvfree(font.data);
return rc;
}

Expand All @@ -4593,9 +4596,10 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
return -EINVAL;
if (!op->data)
return -EINVAL;
if (op->charcount > 512)
if (op->charcount > max_font_glyphs)
return -EINVAL;
if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32)
if (op->width <= 0 || op->width > max_font_width || !op->height ||
op->height > max_font_height)
return -EINVAL;
if (vpitch < op->height)
return -EINVAL;
Expand Down
2 changes: 1 addition & 1 deletion drivers/video/console/vgacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font,
if (vga_video_type < VIDEO_TYPE_EGAM)
return -EINVAL;

if (font->width != VGA_FONTWIDTH || vpitch != 32 ||
if (font->width != VGA_FONTWIDTH || font->height > 32 || vpitch != 32 ||
(charcount != 256 && charcount != 512))
return -EINVAL;

Expand Down
2 changes: 2 additions & 0 deletions drivers/video/fbdev/core/fbcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -2279,6 +2279,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigne

font->width = vc->vc_font.width;
font->height = vc->vc_font.height;
if (font->height > vpitch)
return -ENOSPC;
font->charcount = vc->vc_hi_font_mask ? 512 : 256;
if (!font->data)
return 0;
Expand Down

0 comments on commit 05e2600

Please sign in to comment.