Commit 05e2600c authored by Samuel Thibault's avatar Samuel Thibault Committed by Greg Kroah-Hartman

VT: Bump font size limitation to 64x128 pixels

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: default avatarSamuel Thibault <samuel.thibault@ens-lyon.org>
Link: https://lore.kernel.org/r/20230119151935.112415738@ens-lyon.orgSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 24d69384
...@@ -4523,17 +4523,20 @@ void reset_palette(struct vc_data *vc) ...@@ -4523,17 +4523,20 @@ void reset_palette(struct vc_data *vc)
/* /*
* Font switching * Font switching
* *
* Currently we only support fonts up to 32 pixels wide, at a maximum height * Currently we only support fonts up to 128 pixels wide, at a maximum height
* of 32 pixels. Userspace fontdata is stored with 32 bytes (shorts/ints, * of 128 pixels. Userspace fontdata may have to be stored with 32 bytes
* depending on width) reserved for each character which is kinda wasty, but * (shorts/ints, depending on width) reserved for each character which is
* this is done in order to maintain compatibility with the EGA/VGA fonts. It * kinda wasty, but this is done in order to maintain compatibility with the
* is up to the actual low-level console-driver convert data into its favorite * EGA/VGA fonts. It is up to the actual low-level console-driver convert data
* format (maybe we should add a `fontoffset' field to the `display' * into its favorite format (maybe we should add a `fontoffset' field to the
* structure so we won't have to convert the fontdata all the time. * `display' structure so we won't have to convert the fontdata all the time.
* /Jes * /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) static int con_font_get(struct vc_data *vc, struct console_font_op *op)
{ {
...@@ -4543,7 +4546,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) ...@@ -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; unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32;
if (op->data) { if (op->data) {
font.data = kmalloc(max_font_size, GFP_KERNEL); font.data = kvmalloc(max_font_size, GFP_KERNEL);
if (!font.data) if (!font.data)
return -ENOMEM; return -ENOMEM;
} else } else
...@@ -4578,7 +4581,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) ...@@ -4578,7 +4581,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op)
rc = -EFAULT; rc = -EFAULT;
out: out:
kfree(font.data); kvfree(font.data);
return rc; return rc;
} }
...@@ -4593,9 +4596,10 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op) ...@@ -4593,9 +4596,10 @@ static int con_font_set(struct vc_data *vc, struct console_font_op *op)
return -EINVAL; return -EINVAL;
if (!op->data) if (!op->data)
return -EINVAL; return -EINVAL;
if (op->charcount > 512) if (op->charcount > max_font_glyphs)
return -EINVAL; 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; return -EINVAL;
if (vpitch < op->height) if (vpitch < op->height)
return -EINVAL; return -EINVAL;
......
...@@ -1037,7 +1037,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font, ...@@ -1037,7 +1037,7 @@ static int vgacon_font_set(struct vc_data *c, struct console_font *font,
if (vga_video_type < VIDEO_TYPE_EGAM) if (vga_video_type < VIDEO_TYPE_EGAM)
return -EINVAL; return -EINVAL;
if (font->width != VGA_FONTWIDTH || vpitch != 32 || if (font->width != VGA_FONTWIDTH || font->height > 32 || vpitch != 32 ||
(charcount != 256 && charcount != 512)) (charcount != 256 && charcount != 512))
return -EINVAL; return -EINVAL;
......
...@@ -2279,6 +2279,8 @@ static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigne ...@@ -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->width = vc->vc_font.width;
font->height = vc->vc_font.height; font->height = vc->vc_font.height;
if (font->height > vpitch)
return -ENOSPC;
font->charcount = vc->vc_hi_font_mask ? 512 : 256; font->charcount = vc->vc_hi_font_mask ? 512 : 256;
if (!font->data) if (!font->data)
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment