1

I'm facing an issue with Thunderbolt on a Lenovo Yoga X1 Gen8 in conjunction with the Lenovo Thunderbolt 3 Dock (40AN, Gen 2) when using Ubuntu 24.

On my older HP ProBook 450 G6 (with only USB 3.2 support, no Thunderbolt), the dock works fine in initramfs/plymouth while entering the LUKS passphrase. However, on the Lenovo Yoga X1 Gen8 it does not - which hinders me to use the 1-cable docking solution as I can not type in my password without modifying the setup, f.e. connecting the Keyboard directly to the laptop. -> Side note: I just swapped the SSD of my old machine into the new machine yesterday, so it is the exact same installation that is starting and causing this behavior.

During initramfs boot, Thunderbolt is recognized, but devices connected to the dock (monitors, keyboard) "fail" to work. The keyboard's backlight even turns off at this stage, which is why I assume they are turned off on purpose by some policy.

Pre-boot environments (UEFI and GRUB) recognize the dock as a USB device, initializing all USB devices connected to it successfully, which is why I know everything does work fine. But once Thunderbolt module is loaded during initramfs, the USB devices seemingly shut down.

My Findings: Thunderbolt is being recognized, as evident by on-screen text logs in plymouth/text console like:

thunderbolt 1-0:1.1: new retimer found, vendor ...

thunderbolt 1-1: new device found, vendor ...

thunderbolt 1-1: Lenovo ThinkPad Thunderbolt 3 Dock

I assume the problem lies in how initramfs handles Thunderbolt in general or in this Lenovo Laptop/Dock Combination. My guess is that this could be related to security policies and the module loads fine. Other users considered the thunderbolt module is not loaded or loaded faulty. See: Lenovo docks not recognized in initramfs after upgrading to Ubuntu 24.04

Workaround: Disabling Thunderbolt 4 "PCIe" Passthrough in the UEFI makes the dock work as a USB4 , which again makes it work during initramfs. The keyboard and other devices connected to the dock are functional again. However, this disables Thunderbolt functionality entirely, which isn't ideal as the systems properly uses the authorized (boltctl displays Authorized Connection) device post-encryption.

I was considering to exclude the Thunderbolt module during initramfs to enforce USB recognition, and later allow to load the thunderbolt module (post-LUKS decryption) again.

1. via GRUB Parameter: Using a GRUB boot parameter to disable Thunderbolt during initramfs.

sudo nano /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="thunderbolt.no_pcie=1"

This solution was proposed to me by ChatGPT 4o, but I suspect this parameter doesn't exist or would globally disable Thunderbolt, which defeats the purpose.

2. Modify Initramfs Configuration:

Tinkering with initramfs.conf to change MODULES parameter, like

sudo nano /etc/initramfs-tools/initramfs.conf

MODULES=list or MODULES=dep

The idea to manually exclude Thunderbolt modules by creating a curated list of allowed modules sounds appealing, but this approach could become messy, especially with kernel updates or dependencies, requiring constant manual adjustments of the list.

3. "Blacklist" Thunderbolt Modules in Initramfs:

The ideal approach to me would involve blacklisting Thunderbolt module only during initramfs creation, allowing USB devices to initialize normally: Writing a hook script to exclude Thunderbolt modules during initramfs generation as described in Debian's initramfs-tools documentation suggests this is feasible: https://manpages.debian.org/buster/initramfs-tools-core/initramfs-tools.7.en.html

But I am concerned if adding a hook script for Thunderbolt exclusion would be a reliable and clean solution - something I feel reluctant to experiment with on my production system without actual advice as I am not experienced in coding working hook scripts and afraid to brick initramfs.

In addition, I ask myself what would be the cleanest solution to later load thunderbolt, like via modprobe or with some user configs that are loaded anyway.

Q: Are there better ways to selectively control module loading during initramfs, and loading them in some later stage again?

Thanks for your help

Napzkin
  • 41

2 Answers2

3

Since around October 2024, I have been facing a similar issue with my Dell notebook with my Dell WD19TB Thunderbolt Dock. I tried to ignore it until it became too annoying yesterday, so I looked into the problem and came to the same conclusion as you: The thunderbold module loaded by the initrd somehow prevents the keyboard from working during boot (entering luks passphrase is not possible anymore with a usb keyboard that is connected to the dock), while it works pre-boot (e.g., in grub) and after boot (e.g., in gdm).

So I researched a bit (I did not use any AI tools though, just search engines and search functions) and stumbled across this post, as well as the issue you reported with Launchpad. In line with your research, I also did not find a really convenient way to exclude a module from being packed into the initramfs (why can't we just have a blacklist keyword as we do have with modprobe?). Therefore, I decided to follow-up on your hook-script suggestion and found this post describing how to omit modules.

I adjusted the script to remove thunderbolt stuff more thoroughly. This is my /etc/initramfs-tools/hooks/omit:

#!/bin/sh
PREREQ=""
prereqs()
{
   echo "$PREREQ"
}

case $1 in prereqs) prereqs exit 0 ;; esac

. /usr/share/initramfs-tools/hook-functions

find ${DESTDIR} -name thunderbolt* -delete

The hook seems to need to be executable, so a chmod +x /etc/initramfs-tools/hooks/omit was needed for it to work properly. Additionally, I added the usbhid to /etc/initramfs-tools/modules to make sure it is always included in the initramfs (should be default anyway, but cannot harm to do so explicitly).

After regenerating the initramfs for the current kernel using update-initramfs -c -k $(uname -r) (my idea here is that if I brick the initramfs, I can still boot with an older kernel), I verified that the thunderbolt module is now gone by inspecting the output of lsinitramfs /boot/initrd.img-$(uname -r) | egrep '(thunderbolt|usbhid)'. For me it looks like this now:

usr/lib/modules/6.11.0-17-generic/kernel/drivers/hid/usbhid
usr/lib/modules/6.11.0-17-generic/kernel/drivers/hid/usbhid/usbhid.ko.zst
usr/lib/modules/6.11.0-17-generic/kernel/drivers/hid/usbhid/usbkbd.ko.zst
usr/lib/modules/6.11.0-17-generic/kernel/drivers/hid/usbhid/usbmouse.ko.zst

After a reboot, I could again enter my luks passphrase using the usb keyboard connected to the dock. This has worked for at least 4 boots now, so I am quite happy with this workaround. While this still does not answer your final question on better ways to control module loading selectively, it might still be useful for other users facing the same issue.

xai
  • 31
0

Despite the interpretation of a broken Thunderbolt support by my initial post Ive learned a bit after studying various online posts as well as boltd and boltctl manual (https://manpages.ubuntu.com/manpages/noble/en/man1/boltctl.1.html & https://manpages.ubuntu.com/manpages/noble/en/man8/boltd.8.html).

My latest assumption is to have a working Thunderbolt driver in initrd/initramfs as I have uncovered my UEFI is missing Thunderbolt BootAccessControlList (BootACL) feature & therefor missing a User Authorization of my Dockingstation, which causes this exact behavior that the Dock is blocked by security policy's in Pre-Boot environment while working fine after booting.

I could not solve missing BootACL support on my machine yet and wait for Lenovos Support Feedback, as the suggestions in their online article (https://pcsupport.lenovo.com/lv/en/products/accessory/docks/thinkpad-thunderbolt-3-workstation-dock-gen-2/solutions/ht510635-usb-devices-may-not-function-when-connected-via-thunderbolt-tm-3-docks-thinkpad) of disabling Kernel DMA Protection did not bring the desired effect and BootACL is still missing.

To check for BootACL support of a Domain (Thunderbolt Port) you may continue by checking the verbose log:

  • $ boltd -v

or if your $PATH variable is missing boltd, Ubuntu 22 and 24 store boltd in /usr/libexec. To run it:

  • $ /usr/libexec/boltd -v

boltd by itself is just reading sysfs parameters, so you could readout sysfs directly too but I find it quite comfortable via boltd instead.

The log should contain a statement like "bootacl is supported" or "bootacl is not supported, no vsync".

To gain BootACL capability you need to make changes to your UEFI: "BootACL" or "Pre-BootACL" should be activated and set to "User Authorization".

If BootACL support is present: To further investigate if a User Authorization for your device (the Dock) is set at the Domain (Thunderbolt Port) you may want to check:

  • $ boltctl domains

If the output says "bootacl: 0/0" the manual of boltctl suggests this to interpret as missing BootACL support.

If you have BootACL support but the device is not enlisted, do another enrollment:

  • unplug the cable of the device

  • $ boltctl forget --all

  • connect the device

  • Option 1: follow Ubuntu GUI prompt for authorization

  • Option 2: Manual enrollment

  • $ boltctl list -a

  • check the UUID of your desired device (the Dock)

  • $ boltctl enroll UUID

or maybe

  • $ boltctl enroll UUID --policy auto

Now check "$ boltctl domains" again if the device is listed in BootACL of a domain.

Your device should now be enlisted within the BootAccessControlList and working as desired for LUKS Passphrases.

For everyone with working BootACL support this should be it. In my case: I will report back as soon as I gained BootACL support and can confirm my own answer.

Napzkin
  • 41