Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

VT: Add KD_FONT_OP_SET/GET_TALL operations

The KD_FONT_OP_SET/GET operations hardcode vpitch to be 32 pixels,
which only dates from the old VGA hardware which as asserting this.

Drivers such as fbcon however do not have such limitation, so this
introduces KD_FONT_OP_SET/GET_TALL operations, which userland can try
to use to avoid this limitation, thus opening the patch to >32 pixels
font height.

Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Link: https://lore.kernel.org/r/20230119151935.013597162@ens-lyon.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Samuel Thibault and committed by
Greg Kroah-Hartman
24d69384 ffc1e089

+18 -6
+10 -4
drivers/tty/vt/vt.c
··· 4540 4540 struct console_font font; 4541 4541 int rc = -EINVAL; 4542 4542 int c; 4543 + unsigned int vpitch = op->op == KD_FONT_OP_GET_TALL ? op->height : 32; 4543 4544 4544 4545 if (op->data) { 4545 4546 font.data = kmalloc(max_font_size, GFP_KERNEL); ··· 4553 4552 if (vc->vc_mode != KD_TEXT) 4554 4553 rc = -EINVAL; 4555 4554 else if (vc->vc_sw->con_font_get) 4556 - rc = vc->vc_sw->con_font_get(vc, &font, 32); 4555 + rc = vc->vc_sw->con_font_get(vc, &font, vpitch); 4557 4556 else 4558 4557 rc = -ENOSYS; 4559 4558 console_unlock(); ··· 4561 4560 if (rc) 4562 4561 goto out; 4563 4562 4564 - c = (font.width+7)/8 * 32 * font.charcount; 4563 + c = (font.width+7)/8 * vpitch * font.charcount; 4565 4564 4566 4565 if (op->data && font.charcount > op->charcount) 4567 4566 rc = -ENOSPC; ··· 4587 4586 struct console_font font; 4588 4587 int rc = -EINVAL; 4589 4588 int size; 4589 + unsigned int vpitch = op->op == KD_FONT_OP_SET_TALL ? op->height : 32; 4590 4590 4591 4591 if (vc->vc_mode != KD_TEXT) 4592 4592 return -EINVAL; ··· 4597 4595 return -EINVAL; 4598 4596 if (op->width <= 0 || op->width > 32 || !op->height || op->height > 32) 4599 4597 return -EINVAL; 4600 - size = (op->width+7)/8 * 32 * op->charcount; 4598 + if (vpitch < op->height) 4599 + return -EINVAL; 4600 + size = (op->width+7)/8 * vpitch * op->charcount; 4601 4601 if (size > max_font_size) 4602 4602 return -ENOSPC; 4603 4603 ··· 4617 4613 else if (vc->vc_sw->con_font_set) { 4618 4614 if (vc_is_sel(vc)) 4619 4615 clear_selection(); 4620 - rc = vc->vc_sw->con_font_set(vc, &font, 32, op->flags); 4616 + rc = vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags); 4621 4617 } else 4622 4618 rc = -ENOSYS; 4623 4619 console_unlock(); ··· 4663 4659 { 4664 4660 switch (op->op) { 4665 4661 case KD_FONT_OP_SET: 4662 + case KD_FONT_OP_SET_TALL: 4666 4663 return con_font_set(vc, op); 4667 4664 case KD_FONT_OP_GET: 4665 + case KD_FONT_OP_GET_TALL: 4668 4666 return con_font_get(vc, op); 4669 4667 case KD_FONT_OP_SET_DEFAULT: 4670 4668 return con_font_default(vc, op);
+8 -2
include/uapi/linux/kd.h
··· 161 161 unsigned int flags; /* KD_FONT_FLAG_* */ 162 162 unsigned int width, height; /* font size */ 163 163 unsigned int charcount; 164 - unsigned char __user *data; /* font data with height fixed to 32 */ 164 + unsigned char __user *data; /* font data with vpitch fixed to 32 for 165 + * KD_FONT_OP_SET/GET 166 + */ 165 167 }; 166 168 167 169 struct console_font { 168 170 unsigned int width, height; /* font size */ 169 171 unsigned int charcount; 170 - unsigned char *data; /* font data with height fixed to 32 */ 172 + unsigned char *data; /* font data with vpitch fixed to 32 for 173 + * KD_FONT_OP_SET/GET 174 + */ 171 175 }; 172 176 173 177 #define KD_FONT_OP_SET 0 /* Set font */ 174 178 #define KD_FONT_OP_GET 1 /* Get font */ 175 179 #define KD_FONT_OP_SET_DEFAULT 2 /* Set font to default, data points to name / NULL */ 176 180 #define KD_FONT_OP_COPY 3 /* Obsolete, do not use */ 181 + #define KD_FONT_OP_SET_TALL 4 /* Set font with vpitch = height */ 182 + #define KD_FONT_OP_GET_TALL 5 /* Get font with vpitch = height */ 177 183 178 184 #define KD_FONT_FLAG_DONT_RECALC 1 /* Don't recalculate hw charcell size [compat] */ 179 185