2024-02-15 15:39:17

by Alexey Gladkov

[permalink] [raw]
Subject: [RFC PATCH v1 0/5] VT: Add ability to get font requirements

We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
loaded. No console driver supports tall fonts. Unfortunately, userspace
cannot distinguish the lack of support in the driver from errors in the
font itself. In all cases, EINVAL will be returned.

How about adding another operator to get the supported font size so that
userspace can handle this situation correctly?

I mean something like this proof-of-concept.

---

Alexey Gladkov (5):
VT: Add KD_FONT_OP_GET_INFO operation
newport_con: Allow to get max font width and height
sticon: Allow to get max font width and height
vgacon: Allow to get max font width and height
fbcon: Allow to get max font width and height

drivers/tty/vt/vt.c | 27 +++++++++++++++++++++++++++
drivers/tty/vt/vt_ioctl.c | 2 +-
drivers/video/console/newport_con.c | 21 +++++++++++++++++----
drivers/video/console/sticon.c | 21 +++++++++++++++++++--
drivers/video/console/vgacon.c | 17 ++++++++++++++++-
drivers/video/fbdev/core/fbcon.c | 18 +++++++++++++++++-
include/linux/console.h | 1 +
include/uapi/linux/kd.h | 1 +
8 files changed, 99 insertions(+), 9 deletions(-)

--
2.43.0



2024-02-15 15:39:44

by Alexey Gladkov

[permalink] [raw]
Subject: [RFC PATCH v1 4/5] vgacon: Allow to get max font width and height

Signed-off-by: Alexey Gladkov <[email protected]>
---
drivers/video/console/vgacon.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 8ef1579fa57f..a499a469df4d 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -61,6 +61,10 @@ static struct vgastate vgastate;
#define BLANK 0x0020

#define VGA_FONTWIDTH 8 /* VGA does not support fontwidths != 8 */
+
+#define VGACON_MAX_FONT_WIDTH VGA_FONTWIDTH
+#define VGACON_MAX_FONT_HEIGHT 32
+
/*
* Interface used by the world
*/
@@ -1013,6 +1017,15 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight)
return 0;
}

+static int vgacon_font_info(struct vc_data *vc, struct console_font *font)
+{
+ font->width = VGACON_MAX_FONT_WIDTH;
+ font->height = VGACON_MAX_FONT_HEIGHT;
+ font->charcount = 512;
+
+ return 0;
+}
+
static int vgacon_font_set(struct vc_data *c, struct console_font *font,
unsigned int vpitch, unsigned int flags)
{
@@ -1022,7 +1035,8 @@ 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 || font->height > 32 || vpitch != 32 ||
+ if (font->width != VGACON_MAX_FONT_WIDTH ||
+ font->height > VGACON_MAX_FONT_HEIGHT || vpitch != 32 ||
(charcount != 256 && charcount != 512))
return -EINVAL;

@@ -1177,6 +1191,7 @@ const struct consw vga_con = {
.con_scroll = vgacon_scroll,
.con_switch = vgacon_switch,
.con_blank = vgacon_blank,
+ .con_font_info = vgacon_font_info,
.con_font_set = vgacon_font_set,
.con_font_get = vgacon_font_get,
.con_resize = vgacon_resize,
--
2.43.0


2024-02-15 15:42:55

by Alexey Gladkov

[permalink] [raw]
Subject: [RFC PATCH v1 3/5] sticon: Allow to get max font width and height

Signed-off-by: Alexey Gladkov <[email protected]>
---
drivers/video/console/sticon.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 992a4fa431aa..63368b3ff9c5 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -56,6 +56,11 @@
#define BLANK 0
static int vga_is_gfx;

+#define STICON_MIN_FONT_WIDTH 6
+#define STICON_MIN_FONT_HEIGHT 6
+#define STICON_MAX_FONT_WIDTH 32
+#define STICON_MAX_FONT_HEIGHT 32
+
#define STI_DEF_FONT sticon_sti->font

/* borrowed from fbcon.c */
@@ -180,8 +185,10 @@ static int sticon_set_font(struct vc_data *vc, struct console_font *op,
struct sti_cooked_font *cooked_font;
unsigned char *data = op->data, *p;

- if ((w < 6) || (h < 6) || (w > 32) || (h > 32) || (vpitch != 32)
- || (op->charcount != 256 && op->charcount != 512))
+ if ((w < STICON_MIN_FONT_WIDTH) || (h < STICON_MIN_FONT_HEIGHT) ||
+ (w > STICON_MAX_FONT_WIDTH) || (h > STICON_MAX_FONT_HEIGHT) ||
+ (vpitch != 32) ||
+ (op->charcount != 256 && op->charcount != 512))
return -EINVAL;
pitch = ALIGN(w, 8) / 8;
bpc = pitch * h;
@@ -273,6 +280,15 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font,
return sticon_set_font(vc, font, vpitch);
}

+static int sticon_font_info(struct vc_data *vc, struct console_font *font)
+{
+ font->width = STICON_MAX_FONT_WIDTH;
+ font->height = STICON_MAX_FONT_HEIGHT;
+ font->charcount = 512;
+
+ return 0;
+}
+
static void sticon_init(struct vc_data *c, int init)
{
struct sti_struct *sti = sticon_sti;
@@ -371,6 +387,7 @@ static const struct consw sti_con = {
.con_scroll = sticon_scroll,
.con_switch = sticon_switch,
.con_blank = sticon_blank,
+ .con_font_info = sticon_font_info,
.con_font_set = sticon_font_set,
.con_font_default = sticon_font_default,
.con_build_attr = sticon_build_attr,
--
2.43.0


2024-02-16 07:10:27

by Jiri Slaby

[permalink] [raw]
Subject: Re: [RFC PATCH v1 3/5] sticon: Allow to get max font width and height

On 15. 02. 24, 16:37, Alexey Gladkov wrote:
> Signed-off-by: Alexey Gladkov <[email protected]>
> ---
> drivers/video/console/sticon.c | 21 +++++++++++++++++++--
> 1 file changed, 19 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
> index 992a4fa431aa..63368b3ff9c5 100644
> --- a/drivers/video/console/sticon.c
> +++ b/drivers/video/console/sticon.c
> @@ -56,6 +56,11 @@
> #define BLANK 0
> static int vga_is_gfx;
>
> +#define STICON_MIN_FONT_WIDTH 6
> +#define STICON_MIN_FONT_HEIGHT 6
> +#define STICON_MAX_FONT_WIDTH 32
> +#define STICON_MAX_FONT_HEIGHT 32
> +
> #define STI_DEF_FONT sticon_sti->font
>
> /* borrowed from fbcon.c */
> @@ -180,8 +185,10 @@ static int sticon_set_font(struct vc_data *vc, struct console_font *op,
> struct sti_cooked_font *cooked_font;
> unsigned char *data = op->data, *p;
>
> - if ((w < 6) || (h < 6) || (w > 32) || (h > 32) || (vpitch != 32)
> - || (op->charcount != 256 && op->charcount != 512))
> + if ((w < STICON_MIN_FONT_WIDTH) || (h < STICON_MIN_FONT_HEIGHT) ||
> + (w > STICON_MAX_FONT_WIDTH) || (h > STICON_MAX_FONT_HEIGHT) ||

Will
!in_range(w, STICON_MIN_FONT_WIDTH, STICON_MAX_FONT_WIDTH)
look better?

> + (vpitch != 32) ||
> + (op->charcount != 256 && op->charcount != 512))
> return -EINVAL;
> pitch = ALIGN(w, 8) / 8;
> bpc = pitch * h;
> @@ -273,6 +280,15 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font,
> return sticon_set_font(vc, font, vpitch);
> }
>
> +static int sticon_font_info(struct vc_data *vc, struct console_font *font)
> +{
> + font->width = STICON_MAX_FONT_WIDTH;
> + font->height = STICON_MAX_FONT_HEIGHT;
> + font->charcount = 512;

Why not to have a macro for this constant?

> +
> + return 0;
> +}
> +
> static void sticon_init(struct vc_data *c, int init)
> {
> struct sti_struct *sti = sticon_sti;
> @@ -371,6 +387,7 @@ static const struct consw sti_con = {
> .con_scroll = sticon_scroll,
> .con_switch = sticon_switch,
> .con_blank = sticon_blank,
> + .con_font_info = sticon_font_info,
> .con_font_set = sticon_font_set,
> .con_font_default = sticon_font_default,
> .con_build_attr = sticon_build_attr,

--
js
suse labs


2024-02-16 07:22:02

by Jiri Slaby

[permalink] [raw]
Subject: Re: [RFC PATCH v1 0/5] VT: Add ability to get font requirements

On 15. 02. 24, 16:37, Alexey Gladkov wrote:
> We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
> loaded. No console driver supports tall fonts.

I thought fbcon can, no? If not, we should likely remove all the
KD_FONT_OP_SET_TALL checks here and there.

> Unfortunately, userspace
> cannot distinguish the lack of support in the driver from errors in the
> font itself. In all cases, EINVAL will be returned.

Yeah, AFAIR userspace just tries many possibilities and sees what trial
worked.

> How about adding another operator to get the supported font size so that
> userspace can handle this situation correctly?

The whole font interface is horrid (and we got rid of v1 interface only
recently). Like (ab)using height = vpitch in KD_FONT_OP_SET_TALL :(.

So perhaps, as a band-aid, this might be fine (note you give no
opportunity to find out supported vpitch for example). Eventually, we
need to invent a v3 interface with some better font_op struct with
reserved fields for future use and so on.

> I mean something like this proof-of-concept.
>
> ---
>
> Alexey Gladkov (5):
> VT: Add KD_FONT_OP_GET_INFO operation
> newport_con: Allow to get max font width and height
> sticon: Allow to get max font width and height
> vgacon: Allow to get max font width and height
> fbcon: Allow to get max font width and height
>
> drivers/tty/vt/vt.c | 27 +++++++++++++++++++++++++++
> drivers/tty/vt/vt_ioctl.c | 2 +-
> drivers/video/console/newport_con.c | 21 +++++++++++++++++----
> drivers/video/console/sticon.c | 21 +++++++++++++++++++--
> drivers/video/console/vgacon.c | 17 ++++++++++++++++-
> drivers/video/fbdev/core/fbcon.c | 18 +++++++++++++++++-
> include/linux/console.h | 1 +
> include/uapi/linux/kd.h | 1 +
> 8 files changed, 99 insertions(+), 9 deletions(-)
>

--
js
suse labs


2024-02-16 13:03:39

by Alexey Gladkov

[permalink] [raw]
Subject: Re: [RFC PATCH v1 3/5] sticon: Allow to get max font width and height

On Fri, Feb 16, 2024 at 08:10:15AM +0100, Jiri Slaby wrote:
> On 15. 02. 24, 16:37, Alexey Gladkov wrote:
> > Signed-off-by: Alexey Gladkov <[email protected]>
> > ---
> > drivers/video/console/sticon.c | 21 +++++++++++++++++++--
> > 1 file changed, 19 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
> > index 992a4fa431aa..63368b3ff9c5 100644
> > --- a/drivers/video/console/sticon.c
> > +++ b/drivers/video/console/sticon.c
> > @@ -56,6 +56,11 @@
> > #define BLANK 0
> > static int vga_is_gfx;
> >
> > +#define STICON_MIN_FONT_WIDTH 6
> > +#define STICON_MIN_FONT_HEIGHT 6
> > +#define STICON_MAX_FONT_WIDTH 32
> > +#define STICON_MAX_FONT_HEIGHT 32
> > +
> > #define STI_DEF_FONT sticon_sti->font
> >
> > /* borrowed from fbcon.c */
> > @@ -180,8 +185,10 @@ static int sticon_set_font(struct vc_data *vc, struct console_font *op,
> > struct sti_cooked_font *cooked_font;
> > unsigned char *data = op->data, *p;
> >
> > - if ((w < 6) || (h < 6) || (w > 32) || (h > 32) || (vpitch != 32)
> > - || (op->charcount != 256 && op->charcount != 512))
> > + if ((w < STICON_MIN_FONT_WIDTH) || (h < STICON_MIN_FONT_HEIGHT) ||
> > + (w > STICON_MAX_FONT_WIDTH) || (h > STICON_MAX_FONT_HEIGHT) ||
>
> Will
> !in_range(w, STICON_MIN_FONT_WIDTH, STICON_MAX_FONT_WIDTH)
> look better?

Sure! Much better. I made this patch to illustrate what I mean. I will
finish it if you find the idea itself acceptable.

> > + (vpitch != 32) ||
> > + (op->charcount != 256 && op->charcount != 512))
> > return -EINVAL;
> > pitch = ALIGN(w, 8) / 8;
> > bpc = pitch * h;
> > @@ -273,6 +280,15 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font,
> > return sticon_set_font(vc, font, vpitch);
> > }
> >
> > +static int sticon_font_info(struct vc_data *vc, struct console_font *font)
> > +{
> > + font->width = STICON_MAX_FONT_WIDTH;
> > + font->height = STICON_MAX_FONT_HEIGHT;
> > + font->charcount = 512;
>
> Why not to have a macro for this constant?

Because I don’t know how to correctly transfer this limit to userspace.
I mean, we have the code:

if (op->charcount != 256 && op->charcount != 512)
return -EINVAL;

So 512 is not exactly the maximum number of glyphs. And such checks in the
code begin to look very strange.

if (op->charcount != 256 && op->charcount != STICON_MAX_FONT_GLYPHS)
return -EINVAL;

So I decided not to give the value 512 a name.

In fact, I think this should be passed to userspace as a binary flag.
Something like this:

struct console_font_info {
unsigned int min_width, min_height;
unsigned int max_width, max_height;
unsigned int fnt_flags;
}

enum console_font_flags {
FNT_FLAG_LOW_SIZE = 1U << 0, // 256
FNT_FLAG_HIGH_SIZE = 1U << 1, // 512
};

> > +
> > + return 0;
> > +}
> > +
> > static void sticon_init(struct vc_data *c, int init)
> > {
> > struct sti_struct *sti = sticon_sti;
> > @@ -371,6 +387,7 @@ static const struct consw sti_con = {
> > .con_scroll = sticon_scroll,
> > .con_switch = sticon_switch,
> > .con_blank = sticon_blank,
> > + .con_font_info = sticon_font_info,
> > .con_font_set = sticon_font_set,
> > .con_font_default = sticon_font_default,
> > .con_build_attr = sticon_build_attr,
>
> --
> js
> suse labs
>

--
Rgrds, legion


2024-02-16 13:26:51

by Alexey Gladkov

[permalink] [raw]
Subject: Re: [RFC PATCH v1 0/5] VT: Add ability to get font requirements

On Fri, Feb 16, 2024 at 08:21:38AM +0100, Jiri Slaby wrote:
> On 15. 02. 24, 16:37, Alexey Gladkov wrote:
> > We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
> > loaded. No console driver supports tall fonts.
>
> I thought fbcon can, no? If not, we should likely remove all the
> KD_FONT_OP_SET_TALL checks here and there.

I thought so too until kbd users started trying to use such fonts. A month
after adding KD_FONT_OP_SET_TALL, support for large fonts was turned off
in fbcon:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=2b09d5d364986f724f17001ccfe4126b9b43a0be

But I don't think we need to remove KD_FONT_OP_SET_TALL completely. Maybe
support for large fonts can be fixed.

I suggested GET_INFO to solve the problem in general. Even if there is no
SET_TALL, the problem still remains. For example newport only supports
8x16 fonts.

> > Unfortunately, userspace
> > cannot distinguish the lack of support in the driver from errors in the
> > font itself. In all cases, EINVAL will be returned.
>
> Yeah, AFAIR userspace just tries many possibilities and sees what trial
> worked.

Yep. In case of big font, I don’t know how to improve the error message in
setfont. The EINVAL is very confusing for users.

> > How about adding another operator to get the supported font size so that
> > userspace can handle this situation correctly?
>
> The whole font interface is horrid (and we got rid of v1 interface only
> recently). Like (ab)using height = vpitch in KD_FONT_OP_SET_TALL :(.

Yep.

> So perhaps, as a band-aid, this might be fine (note you give no
> opportunity to find out supported vpitch for example).

The vpitch can be 32 or if the height is greater, then vpitch = fnt_height

> Eventually, we need to invent a v3 interface with some better font_op
> struct with reserved fields for future use and so on.

Yes, yes, yes! Can we discuss this, pleeeeese? :)

>
> > I mean something like this proof-of-concept.
> >
> > ---
> >
> > Alexey Gladkov (5):
> > VT: Add KD_FONT_OP_GET_INFO operation
> > newport_con: Allow to get max font width and height
> > sticon: Allow to get max font width and height
> > vgacon: Allow to get max font width and height
> > fbcon: Allow to get max font width and height
> >
> > drivers/tty/vt/vt.c | 27 +++++++++++++++++++++++++++
> > drivers/tty/vt/vt_ioctl.c | 2 +-
> > drivers/video/console/newport_con.c | 21 +++++++++++++++++----
> > drivers/video/console/sticon.c | 21 +++++++++++++++++++--
> > drivers/video/console/vgacon.c | 17 ++++++++++++++++-
> > drivers/video/fbdev/core/fbcon.c | 18 +++++++++++++++++-
> > include/linux/console.h | 1 +
> > include/uapi/linux/kd.h | 1 +
> > 8 files changed, 99 insertions(+), 9 deletions(-)
> >
>
> --
> js
> suse labs
>

--
Rgrds, legion


2024-02-16 13:46:40

by Samuel Thibault

[permalink] [raw]
Subject: Re: [RFC PATCH v1 0/5] VT: Add ability to get font requirements

Alexey Gladkov, le ven. 16 févr. 2024 14:26:38 +0100, a ecrit:
> On Fri, Feb 16, 2024 at 08:21:38AM +0100, Jiri Slaby wrote:
> > On 15. 02. 24, 16:37, Alexey Gladkov wrote:
> > > We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
> > > loaded. No console driver supports tall fonts.
> >
> > I thought fbcon can, no? If not, we should likely remove all the
> > KD_FONT_OP_SET_TALL checks here and there.
>
> I thought so too until kbd users started trying to use such fonts. A month
> after adding KD_FONT_OP_SET_TALL, support for large fonts was turned off
> in fbcon:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=2b09d5d364986f724f17001ccfe4126b9b43a0be
>
> But I don't think we need to remove KD_FONT_OP_SET_TALL completely. Maybe
> support for large fonts can be fixed.

Some users *need* it to be fixed, because they need large fonts to be
able to read their screen.

Samuel

2024-02-16 14:41:46

by Alexey Gladkov

[permalink] [raw]
Subject: Re: [RFC PATCH v1 0/5] VT: Add ability to get font requirements

On Fri, Feb 16, 2024 at 02:45:22PM +0100, Samuel Thibault wrote:
> Alexey Gladkov, le ven. 16 f?vr. 2024 14:26:38 +0100, a ecrit:
> > On Fri, Feb 16, 2024 at 08:21:38AM +0100, Jiri Slaby wrote:
> > > On 15. 02. 24, 16:37, Alexey Gladkov wrote:
> > > > We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
> > > > loaded. No console driver supports tall fonts.
> > >
> > > I thought fbcon can, no? If not, we should likely remove all the
> > > KD_FONT_OP_SET_TALL checks here and there.
> >
> > I thought so too until kbd users started trying to use such fonts. A month
> > after adding KD_FONT_OP_SET_TALL, support for large fonts was turned off
> > in fbcon:
> >
> > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=2b09d5d364986f724f17001ccfe4126b9b43a0be
> >
> > But I don't think we need to remove KD_FONT_OP_SET_TALL completely. Maybe
> > support for large fonts can be fixed.
>
> Some users *need* it to be fixed, because they need large fonts to be
> able to read their screen.

I totally understand that. That's why I don't think it's necessary to
remove or block SET_TALL. And that's also why I added you to the thread.

--
Rgrds, legion


2024-02-21 07:04:22

by Jiri Slaby

[permalink] [raw]
Subject: Re: [RFC PATCH v1 0/5] VT: Add ability to get font requirements

Cc Thomas (fbdev/fbcon fadeaway -- search SUSE below)

On 16. 02. 24, 14:26, Alexey Gladkov wrote:
> On Fri, Feb 16, 2024 at 08:21:38AM +0100, Jiri Slaby wrote:
>> On 15. 02. 24, 16:37, Alexey Gladkov wrote:
>>> We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
>>> loaded. No console driver supports tall fonts.
>>
>> I thought fbcon can, no? If not, we should likely remove all the
>> KD_FONT_OP_SET_TALL checks here and there.
>
> I thought so too until kbd users started trying to use such fonts. A month
> after adding KD_FONT_OP_SET_TALL, support for large fonts was turned off
> in fbcon:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?h=2b09d5d364986f724f17001ccfe4126b9b43a0be

Hmmm -- it has been a year!

> But I don't think we need to remove KD_FONT_OP_SET_TALL completely. Maybe
> support for large fonts can be fixed.

Either someone needs it so (not necessarily the same) someone fixes it,
or we remove it.

Note that this whole fbdev is deprecated in favor of (simple)drm. I
wonder if we want to invest any time to fix this mess at all? Or we
simply drop the defunct parts now.

I believe SUSE and Fedora (and others very likely too) are currently in
the process of moving away from fbdev completely at last. I don't know
the current state, though. Thomas?

>> Eventually, we need to invent a v3 interface with some better font_op
>> struct with reserved fields for future use and so on.
>
> Yes, yes, yes! Can we discuss this, pleeeeese? :)

You need not discuss at first, propose something ;).

thanks,
--
js
suse labs


2024-02-26 15:25:27

by Alexey Gladkov

[permalink] [raw]
Subject: [RFC PATCH v2 0/5] VT: Add ability to get font requirements

We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
loaded. No console driver supports tall fonts. Unfortunately, userspace
cannot distinguish the lack of support in the driver from errors in the
font itself. In all cases, EINVAL will be returned.

In order not to hack the KDFONTOP interface, I suggest adding a new ioctl to
obtain information about the capabilities of the console driver.

This is the second version of the patch with the fixes pointed out by Jiri
Slaby.

Previous version: https://lore.kernel.org/all/[email protected]/

---

Alexey Gladkov (5):
VT: Add KD_FONT_OP_GET_INFO operation
newport_con: Allow to get max font width and height
sticon: Allow to get max font width and height
vgacon: Allow to get max font width and height
fbcon: Allow to get max font width and height

drivers/tty/vt/vt.c | 24 ++++++++++++++++++++++++
drivers/tty/vt/vt_ioctl.c | 12 ++++++++++++
drivers/video/console/newport_con.c | 21 +++++++++++++++++----
drivers/video/console/sticon.c | 25 +++++++++++++++++++++++--
drivers/video/console/vgacon.c | 21 ++++++++++++++++++++-
drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
include/linux/console.h | 2 ++
include/linux/vt_kern.h | 1 +
include/uapi/linux/kd.h | 13 ++++++++++++-
9 files changed, 132 insertions(+), 9 deletions(-)

--
2.44.0


2024-02-26 15:23:31

by Alexey Gladkov

[permalink] [raw]
Subject: [RFC PATCH v2 5/5] fbcon: Allow to get max font width and height

Signed-off-by: Alexey Gladkov <[email protected]>
---
drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 1183e7a871f8..055d0d01243c 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -101,6 +101,9 @@ enum {
FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */
};

+#define FBCON_MAX_FONT_WIDTH 32
+#define FBCON_MAX_FONT_HEIGHT 32
+
static struct fbcon_display fb_display[MAX_NR_CONSOLES];

static struct fb_info *fbcon_registered_fb[FB_MAX];
@@ -2458,6 +2461,21 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
return ret;
}

+
+static int fbcon_font_info(struct vc_data *vc, struct console_font_info *info)
+{
+ info->min_width = 0;
+ info->min_height = 0;
+
+ info->max_width = FBCON_MAX_FONT_WIDTH;
+ info->max_height = FBCON_MAX_FONT_HEIGHT;
+
+ info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
+
+ return 0;
+}
+
+
/*
* User asked to set font; we are guaranteed that charcount does not exceed 512
* but lets not assume that, since charcount of 512 is small for unicode support.
@@ -2485,7 +2503,8 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
return -EINVAL;

- if (font->width > 32 || font->height > 32)
+ if (font->width > FBCON_MAX_FONT_WIDTH ||
+ font->height > FBCON_MAX_FONT_HEIGHT)
return -EINVAL;

/* Make sure drawing engine can handle the font */
@@ -3160,6 +3179,7 @@ static const struct consw fb_con = {
.con_scroll = fbcon_scroll,
.con_switch = fbcon_switch,
.con_blank = fbcon_blank,
+ .con_font_info = fbcon_font_info,
.con_font_set = fbcon_set_font,
.con_font_get = fbcon_get_font,
.con_font_default = fbcon_set_def_font,
--
2.44.0


2024-03-12 14:24:21

by Alexey Gladkov

[permalink] [raw]
Subject: [PATCH v3 0/2] VT: Add ability to get font requirements

From: Alexey Gladkov <[email protected]>

We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
loaded. No console driver supports tall fonts. Unfortunately, userspace
cannot distinguish the lack of support in the driver from errors in the
font itself. In all cases, EINVAL will be returned.

This patchset adds a separate ioctl to obtain the font parameters
supported by the console driver.

v3:
* Added the use of the in_range macro.
* Squashed the commits that add ioctl to console divers.

v2:
* Instead of the KDFONTOP extension, a new ioctl has been added to
obtain font information.

---

Alexey Gladkov (2):
VT: Add KDFONTINFO ioctl
VT: Allow to get max font width and height

drivers/tty/vt/vt.c | 24 ++++++++++++++++++++++++
drivers/tty/vt/vt_ioctl.c | 13 +++++++++++++
drivers/video/console/newport_con.c | 21 +++++++++++++++++----
drivers/video/console/sticon.c | 25 +++++++++++++++++++++++--
drivers/video/console/vgacon.c | 21 ++++++++++++++++++++-
drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
include/linux/console.h | 2 ++
include/linux/vt_kern.h | 1 +
include/uapi/linux/kd.h | 13 ++++++++++++-
9 files changed, 133 insertions(+), 9 deletions(-)

--
2.44.0


2024-03-12 14:24:36

by Alexey Gladkov

[permalink] [raw]
Subject: [PATCH v3 1/2] VT: Add KDFONTINFO ioctl

From: Alexey Gladkov <[email protected]>

Each driver has its own restrictions on font size. There is currently no
way to understand what the requirements are. The new ioctl allows
userspace to get the minmum and maximum font size values.

Signed-off-by: Alexey Gladkov <[email protected]>
---
drivers/tty/vt/vt.c | 24 ++++++++++++++++++++++++
drivers/tty/vt/vt_ioctl.c | 13 +++++++++++++
include/linux/console.h | 2 ++
include/linux/vt_kern.h | 1 +
include/uapi/linux/kd.h | 13 ++++++++++++-
5 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 156efda7c80d..8c2a3d98b5ec 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4680,6 +4680,30 @@ int con_font_op(struct vc_data *vc, struct console_font_op *op)
return -ENOSYS;
}

+int con_font_info(struct vc_data *vc, struct console_font_info *info)
+{
+ int rc = -EINVAL;
+
+ info->min_height = 0;
+ info->max_height = max_font_height;
+
+ info->min_width = 0;
+ info->max_width = max_font_width;
+
+ info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
+
+ console_lock();
+ if (vc->vc_mode != KD_TEXT)
+ rc = -EINVAL;
+ else if (vc->vc_sw->con_font_info)
+ rc = vc->vc_sw->con_font_info(vc, info);
+ else
+ rc = -ENOSYS;
+ console_unlock();
+
+ return rc;
+}
+
/*
* Interface exported to selection and vcs.
*/
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index 8c685b501404..b3b4e4b69366 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -479,6 +479,19 @@ static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
break;
}

+ case KDFONTINFO: {
+ struct console_font_info fnt_info;
+
+ if (copy_from_user(&fnt_info, up, sizeof(fnt_info)))
+ return -EFAULT;
+ ret = con_font_info(vc, &fnt_info);
+ if (ret)
+ return ret;
+ if (copy_to_user(up, &fnt_info, sizeof(fnt_info)))
+ return -EFAULT;
+ break;
+ }
+
default:
return -ENOIOCTLCMD;
}
diff --git a/include/linux/console.h b/include/linux/console.h
index 779d388af8a0..5bea6f6c2042 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -20,6 +20,7 @@
#include <linux/types.h>

struct vc_data;
+struct console_font_info;
struct console_font_op;
struct console_font;
struct module;
@@ -59,6 +60,7 @@ struct consw {
unsigned int lines);
int (*con_switch)(struct vc_data *vc);
int (*con_blank)(struct vc_data *vc, int blank, int mode_switch);
+ int (*con_font_info)(struct vc_data *vc, struct console_font_info *info);
int (*con_font_set)(struct vc_data *vc, struct console_font *font,
unsigned int vpitch, unsigned int flags);
int (*con_font_get)(struct vc_data *vc, struct console_font *font,
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
index c1f5aebef170..6bda4cc1fe6f 100644
--- a/include/linux/vt_kern.h
+++ b/include/linux/vt_kern.h
@@ -32,6 +32,7 @@ void do_blank_screen(int entering_gfx);
void do_unblank_screen(int leaving_gfx);
void poke_blanked_console(void);
int con_font_op(struct vc_data *vc, struct console_font_op *op);
+int con_font_info(struct vc_data *vc, struct console_font_info *info);
int con_set_cmap(unsigned char __user *cmap);
int con_get_cmap(unsigned char __user *cmap);
void scrollback(struct vc_data *vc);
diff --git a/include/uapi/linux/kd.h b/include/uapi/linux/kd.h
index 6b384065c013..781e086e55bf 100644
--- a/include/uapi/linux/kd.h
+++ b/include/uapi/linux/kd.h
@@ -183,8 +183,19 @@ struct console_font {

#define KD_FONT_FLAG_DONT_RECALC 1 /* Don't recalculate hw charcell size [compat] */

+#define KDFONTINFO 0x4B73 /* font information */
+
+#define KD_FONT_INFO_FLAG_LOW_SIZE (1U << 0) /* 256 */
+#define KD_FONT_INFO_FLAG_HIGH_SIZE (1U << 1) /* 512 */
+
+struct console_font_info {
+ unsigned int min_width, min_height; /* minimal font size */
+ unsigned int max_width, max_height; /* maximum font size */
+ unsigned int flags; /* KD_FONT_INFO_FLAG_* */
+};
+
/* note: 0x4B00-0x4B4E all have had a value at some time;
don't reuse for the time being */
-/* note: 0x4B60-0x4B6D, 0x4B70-0x4B72 used above */
+/* note: 0x4B60-0x4B6D, 0x4B70-0x4B73 used above */

#endif /* _UAPI_LINUX_KD_H */
--
2.44.0


2024-03-12 14:24:53

by Alexey Gladkov

[permalink] [raw]
Subject: [PATCH v3 2/2] VT: Allow to get max font width and height

From: Alexey Gladkov <[email protected]>

The Console drivers has more restrictive font size limits than vt_ioctl.
This leads to errors that are difficult to handle. If a font whose size
is not supported is used, an EINVAL error will be returned, which is
also returned in case of errors in the font itself. At the moment there
is no way to understand what font sizes the current console driver
supports.

To solve this problem, we need to transfer information about the
supported font to userspace from the console driver.

Signed-off-by: Alexey Gladkov <[email protected]>
---
drivers/video/console/newport_con.c | 21 +++++++++++++++++----
drivers/video/console/sticon.c | 25 +++++++++++++++++++++++--
drivers/video/console/vgacon.c | 21 ++++++++++++++++++++-
drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
4 files changed, 81 insertions(+), 8 deletions(-)

diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index e8e4f82cd4a1..87f174a95fa8 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -33,6 +33,9 @@

#define NEWPORT_LEN 0x10000

+#define NEWPORT_MAX_FONT_WIDTH 8
+#define NEWPORT_MAX_FONT_HEIGHT 16
+
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)

static unsigned char *font_data[MAX_NR_CONSOLES];
@@ -328,8 +331,8 @@ static void newport_init(struct vc_data *vc, int init)
{
int cols, rows;

- cols = newport_xsize / 8;
- rows = newport_ysize / 16;
+ cols = newport_xsize / NEWPORT_MAX_FONT_WIDTH;
+ rows = newport_ysize / NEWPORT_MAX_FONT_HEIGHT;
vc->vc_can_do_color = 1;
if (init) {
vc->vc_cols = cols;
@@ -507,8 +510,8 @@ static int newport_set_font(int unit, struct console_font *op, unsigned int vpit

/* ladis: when I grow up, there will be a day... and more sizes will
* be supported ;-) */
- if ((w != 8) || (h != 16) || (vpitch != 32)
- || (op->charcount != 256 && op->charcount != 512))
+ if ((w != NEWPORT_MAX_FONT_WIDTH) || (h != NEWPORT_MAX_FONT_HEIGHT) ||
+ (vpitch != 32) || (op->charcount != 256 && op->charcount != 512))
return -EINVAL;

if (!(new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size,
@@ -569,6 +572,15 @@ static int newport_font_default(struct vc_data *vc, struct console_font *op, cha
return newport_set_def_font(vc->vc_num, op);
}

+static int newport_font_info(struct vc_data *vc, struct console_font_info *info)
+{
+ info->min_width = info->max_width = NEWPORT_MAX_FONT_WIDTH;
+ info->min_height = info->max_height = NEWPORT_MAX_FONT_HEIGHT;
+ info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
+
+ return 0;
+}
+
static int newport_font_set(struct vc_data *vc, struct console_font *font,
unsigned int vpitch, unsigned int flags)
{
@@ -688,6 +700,7 @@ const struct consw newport_con = {
.con_scroll = newport_scroll,
.con_switch = newport_switch,
.con_blank = newport_blank,
+ .con_font_info = newport_font_info,
.con_font_set = newport_font_set,
.con_font_default = newport_font_default,
.con_save_screen = newport_save_screen
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 992a4fa431aa..d32ca458eb77 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -56,6 +56,11 @@
#define BLANK 0
static int vga_is_gfx;

+#define STICON_MIN_FONT_WIDTH 6
+#define STICON_MIN_FONT_HEIGHT 6
+#define STICON_MAX_FONT_WIDTH 32
+#define STICON_MAX_FONT_HEIGHT 32
+
#define STI_DEF_FONT sticon_sti->font

/* borrowed from fbcon.c */
@@ -180,8 +185,10 @@ static int sticon_set_font(struct vc_data *vc, struct console_font *op,
struct sti_cooked_font *cooked_font;
unsigned char *data = op->data, *p;

- if ((w < 6) || (h < 6) || (w > 32) || (h > 32) || (vpitch != 32)
- || (op->charcount != 256 && op->charcount != 512))
+ if (!in_range(w, STICON_MIN_FONT_WIDTH, STICON_MAX_FONT_WIDTH) ||
+ !in_range(h, STICON_MIN_FONT_HEIGHT, STICON_MAX_FONT_HEIGHT) ||
+ (vpitch != 32) ||
+ (op->charcount != 256 && op->charcount != 512))
return -EINVAL;
pitch = ALIGN(w, 8) / 8;
bpc = pitch * h;
@@ -273,6 +280,19 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font,
return sticon_set_font(vc, font, vpitch);
}

+static int sticon_font_info(struct vc_data *vc, struct console_font_info *info)
+{
+ info->min_width = STICON_MIN_FONT_WIDTH;
+ info->min_height = STICON_MIN_FONT_HEIGHT;
+
+ info->max_width = STICON_MAX_FONT_WIDTH;
+ info->max_height = STICON_MAX_FONT_HEIGHT;
+
+ info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
+
+ return 0;
+}
+
static void sticon_init(struct vc_data *c, int init)
{
struct sti_struct *sti = sticon_sti;
@@ -371,6 +391,7 @@ static const struct consw sti_con = {
.con_scroll = sticon_scroll,
.con_switch = sticon_switch,
.con_blank = sticon_blank,
+ .con_font_info = sticon_font_info,
.con_font_set = sticon_font_set,
.con_font_default = sticon_font_default,
.con_build_attr = sticon_build_attr,
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index 8ef1579fa57f..b75d31ef3353 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -61,6 +61,10 @@ static struct vgastate vgastate;
#define BLANK 0x0020

#define VGA_FONTWIDTH 8 /* VGA does not support fontwidths != 8 */
+
+#define VGACON_MAX_FONT_WIDTH VGA_FONTWIDTH
+#define VGACON_MAX_FONT_HEIGHT 32
+
/*
* Interface used by the world
*/
@@ -1013,6 +1017,19 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight)
return 0;
}

+static int vgacon_font_info(struct vc_data *vc, struct console_font_info *info)
+{
+ info->min_width = VGACON_MAX_FONT_WIDTH;
+ info->min_height = 0;
+
+ info->max_width = VGACON_MAX_FONT_WIDTH;
+ info->max_height = VGACON_MAX_FONT_HEIGHT;
+
+ info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
+
+ return 0;
+}
+
static int vgacon_font_set(struct vc_data *c, struct console_font *font,
unsigned int vpitch, unsigned int flags)
{
@@ -1022,7 +1039,8 @@ 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 || font->height > 32 || vpitch != 32 ||
+ if (font->width != VGACON_MAX_FONT_WIDTH ||
+ font->height > VGACON_MAX_FONT_HEIGHT || vpitch != 32 ||
(charcount != 256 && charcount != 512))
return -EINVAL;

@@ -1177,6 +1195,7 @@ const struct consw vga_con = {
.con_scroll = vgacon_scroll,
.con_switch = vgacon_switch,
.con_blank = vgacon_blank,
+ .con_font_info = vgacon_font_info,
.con_font_set = vgacon_font_set,
.con_font_get = vgacon_font_get,
.con_resize = vgacon_resize,
diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index 46823c2e2ba1..e10abe416159 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -101,6 +101,9 @@ enum {
FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */
};

+#define FBCON_MAX_FONT_WIDTH 32
+#define FBCON_MAX_FONT_HEIGHT 32
+
static struct fbcon_display fb_display[MAX_NR_CONSOLES];

static struct fb_info *fbcon_registered_fb[FB_MAX];
@@ -2456,6 +2459,21 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
return ret;
}

+
+static int fbcon_font_info(struct vc_data *vc, struct console_font_info *info)
+{
+ info->min_width = 0;
+ info->min_height = 0;
+
+ info->max_width = FBCON_MAX_FONT_WIDTH;
+ info->max_height = FBCON_MAX_FONT_HEIGHT;
+
+ info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
+
+ return 0;
+}
+
+
/*
* User asked to set font; we are guaranteed that charcount does not exceed 512
* but lets not assume that, since charcount of 512 is small for unicode support.
@@ -2483,7 +2501,8 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
return -EINVAL;

- if (font->width > 32 || font->height > 32)
+ if (font->width > FBCON_MAX_FONT_WIDTH ||
+ font->height > FBCON_MAX_FONT_HEIGHT)
return -EINVAL;

/* Make sure drawing engine can handle the font */
@@ -3158,6 +3177,7 @@ static const struct consw fb_con = {
.con_scroll = fbcon_scroll,
.con_switch = fbcon_switch,
.con_blank = fbcon_blank,
+ .con_font_info = fbcon_font_info,
.con_font_set = fbcon_set_font,
.con_font_get = fbcon_get_font,
.con_font_default = fbcon_set_def_font,
--
2.44.0


2024-03-13 18:48:45

by Oleg Bulatov

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] VT: Allow to get max font width and height

On Tue, Mar 12, 2024 at 03:23:58PM +0100, [email protected] wrote:
> drivers/video/console/newport_con.c | 21 +++++++++++++++++----
> drivers/video/console/sticon.c | 25 +++++++++++++++++++++++--
> drivers/video/console/vgacon.c | 21 ++++++++++++++++++++-
> drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
> 4 files changed, 81 insertions(+), 8 deletions(-)

newport_con.c is an interesting one, apparently it's for SGI Indy and
Indigo2, both are discontinued in 1997. Do we still have a way to test
this driver?

Oleg

2024-03-15 09:15:48

by Helge Deller

[permalink] [raw]
Subject: Re: [PATCH v3 1/2] VT: Add KDFONTINFO ioctl

On 3/12/24 15:23, [email protected] wrote:
> From: Alexey Gladkov <[email protected]>
>
> Each driver has its own restrictions on font size. There is currently no
> way to understand what the requirements are. The new ioctl allows
> userspace to get the minmum and maximum font size values.
>
> Signed-off-by: Alexey Gladkov <[email protected]>

Acked-by: Helge Deller <[email protected]>

Helge

> ---
> drivers/tty/vt/vt.c | 24 ++++++++++++++++++++++++
> drivers/tty/vt/vt_ioctl.c | 13 +++++++++++++
> include/linux/console.h | 2 ++
> include/linux/vt_kern.h | 1 +
> include/uapi/linux/kd.h | 13 ++++++++++++-
> 5 files changed, 52 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
> index 156efda7c80d..8c2a3d98b5ec 100644
> --- a/drivers/tty/vt/vt.c
> +++ b/drivers/tty/vt/vt.c
> @@ -4680,6 +4680,30 @@ int con_font_op(struct vc_data *vc, struct console_font_op *op)
> return -ENOSYS;
> }
>
> +int con_font_info(struct vc_data *vc, struct console_font_info *info)
> +{
> + int rc = -EINVAL;
> +
> + info->min_height = 0;
> + info->max_height = max_font_height;
> +
> + info->min_width = 0;
> + info->max_width = max_font_width;
> +
> + info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
> +
> + console_lock();
> + if (vc->vc_mode != KD_TEXT)
> + rc = -EINVAL;
> + else if (vc->vc_sw->con_font_info)
> + rc = vc->vc_sw->con_font_info(vc, info);
> + else
> + rc = -ENOSYS;
> + console_unlock();
> +
> + return rc;
> +}
> +
> /*
> * Interface exported to selection and vcs.
> */
> diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
> index 8c685b501404..b3b4e4b69366 100644
> --- a/drivers/tty/vt/vt_ioctl.c
> +++ b/drivers/tty/vt/vt_ioctl.c
> @@ -479,6 +479,19 @@ static int vt_k_ioctl(struct tty_struct *tty, unsigned int cmd,
> break;
> }
>
> + case KDFONTINFO: {
> + struct console_font_info fnt_info;
> +
> + if (copy_from_user(&fnt_info, up, sizeof(fnt_info)))
> + return -EFAULT;
> + ret = con_font_info(vc, &fnt_info);
> + if (ret)
> + return ret;
> + if (copy_to_user(up, &fnt_info, sizeof(fnt_info)))
> + return -EFAULT;
> + break;
> + }
> +
> default:
> return -ENOIOCTLCMD;
> }
> diff --git a/include/linux/console.h b/include/linux/console.h
> index 779d388af8a0..5bea6f6c2042 100644
> --- a/include/linux/console.h
> +++ b/include/linux/console.h
> @@ -20,6 +20,7 @@
> #include <linux/types.h>
>
> struct vc_data;
> +struct console_font_info;
> struct console_font_op;
> struct console_font;
> struct module;
> @@ -59,6 +60,7 @@ struct consw {
> unsigned int lines);
> int (*con_switch)(struct vc_data *vc);
> int (*con_blank)(struct vc_data *vc, int blank, int mode_switch);
> + int (*con_font_info)(struct vc_data *vc, struct console_font_info *info);
> int (*con_font_set)(struct vc_data *vc, struct console_font *font,
> unsigned int vpitch, unsigned int flags);
> int (*con_font_get)(struct vc_data *vc, struct console_font *font,
> diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h
> index c1f5aebef170..6bda4cc1fe6f 100644
> --- a/include/linux/vt_kern.h
> +++ b/include/linux/vt_kern.h
> @@ -32,6 +32,7 @@ void do_blank_screen(int entering_gfx);
> void do_unblank_screen(int leaving_gfx);
> void poke_blanked_console(void);
> int con_font_op(struct vc_data *vc, struct console_font_op *op);
> +int con_font_info(struct vc_data *vc, struct console_font_info *info);
> int con_set_cmap(unsigned char __user *cmap);
> int con_get_cmap(unsigned char __user *cmap);
> void scrollback(struct vc_data *vc);
> diff --git a/include/uapi/linux/kd.h b/include/uapi/linux/kd.h
> index 6b384065c013..781e086e55bf 100644
> --- a/include/uapi/linux/kd.h
> +++ b/include/uapi/linux/kd.h
> @@ -183,8 +183,19 @@ struct console_font {
>
> #define KD_FONT_FLAG_DONT_RECALC 1 /* Don't recalculate hw charcell size [compat] */
>
> +#define KDFONTINFO 0x4B73 /* font information */
> +
> +#define KD_FONT_INFO_FLAG_LOW_SIZE (1U << 0) /* 256 */
> +#define KD_FONT_INFO_FLAG_HIGH_SIZE (1U << 1) /* 512 */
> +
> +struct console_font_info {
> + unsigned int min_width, min_height; /* minimal font size */
> + unsigned int max_width, max_height; /* maximum font size */
> + unsigned int flags; /* KD_FONT_INFO_FLAG_* */
> +};
> +
> /* note: 0x4B00-0x4B4E all have had a value at some time;
> don't reuse for the time being */
> -/* note: 0x4B60-0x4B6D, 0x4B70-0x4B72 used above */
> +/* note: 0x4B60-0x4B6D, 0x4B70-0x4B73 used above */
>
> #endif /* _UAPI_LINUX_KD_H */


2024-03-15 09:16:35

by Helge Deller

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] VT: Allow to get max font width and height

On 3/12/24 15:23, [email protected] wrote:
> From: Alexey Gladkov <[email protected]>
>
> The Console drivers has more restrictive font size limits than vt_ioctl.
> This leads to errors that are difficult to handle. If a font whose size
> is not supported is used, an EINVAL error will be returned, which is
> also returned in case of errors in the font itself. At the moment there
> is no way to understand what font sizes the current console driver
> supports.
>
> To solve this problem, we need to transfer information about the
> supported font to userspace from the console driver.
>
> Signed-off-by: Alexey Gladkov <[email protected]>

Acked-by: Helge Deller <[email protected]>

Helge


> ---
> drivers/video/console/newport_con.c | 21 +++++++++++++++++----
> drivers/video/console/sticon.c | 25 +++++++++++++++++++++++--
> drivers/video/console/vgacon.c | 21 ++++++++++++++++++++-
> drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
> 4 files changed, 81 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
> index e8e4f82cd4a1..87f174a95fa8 100644
> --- a/drivers/video/console/newport_con.c
> +++ b/drivers/video/console/newport_con.c
> @@ -33,6 +33,9 @@
>
> #define NEWPORT_LEN 0x10000
>
> +#define NEWPORT_MAX_FONT_WIDTH 8
> +#define NEWPORT_MAX_FONT_HEIGHT 16
> +
> #define FONT_DATA ((unsigned char *)font_vga_8x16.data)
>
> static unsigned char *font_data[MAX_NR_CONSOLES];
> @@ -328,8 +331,8 @@ static void newport_init(struct vc_data *vc, int init)
> {
> int cols, rows;
>
> - cols = newport_xsize / 8;
> - rows = newport_ysize / 16;
> + cols = newport_xsize / NEWPORT_MAX_FONT_WIDTH;
> + rows = newport_ysize / NEWPORT_MAX_FONT_HEIGHT;
> vc->vc_can_do_color = 1;
> if (init) {
> vc->vc_cols = cols;
> @@ -507,8 +510,8 @@ static int newport_set_font(int unit, struct console_font *op, unsigned int vpit
>
> /* ladis: when I grow up, there will be a day... and more sizes will
> * be supported ;-) */
> - if ((w != 8) || (h != 16) || (vpitch != 32)
> - || (op->charcount != 256 && op->charcount != 512))
> + if ((w != NEWPORT_MAX_FONT_WIDTH) || (h != NEWPORT_MAX_FONT_HEIGHT) ||
> + (vpitch != 32) || (op->charcount != 256 && op->charcount != 512))
> return -EINVAL;
>
> if (!(new_data = kmalloc(FONT_EXTRA_WORDS * sizeof(int) + size,
> @@ -569,6 +572,15 @@ static int newport_font_default(struct vc_data *vc, struct console_font *op, cha
> return newport_set_def_font(vc->vc_num, op);
> }
>
> +static int newport_font_info(struct vc_data *vc, struct console_font_info *info)
> +{
> + info->min_width = info->max_width = NEWPORT_MAX_FONT_WIDTH;
> + info->min_height = info->max_height = NEWPORT_MAX_FONT_HEIGHT;
> + info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
> +
> + return 0;
> +}
> +
> static int newport_font_set(struct vc_data *vc, struct console_font *font,
> unsigned int vpitch, unsigned int flags)
> {
> @@ -688,6 +700,7 @@ const struct consw newport_con = {
> .con_scroll = newport_scroll,
> .con_switch = newport_switch,
> .con_blank = newport_blank,
> + .con_font_info = newport_font_info,
> .con_font_set = newport_font_set,
> .con_font_default = newport_font_default,
> .con_save_screen = newport_save_screen
> diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
> index 992a4fa431aa..d32ca458eb77 100644
> --- a/drivers/video/console/sticon.c
> +++ b/drivers/video/console/sticon.c
> @@ -56,6 +56,11 @@
> #define BLANK 0
> static int vga_is_gfx;
>
> +#define STICON_MIN_FONT_WIDTH 6
> +#define STICON_MIN_FONT_HEIGHT 6
> +#define STICON_MAX_FONT_WIDTH 32
> +#define STICON_MAX_FONT_HEIGHT 32
> +
> #define STI_DEF_FONT sticon_sti->font
>
> /* borrowed from fbcon.c */
> @@ -180,8 +185,10 @@ static int sticon_set_font(struct vc_data *vc, struct console_font *op,
> struct sti_cooked_font *cooked_font;
> unsigned char *data = op->data, *p;
>
> - if ((w < 6) || (h < 6) || (w > 32) || (h > 32) || (vpitch != 32)
> - || (op->charcount != 256 && op->charcount != 512))
> + if (!in_range(w, STICON_MIN_FONT_WIDTH, STICON_MAX_FONT_WIDTH) ||
> + !in_range(h, STICON_MIN_FONT_HEIGHT, STICON_MAX_FONT_HEIGHT) ||
> + (vpitch != 32) ||
> + (op->charcount != 256 && op->charcount != 512))
> return -EINVAL;
> pitch = ALIGN(w, 8) / 8;
> bpc = pitch * h;
> @@ -273,6 +280,19 @@ static int sticon_font_set(struct vc_data *vc, struct console_font *font,
> return sticon_set_font(vc, font, vpitch);
> }
>
> +static int sticon_font_info(struct vc_data *vc, struct console_font_info *info)
> +{
> + info->min_width = STICON_MIN_FONT_WIDTH;
> + info->min_height = STICON_MIN_FONT_HEIGHT;
> +
> + info->max_width = STICON_MAX_FONT_WIDTH;
> + info->max_height = STICON_MAX_FONT_HEIGHT;
> +
> + info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
> +
> + return 0;
> +}
> +
> static void sticon_init(struct vc_data *c, int init)
> {
> struct sti_struct *sti = sticon_sti;
> @@ -371,6 +391,7 @@ static const struct consw sti_con = {
> .con_scroll = sticon_scroll,
> .con_switch = sticon_switch,
> .con_blank = sticon_blank,
> + .con_font_info = sticon_font_info,
> .con_font_set = sticon_font_set,
> .con_font_default = sticon_font_default,
> .con_build_attr = sticon_build_attr,
> diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> index 8ef1579fa57f..b75d31ef3353 100644
> --- a/drivers/video/console/vgacon.c
> +++ b/drivers/video/console/vgacon.c
> @@ -61,6 +61,10 @@ static struct vgastate vgastate;
> #define BLANK 0x0020
>
> #define VGA_FONTWIDTH 8 /* VGA does not support fontwidths != 8 */
> +
> +#define VGACON_MAX_FONT_WIDTH VGA_FONTWIDTH
> +#define VGACON_MAX_FONT_HEIGHT 32
> +
> /*
> * Interface used by the world
> */
> @@ -1013,6 +1017,19 @@ static int vgacon_adjust_height(struct vc_data *vc, unsigned fontheight)
> return 0;
> }
>
> +static int vgacon_font_info(struct vc_data *vc, struct console_font_info *info)
> +{
> + info->min_width = VGACON_MAX_FONT_WIDTH;
> + info->min_height = 0;
> +
> + info->max_width = VGACON_MAX_FONT_WIDTH;
> + info->max_height = VGACON_MAX_FONT_HEIGHT;
> +
> + info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
> +
> + return 0;
> +}
> +
> static int vgacon_font_set(struct vc_data *c, struct console_font *font,
> unsigned int vpitch, unsigned int flags)
> {
> @@ -1022,7 +1039,8 @@ 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 || font->height > 32 || vpitch != 32 ||
> + if (font->width != VGACON_MAX_FONT_WIDTH ||
> + font->height > VGACON_MAX_FONT_HEIGHT || vpitch != 32 ||
> (charcount != 256 && charcount != 512))
> return -EINVAL;
>
> @@ -1177,6 +1195,7 @@ const struct consw vga_con = {
> .con_scroll = vgacon_scroll,
> .con_switch = vgacon_switch,
> .con_blank = vgacon_blank,
> + .con_font_info = vgacon_font_info,
> .con_font_set = vgacon_font_set,
> .con_font_get = vgacon_font_get,
> .con_resize = vgacon_resize,
> diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
> index 46823c2e2ba1..e10abe416159 100644
> --- a/drivers/video/fbdev/core/fbcon.c
> +++ b/drivers/video/fbdev/core/fbcon.c
> @@ -101,6 +101,9 @@ enum {
> FBCON_LOGO_DONTSHOW = -3 /* do not show the logo */
> };
>
> +#define FBCON_MAX_FONT_WIDTH 32
> +#define FBCON_MAX_FONT_HEIGHT 32
> +
> static struct fbcon_display fb_display[MAX_NR_CONSOLES];
>
> static struct fb_info *fbcon_registered_fb[FB_MAX];
> @@ -2456,6 +2459,21 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,
> return ret;
> }
>
> +
> +static int fbcon_font_info(struct vc_data *vc, struct console_font_info *info)
> +{
> + info->min_width = 0;
> + info->min_height = 0;
> +
> + info->max_width = FBCON_MAX_FONT_WIDTH;
> + info->max_height = FBCON_MAX_FONT_HEIGHT;
> +
> + info->flags = KD_FONT_INFO_FLAG_LOW_SIZE | KD_FONT_INFO_FLAG_HIGH_SIZE;
> +
> + return 0;
> +}
> +
> +
> /*
> * User asked to set font; we are guaranteed that charcount does not exceed 512
> * but lets not assume that, since charcount of 512 is small for unicode support.
> @@ -2483,7 +2501,8 @@ static int fbcon_set_font(struct vc_data *vc, struct console_font *font,
> h > FBCON_SWAP(info->var.rotate, info->var.yres, info->var.xres))
> return -EINVAL;
>
> - if (font->width > 32 || font->height > 32)
> + if (font->width > FBCON_MAX_FONT_WIDTH ||
> + font->height > FBCON_MAX_FONT_HEIGHT)
> return -EINVAL;
>
> /* Make sure drawing engine can handle the font */
> @@ -3158,6 +3177,7 @@ static const struct consw fb_con = {
> .con_scroll = fbcon_scroll,
> .con_switch = fbcon_switch,
> .con_blank = fbcon_blank,
> + .con_font_info = fbcon_font_info,
> .con_font_set = fbcon_set_font,
> .con_font_get = fbcon_get_font,
> .con_font_default = fbcon_set_def_font,


2024-04-02 10:42:08

by Alexey Gladkov

[permalink] [raw]
Subject: [RESEND PATCH v3 0/2] VT: Add ability to get font requirements

We now have KD_FONT_OP_SET_TALL, but in fact such large fonts cannot be
loaded. No console driver supports tall fonts. Unfortunately, userspace
cannot distinguish the lack of support in the driver from errors in the
font itself. In all cases, EINVAL will be returned.

This patchset adds a separate ioctl to obtain the font parameters
supported by the console driver.

v3:
* Added the use of the in_range macro.
* Squashed the commits that add ioctl to console divers.

v2:
* Instead of the KDFONTOP extension, a new ioctl has been added to
obtain font information.

Alexey Gladkov (2):
VT: Add KDFONTINFO ioctl
VT: Allow to get max font width and height

drivers/tty/vt/vt.c | 24 ++++++++++++++++++++++++
drivers/tty/vt/vt_ioctl.c | 13 +++++++++++++
drivers/video/console/newport_con.c | 21 +++++++++++++++++----
drivers/video/console/sticon.c | 25 +++++++++++++++++++++++--
drivers/video/console/vgacon.c | 21 ++++++++++++++++++++-
drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
include/linux/console.h | 2 ++
include/linux/vt_kern.h | 1 +
include/uapi/linux/kd.h | 13 ++++++++++++-
9 files changed, 133 insertions(+), 9 deletions(-)

--
2.44.0


2024-04-02 11:10:27

by Jiri Slaby

[permalink] [raw]
Subject: Re: [PATCH v3 2/2] VT: Allow to get max font width and height

On 13. 03. 24, 18:40, Oleg Bulatov wrote:
> On Tue, Mar 12, 2024 at 03:23:58PM +0100, [email protected] wrote:
>> drivers/video/console/newport_con.c | 21 +++++++++++++++++----
>> drivers/video/console/sticon.c | 25 +++++++++++++++++++++++--
>> drivers/video/console/vgacon.c | 21 ++++++++++++++++++++-
>> drivers/video/fbdev/core/fbcon.c | 22 +++++++++++++++++++++-
>> 4 files changed, 81 insertions(+), 8 deletions(-)
>
> newport_con.c is an interesting one, apparently it's for SGI Indy and
> Indigo2, both are discontinued in 1997. Do we still have a way to test
> this driver?

I doubt that.

Care to submit a removal patch? I am afraid, there is no other way to
find out anyway...

thanks,
--
js
suse labs