F44 Change Proposal: UseKmsconVTConsole [SystemWide]

UseKmsconVTConsole

Wiki

Announced

This is a proposed Change for Fedora Linux.
This document represents a proposed Change. As part of the Changes process, proposals are publicly announced in order to receive community feedback. This proposal will only be implemented if approved by the Fedora Engineering Steering Committee.

Summary :open_book:

This change is to replace the kernel console ‘’‘fbcon’‘’ with the userspace console ‘’‘kmscon’‘’ in Fedora, to provide an enhanced and more secure console for Fedora users.
The long term goal is also to deprecate fbcon/fbdev emulation in the kernel, and this is the first step in this direction.

Owner :open_book:

Detailed Description :open_book:

‘’‘fbcon’‘’ is a terminal emulator in the kernel, which is not well maintained (it lost scrolling support a few years ago due to a CVE), and requires a fbdev emulation layer in the kernel, as all GPU drivers are using the newer drm interface. It still requires userspace executable like getty and bash to be useful.
‘’‘kmscon’‘’ is a simple terminal emulator based on linux kernel mode setting (KMS). It can replace fbcon for VT console, and provide better keyboard support, and better security.
This change will do the following:
Install kmscon by default, and update the symbolic link /usr/lib/systemd/system/autovt@.service to point to kmsconvt@.service, to start kmscon by default when switching VT.
kmscon should be the default also on non-graphical installation, as it doesn’t require any graphic library (only libdrm, to access the framebuffer).
This change won’t affect the installation, the boot process (like encryption password fallback), as fbcon will still be compiled in the kernel.
User can still revert to fbcon if they want, or if kmscon has issue on their setup.
If kmscon fails to launch, it will fallback to getty/fbcon.
Currently kmscon depends on opengl/mesa, because it has an optional opengl backend. But we don’t want that on non-graphical server installation. I will split the package in two, having something like kmscon and kmscon-gl for the optional gl renderer.

Feedback :open_book:

Benefit to Fedora :open_book:

kmscon is more configurable, and has more features than fbcon:

Scope :open_book:

  • Proposal owners:
    ** Add kmscon in default installation target.
    ** Enable kmscon systemd service, for all tty, by changing the symbolic link /usr/lib/systemd/system/autvt@.service, to point to kmsconvt@.service
    ** Split the kmscon package in 2, to avoid direct dependencies on egl.
  • Trademark approval: N/A (not needed for this Change)
  • Alignment with the Fedora Strategy:

Upgrade/compatibility impact :open_book:

Early Testing (Optional) :open_book:

How To Test :open_book:

Press Ctrl+alt+F3 to switch to the VT console.
Login and check if it’s running kmscon with ‘‘ps aux | grep tty3’’
Check that you can scroll back with page up/page down.
Check that you can increase the font size with “ctrl +” and decrease with “ctrl -”

User Experience :open_book:

==== Improvements ====

  • The look & feel of the VT console, will be much better.
  • Users will be able to configure special fonts, and use more unicode characters.
  • Users will have the same keyboard layout has what they have in graphical environment. (Currently the kernel keyboard layout are different).
  • Users will be able to scroll in the console.
    ==== Caveats ====
  • Starting graphical application from the console (like “startx”) won’t work, but you can work around it by using the script ‘‘kmscon-launch-gui startx’’

Dependencies :open_book:

No dependencies.

Contingency Plan :open_book:

It should be easy to revert, just not install kmscon, and fbcon with getty service will be the default.

Documentation :open_book:

N/A (not a System Wide Change)

Release Notes :open_book:

Last edited by @alking 2025-11-14T13:46:54Z

Last edited by @alking 2025-11-14T13:46:54Z

4 Likes

How do you feel about the proposal as written?

  • Strongly in favor
  • In favor, with reservations
  • Neutral
  • Opposed, but could be convinced
  • Strongly opposed
0 voters

If you are in favor but have reservations, or are opposed but something could change your mind, please explain in a reply.

We want everyone to be heard, but many posts repeating the same thing actually makes that harder. If you have something new to say, please say it. If, instead, you find someone has already covered what you’d like to express, please simply give that post a :heart: instead of reiterating. You can even do this by email, by replying with the heart emoji or just “+1”. This will make long topics easier to follow.

Please note that this is an advisory “straw poll” meant to gauge sentiment. It isn’t a vote or a scientific survey. See About the Change Proposals category for more about the Change Process and moderation policy.

1 Like

I’m testing it on f43. it is running ok here on amdgpu and nvidia-open hardware.

sudo dnf install kmscon
cd /usr/lib/systemd/system/
sudo ln -sf kmsconvt@.service autovt@.service

reboot

the kmscon-launch-gui script doesn’t work with wayland compositors like gamescope or weston.
also for me with nvidia-open it consumes 100% of a cpu thread while running:

if i run setenforce 0 cpu usage drops back to normal

strace log

...
recvfrom(9, NULL, 0, MSG_PEEK|MSG_TRUNC, NULL, NULL) = -1 EACCES (PermissĂŁo negada)
epoll_wait(3, [{events=EPOLLIN, data=0x55d16dea0b20}], 32, -1) = 1
ppoll([{fd=8, events=POLLIN}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 (Timeout)
openat(AT_FDCWD, "/run/systemd/seats/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 18
fstat(18, {st_mode=S_IFDIR|0755, st_size=60, ...}) = 0
getdents64(18, 0x55d16e1ec1a0 /* 3 entries */, 32768) = 80
getdents64(18, 0x55d16e1ec1a0 /* 0 entries */, 32768) = 0
close(18)                               = 0
recvfrom(9, NULL, 0, MSG_PEEK|MSG_TRUNC, NULL, NULL) = -1 EACCES (PermissĂŁo negada)
epoll_wait(3, [{events=EPOLLIN, data=0x55d16dea0b20}], 32, -1) = 1
ppoll([{fd=8, events=POLLIN}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 (Timeout)
openat(AT_FDCWD, "/run/systemd/seats/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 18
fstat(18, {st_mode=S_IFDIR|0755, st_size=60, ...}) = 0
getdents64(18, 0x55d16e1ec1a0 /* 3 entries */, 32768) = 80
getdents64(18, 0x55d16e1ec1a0 /* 0 entries */, 32768) = 0
close(18)                               = 0
recvfrom(9, NULL, 0, MSG_PEEK|MSG_TRUNC, NULL, NULL) = -1 EACCES (PermissĂŁo negada)
epoll_wait(3, [{events=EPOLLIN, data=0x55d16dea0b20}], 32, -1) = 1
ppoll([{fd=8, events=POLLIN}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 (Timeout)
openat(AT_FDCWD, "/run/systemd/seats/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 18
fstat(18, {st_mode=S_IFDIR|0755, st_size=60, ...}) = 0
getdents64(18, 0x55d16e1ec1a0 /* 3 entries */, 32768) = 80
getdents64(18, 0x55d16e1ec1a0 /* 0 entries */, 32768) = 0
close(18)                               = 0
recvfrom(9, NULL, 0, MSG_PEEK|MSG_TRUNC, NULL, NULL) = -1 EACCES (PermissĂŁo negada)
epoll_wait(3, [{events=EPOLLIN, data=0x55d16dea0b20}], 32, -1) = 1
ppoll([{fd=8, events=POLLIN}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 (Timeout)
openat(AT_FDCWD, "/run/systemd/seats/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 18
fstat(18, {st_mode=S_IFDIR|0755, st_size=60, ...}) = 0
getdents64(18, 0x55d16e1ec1a0 /* 3 entries */, 32768) = 80
getdents64(18, 0x55d16e1ec1a0 /* 0 entries */, 32768) = 0
close(18)                               = 0
recvfrom(9, NULL, 0, MSG_PEEK|MSG_TRUNC, NULL, NULL) = -1 EACCES (PermissĂŁo negada)
epoll_wait(3, [{events=EPOLLIN, data=0x55d16dea0b20}], 32, -1) = 1
ppoll([{fd=8, events=POLLIN}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 (Timeout)
openat(AT_FDCWD, "/run/systemd/seats/", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 18
fstat(18, {st_mode=S_IFDIR|0755, st_size=60, ...}) = 0
getdents64(18, 0x55d16e1ec1a0 /* 3 entries */, 32768) = 80
getdents64(18, 0x55d16e1ec1a0 /* 0 entries */, 32768) = 0
close(18)                               = 0
recvfrom(9, NULL, 0, MSG_PEEK|MSG_TRUNC, NULL, NULL) = -1 EACCES (PermissĂŁo negada)
epoll_wait(3, [{events=EPOLLIN, data=0x55d16dea0b20}], 32, -1) = 1
ppoll([{fd=8, events=POLLIN}], 1, {tv_sec=0, tv_nsec=0}, NULL, 8) = 0 (Timeout)
openat(AT_FDCWD, "/run/systemd/seats/", 
close(18)                               = 0
...

1 Like

Regarding kmscon-launch-gui, it’s not present in the v9.1.0 release that I pushed to Fedora.
I will do a release soon, when mouse support, and a few other pending work are merged.

For the nvidia-open issue, it looks like the permission error is from file descriptor 9, can you look in your full ftrace log, which file it is?
At least with intel GPU and Xe driver, there are no permission issue when using hwaccel and gltex. So that might be something specific to nvidia.

i downloaded the kmscon-launch-gui manually to test it.

looks like its a socket:

socket create
socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC|SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT) = 9
setsockopt(9, SOL_SOCKET, SO_PASSCRED, [1], 4) = 0
bind(9, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=0x000002}, 12) = 0
getsockname(9, {sa_family=AF_NETLINK, nl_pid=53314, nl_groups=0x000002}, [12]) = 0
getsockopt(9, SOL_SOCKET, SO_RCVBUF, [212992], [4]) = 0
setsockopt(9, SOL_SOCKET, SO_RCVBUF, [134217728], 4) = 0
getsockopt(9, SOL_SOCKET, SO_RCVBUF, [425984], [4]) = 0
setsockopt(9, SOL_SOCKET, SO_RCVBUFFORCE, [134217728], 4) = 0

from the message seems related to udev:

mesage
recvfrom(9, NULL, 0, MSG_PEEK|MSG_TRUNC, NULL, NULL) = 583
recvmsg(9, {msg_name={sa_family=AF_NETLINK, nl_pid=875, nl_groups=0x000002}, msg_namelen=128 => 12, msg_iov=[{iov_base=[{prefix="libudev", magic=htonl(0xfeedcafe), header_size=40, properties_off=40, properties_len=543, filter_subsystem_hash=htonl(0x16664179), filter_devtype_hash=htonl(0x1ca6541e), filter_tag_bloom_hi=htonl(0xa1a2108), filter_tag_bloom_lo=htonl(0x601849)}, "UDEV_DATABASE_VERSION=1\0ACTION=c"...], iov_len=583}], msg_iovlen=1, msg_control=[{cmsg_len=28, cmsg_level=SOL_SOCKET, cmsg_type=SCM_CREDENTIALS, cmsg_data={pid=54069, uid=0, gid=0}}], msg_controllen=32, msg_flags=0}, 0) = 583
ls -ltr /proc/$pid/fd
lrwx------. 1 root root 64 nov 14 12:57 9 -> 'socket:[562240]'
lsof -p $pid
kmscon  55134 root    9u  netlink                         0t0  562240 KOBJECT_UEVENT

Ok, unfortunately, just copying the kmscon-launch-gui script won’t work, the script sends an OSC command to the kmscon executable, and the v9.1.0 doesn’t support that.
Sorry I should have done a release with kmscon-launch-gui before doing the change proposal.

Thanks, so it’s a socket and not a regular file. It seems to be related to nvidia gpu, as I have one system with an nvidia card, I will try to reproduce there.

Thanks

2 Likes

To ease testing of kmscon, I have made a new build in my kmscon copr repository with all the pending PR:
https://copr.fedorainfracloud.org/coprs/jfalempe/kmscon

I’ve updated the how-to-test section accordingly:
https://fedoraproject.org/wiki/Changes/UseKmsconVTConsole#How_To_Test

With the copr version, you get:

  • Screen rotation support
  • Mouse support
  • kmscon-launch-gui script
  • Better double-width character support
  • A default kmscon.conf is installed in /etc/kmscon/kmscon.conf
  • The kmscon package is split in 2, kmscon, and kmscon-gl, the later contains the plugins for drm3d, gltex and pango.
1 Like

just tested here on my x1e/snapdragon-x laptop (a lenovo slim 7x).

Everything appears to work fine, but…

PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                    

197600 root 20 0 958424 95024 58596 R 99.7 0.3 1:49.98 kmscon

kmscon seems to take 100% cpu all the time. ;(
Thats the case with both accel set or not.

Happy to provide debugging/more info.

Also mouse selection doesn’t seem to work, but I understand thats a work
in progress.

Thanks for working on all this, I am really looking forward to it.

@kevin From the prior flamegraph, if you have the same issue as @lnvso it looks related to systemd seats.

can you check that you have a seat0 configured with:
loginctl list-seats

Another thing you can try is to remove “–seats=seat0” in /usr/lib/systemd/system/kmsconvt@.service.

You will need to run sudo systemd daemon-reload && sudo systemctl restart kmsconvt@tty3 for the change to take effect.

Thanks.

@kevin From the prior flamegraph, if you have the same issue as @lnvso it looks related to systemd seats.

can you check that you have a seat0 configured with:
loginctl list-seats

SEAT
seat0

1 seats listed.

Another thing you can try is to remove “–seats=seat0” in /usr/lib/systemd/system/kmsconvt@.service.

You will need to run sudo systemd daemon-reload && sudo systemctl restart kmsconvt@tty3 for the change to take effect.

Will that do anything good if I do have a seat0? :slight_smile:

I guess this will impact all the Sway WM users as well? It is common for Sway users to skip installing a DM and launch Sway directly from the VT.[1]


  1. ↩︎

Hello, I have two systems (one Intel i915, one AMD amdgpu) which both experience the 100% CPU thread for every kmscon process.

On the AMD system it only started after I logged out.

There are other smaller issues like increasing the font size makes the upper text disappear from the screen (it doesn’t come back after decreasing the font size again, thoug you can see it in the scroll buffer), the cursor disappears after changing font size, some keys not working right (backspace prints ^H, Home and End not working inside the mcedit editor, will try changing keyboard and term configs), I can’t seem to be able to copy/paste with the mouse, etc, but these are all solvable I think.

Intel system info:

$ kinfo
Operating System: Fedora Linux 43
KDE Plasma Version: 6.5.2
KDE Frameworks Version: 6.19.0
Qt Version: 6.10.0
Kernel Version: 6.17.7-300.fc43.x86_64 (64-bit)
Graphics Platform: Wayland
Processors: 8 × Intel® Core™ i5-1035G1 CPU @ 1.00GHz
Memory: 16 GiB of RAM (15.2 GiB usable)
Graphics Processor: IntelÂŽ UHD Graphics
$ lspci -k -s 00:02.0
00:02.0 VGA compatible controller: Intel Corporation Iris Plus Graphics G1 (Ice Lake) (rev 07)
Subsystem: Lenovo Device 3fd9
Kernel driver in use: i915
Kernel modules: i915

AMD system info:

$ kinfo:
Operating System: Fedora Linux 43
KDE Plasma Version: 6.5.2
KDE Frameworks Version: 6.19.0
Qt Version: 6.10.0
Kernel Version: 6.17.8-300.fc43.x86_64 (64-bit)
Graphics Platform: Wayland
Processors: 12 × AMD Ryzen 5 5600H with Radeon Graphics
Memory: 16 GiB of RAM (15.0 GiB usable)
Graphics Processor: AMD Radeon Graphics
$ lspci -k -s 06:00.0
06:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Cezanne [Radeon Vega Series / Radeon Vega Mobile Series] (rev c6)
Subsystem: ASUSTeK Computer Inc. Device 885b
Kernel driver in use: amdgpu
Kernel modules: amdgpu

just tested the change on a fresh virtual machine with fedora 43 kde, if i boot the machine then go from sddm → kmscon the cpu usage will be fine, switching between different kmscon sessions will also be fine, but if i go from a kmscon session to sddm the cpu usage from all kmscon processes will jump to the max, running setenforce 0 still works to ‘fix’ the usage

Yes, you will need to use kmscon-launch-gui for Sway too. That’s because the kernel only allows one userspace application to be the drm master at the same time. So kmscon has to release it in order for Sway or any other graphical application to acquire it.

2 Likes

can you check if there are selinux errors:

I think the commands are:

sudo ausearch -m avc -ts recent

or

sudo grep AVC /var/log/audit/audit.log

so we will see what is missing in the selinux rules.

Yes, I can reproduce this glitches:

Upper line disappearing when increasing/decreasing the font size, and the cursor that disappear too.

I tried msedit, and home/end keys are working (I’m using dvorak us layout), but most layout won’t change those keys.

For the 100% CPU issue, that looks related to selinux, if you can check your selinux logs, and try with setenforce 0, that would help to root cause it.

Thanks for testing and for reporting your findings.

had to run semodule -DB first before getting any events logged

#ausearch -m -ts recent

time->Sat Nov 15 19:13:29 2025
type=AVC msg=audit(1763244809.103:36160): avc:  denied  { read } for  pid=3419 comm="kmscon" scontext=system_u:system_r:kmscon_t:s0 tcontext=system_u:system_r:kmscon_t:s0 tclass=netlink_kobject_uevent_socket permissive=0
#journalctl -t setroubleshoot

Nov 15 19:24:30 fedora setroubleshoot[1464]: SELinux is preventing kmscon from read access on the netlink_kobject_uevent_socket labeled kmscon_t. For complete SELinux messages run: sealert -l 4dbb6b33-7893-43ee-9468-e473925bde03
Nov 15 19:24:30 fedora setroubleshoot[1464]: SELinux is preventing kmscon from read access on the netlink_kobject_uevent_socket labeled kmscon_t.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that kmscon should be allowed read access on netlink_kobject_uevent_socket labeled kmscon_t by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'kmscon' --raw | audit2allow -M my-kmscon
# semodule -X 300 -i my-kmscon.pp
#sealert -l 4dbb6b33-7893-43ee-9468-e473925bde03
SELinux is preventing kmscon from read access on the netlink_kobject_uevent_socket labeled kmscon_t.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that kmscon should be allowed read access on netlink_kobject_uevent_socket labeled kmscon_t by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'kmscon' --raw | audit2allow -M my-kmscon
# semodule -X 300 -i my-kmscon.pp


Additional Information:
Source Context                system_u:system_r:kmscon_t:s0
Target Context                system_u:system_r:kmscon_t:s0
Target Objects                Unknown [ netlink_kobject_uevent_socket ]
Source                        kmscon
Source Path                   kmscon
Port                          <Unknown>
Host                          fedora
Source RPM Packages
Target RPM Packages
SELinux Policy RPM            selinux-policy-targeted-42.15-1.fc43.noarch
Local Policy RPM              selinux-policy-targeted-42.15-1.fc43.noarch
Selinux Enabled               True
Policy Type                   targeted
Enforcing Mode                Enforcing
Host Name                     fedora
Platform                      Linux fedora 6.17.7-300.fc43.x86_64 #1 SMP
PREEMPT_DYNAMIC Sun Nov  2 15:30:09 UTC 2025
x86_64
Alert Count                   10497
First Seen                    2025-11-15 19:23:48 -03
Last Seen                     2025-11-15 19:23:48 -03
Local ID                      4dbb6b33-7893-43ee-9468-e473925bde03

Raw Audit Messages
type=AVC msg=audit(1763245428.685:11202): avc:  denied  { read } for  pid=1396 comm="kmscon" scontext=system_u:system_r:kmscon_t:s0 tcontext=system_u:system_r:kmscon_t:s0 tclass=netlink_kobject_uevent_socket permissive=0


Hash: kmscon,kmscon_t,kmscon_t,netlink_kobject_uevent_socket,read
#ausearch -c 'kmscon' --raw | audit2why
type=AVC msg=audit(1763245447.266:26810): avc:  denied  { read } for  pid=1396 comm="kmscon" scontext=system_u:system_r:kmscon_t:s0 tcontext=system_u:system_r:kmscon_t:s0 tclass=netlink_kobject_uevent_socket permissive=0

Was caused by:
Missing type enforcement (TE) allow rule.

You can use audit2allow to generate a loadable module to allow this access.

after installing the module generated by ausearch -c 'kmscon' --raw |audit2allow, the cpu issue doesn’t happen anymore, now when switching between kmscon and a plasma session i get these 3 selinux alerts logged:

Nov 15 19:33:27 fedora setroubleshoot[1994]: SELinux is preventing polkitd from using the noatsecure access on a process. For complete SELinux messages run: sealert -l cb48ef73-2>
Nov 15 19:33:27 fedora setroubleshoot[1994]: SELinux is preventing polkitd from using the noatsecure access on a process.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that polkitd should be allowed noatsecure access on processes labeled policykit_auth_t by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'polkitd' --raw | audit2allow -M my-polkitd
# semodule -X 300 -i my-polkitd.pp

Nov 15 19:33:27 fedora setroubleshoot[1994]: SELinux is preventing pkla-check-auth from using the rlimitinh access on a process. For complete SELinux messages run: sealert -l c55>
Nov 15 19:33:27 fedora setroubleshoot[1994]: SELinux is preventing pkla-check-auth from using the rlimitinh access on a process.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that pkla-check-auth should be allowed rlimitinh access on processes labeled policykit_auth_t by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'pkla-check-auth' --raw | audit2allow -M my-pklacheckauth
# semodule -X 300 -i my-pklacheckauth.pp

Nov 15 19:33:27 fedora setroubleshoot[1994]: SELinux is preventing pkla-check-auth from using the siginh access on a process. For complete SELinux messages run: sealert -l 045220>
Nov 15 19:33:27 fedora setroubleshoot[1994]: SELinux is preventing pkla-check-auth from using the siginh access on a process.

*****  Plugin catchall (100. confidence) suggests   **************************

If you believe that pkla-check-auth should be allowed siginh access on processes labeled policykit_auth_t by default.
Then you should report this as a bug.
You can generate a local policy module to allow this access.
Do
allow this access for now by executing:
# ausearch -c 'pkla-check-auth' --raw | audit2allow -M my-pklacheckauth
# semodule -X 300 -i my-pklacheckauth.pp

but i can’t see any side effect from them

Thanks a lot for the investigation.

The netlink_kobject_uevent is already marked kmscon_t, so there is just a missing read policy for that object. I think that can be fixed quickly by the selinux team.

2 Likes