How to install extra kernel modules in dom0?

Hi,

I’m attempting to migrate to Qubes OS and I’m encountering difficulties with fan control on my system.

Previously, on Ubuntu, I managed fan speed by loading the ec_sys kernel module using modprobe ec_sys write_support=1 and then writing specific values to /sys/kernel/debug/ec/ec0/io at specific offsets. However, Fedora kernels appear to be compiled without CONFIG_ACPI_EC_DEBUGFS=m, and the ec_sys module seems to be absent from all available kernel module packages.

I’m seeking a method to install the ec_sys kernel module in dom0. While I’ve explored Qubes resources regarding kernel modules and custom kernels, these primarily focus on domU scenarios, not dom0.

I have also considered the possibilty of writing to the EC from a domU, but I don’t think it is possible to pass the ACPI embedded controller to a domU. I’m uncertain if the EC is part of a PCI device, but I suspect it is not.

Any guidance would be greatly appreciated.

Thanks,

Rex

You can build the module in dom0 the same way as in any other Linux system e.g.:

This is a slightly different scenario because the ec_sys module does not come from a separate repo but is part of the stock kernel source code instead. Initially, I thought downloading and recompiling the entire Qubes kernel was necessary.

Fortunately, it was simpler. I could compile just the ec_sys module from the stock kernel. By leveraging the fact that domU qubes use the dom0 kernel by default, I could do the compilation within an app qube.

First I downloaded and unpacked the kernel source corresponding to my version in the work qube:

[user@work kernel]$ curl https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.9.7.tar.xz -O
[user@work kernel]$ tar xf linux-6.9.7.tar.xz
[user@work kernel]$ cd linux-6.9.7/drivers/acpi

Following the guide Building Only Kernel Modules (Out Of Tree Modules), I replaced the original Makefile with the following one:

obj-m := ec_sys.o

KDIR  := /lib/modules/$(shell uname -r)/build
PWD   := $(shell pwd)

default:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

Then I issued the make command to trigger the compilation process, which produced the following output:

make -C /lib/modules/6.9.7-1.qubes.fc37.x86_64/build M=/rw/home/user/kernel/linux-6.9.7/drivers/acpi modules
make[1]: Entering directory '/usr/lib/modules/6.9.7-1.qubes.fc37.x86_64/build'
warning: the compiler differs from the one used to build the kernel
  The kernel was built by: gcc (GCC) 12.3.1 20230508 (Red Hat 12.3.1-1)
  You are using:           gcc (GCC) 14.1.1 20240701 (Red Hat 14.1.1-7)
  CC [M]  /home/user/kernel/linux-6.9.7/drivers/acpi/ec_sys.o
  MODPOST /home/user/kernel/linux-6.9.7/drivers/acpi/Module.symvers
  CC [M]  /home/user/kernel/linux-6.9.7/drivers/acpi/ec_sys.mod.o
  LD [M]  /home/user/kernel/linux-6.9.7/drivers/acpi/ec_sys.ko
make[1]: Leaving directory '/usr/lib/modules/6.9.7-1.qubes.fc37.x86_64/build'

After this, I issued the following commands in dom0 to copy the compiled kernel module there and load it:

[user@dom0 ~]$ qvm-run --pass-io work 'cat /home/user/kernel/linux-6.9.7/drivers/acpi/ec_sys.ko' | \
  sudo tee "/lib/modules/$(uname -r)/kernel/drivers/acpi/ec_sys.ko" > /dev/null
[user@dom0 ~]$ sudo depmod -a
[user@dom0 ~]$ sudo modprobe ec_sys write_support=1

The only downside is that this will need to be done after every kernel update manually. It would be nice if the dkms systemd service automatically took care of this, but it is unclear to me how it could be applied to stock kernel modules.

1 Like