Arrow Lake iGPU support - External monitors (USB-C) not working

Hello,

I’m running Qubes 4.3-rc4 on a system with an Intel Arrow Lake-S processor (Core Ultra 200S series) and having issues with external displays connected via USB-C dock.

System Details:

Qubes OS: 4.3-rc4
Kernel: 6.17.9-1.qubes.fc41.x86_64
GPU: Intel Arrow Lake-S [Intel Graphics] [8086:7d67]
linux-firmware version: 20251125-1 (latest available)

Additional Context:
I’ve already applied workarounds for other Arrow Lake issues:

  • intel_pmc_core.disable=1 and initcall_blacklist=intel_pmc_ssram_telemetry_driver_init (PMC telemetry)
  • Custom libvirt patches for PCIe bus 0x80 topology

The Problem:
The internal laptop display (eDP-1) works perfectly, as does the internal HDMI-port, but external monitors connected through a USB-C to HDMI dock fail to activate:

External displays ARE detected by xrandr (DP-1-1 and DP-1-3 show available modes)
Attempting to enable them with xrandr --output DP-1-1 --auto fails with: xrandr: Configure crt 1 failed
dmesg shows: i915 0000:00:02.0: [drm] PHY A failed to request refclk after 1us

What I’ve Tried:

  • GRUB kernel parameters - no effect: i915.enable_dc=0 i915.enable_psr=0
  • Switching to xe driver - The system has both i915 and xe drivers available. Arrow Lake should potentially use the newer xe driver, but:
    ** Attempted to switch using i915.force_probe=!8086:7d67 xe.force_probe=8086:7d67
    i915 still claims the device before xe can
    The /lib/firmware/xe/ directory doesn’t exist - xe firmware files (lnl_guc_70.bin, lnl_huc.bin) are missing while they are available in the original linux-firmware-20251125.tar.gz.

Blacklisting i915 completely breaks the graphical interface

Questions:

  • Has anyone successfully used external displays with Arrow Lake on Qubes?
  • Should I be using the xe driver instead of i915 for this GPU? If so, how do I properly switch?
  • Is the missing /lib/firmware/xe/ directory and firmware files an issue?
  • Are there other kernel parameters or configurations I should try?

Any help is greatly appreciated.

Kind regards, Bloged

I have tried using external displays on Arrow Lake through a Thunderbolt Dock(using Type C connector). Works but sometimes the monitor disconnects.(HDMI connection from monitor to Dock).

What’s interesting is that it works flawless before login. I can use the monitors in Bios at 1080p.

What I use now is daisy chaining monitors via MST and then driving them through DisplayPort Alt.
(the monitors don’t support TB). This has always worked perfectly on any laptop I’ve tried.
(type c between monitors, another type c to computer)

Not all docks connected through Type C are Thunderbolt docks though, some are USB4(DP tunneling over USB)/USB3(DisplayPort Alternate Mode) docks. So perhaps you should check the exact model.

I haven’t modified anything, no custom configurations. 4.3-RC4.

Perhaps trying a DisplayPort Alt dock would work for you, but I am not sure if you could get more than 1 4k.

Arguably before I had a Dell with a TB dock many years ago, and I had constant problems with 1080p monitors disconnecting. Link training issues.

Same Dell laptop worked flawlessly with DisplayPort Alt Type C 1080p monitors.

With a TB dock, xrandr: Configure crt 1 failed was one of the errors. I remember getting lots of these. One thing I noticed is, using a better cable also helps. But most TB docks don’t have a user replaceable cable.

I will check, but I think I am using the i915. Haven’t had any issues with it.

How did you compiled it? I tried to use the qusal set of salt recipes but I have a problem of gpg signature verification. How did you install your development environment?

Thanks
Bertrand

@bertrand Hope this helps to build them:

I’ve pieced together my own kind of way of working.

I’ve copied fedora-41-xfce template to fedora-41-builder. Then created an AppVM based on that.

In the template I installed all dependencies which can be found in the dependencies-fedora.txt inside the qubes-builderv2 repo.

In the AppVm I’ve checked out the quibes-builderv2 repo; Created the file builder.yml with the following content:

# include configuration relevant for the current release
include:
- example-configs/qubes-os-r4.3.yml

# which repository to use to fetch sources
use-qubes-repo:
  version: 4.3
  testing: true

# each package built will have local build number appended to package release
# number. It makes it easier to update in testing environment
increment-devel-versions: true

# reduce output
debug: false

# this can be set to true if you do not want sources to be automatically
# fetched from git
skip-git-fetch: false

# executor configuration
executor:
  type: docker
  options:
    image: "qubes-builder-fedora:latest"

Ran the ./tools/generate-container-image.sh script. And build what I needed. Before building libvirt I already built a complete ISO to check somethings.

Note: This uses the docker build way to do stuff… I didn’t want to look into the quibes builder method so choose the “easy” way out :wink: .

Regards, Bloged

I’ve got a Icy Box USB-c/TB dock and a Dell WD-15 both fail with the same issue… Haven’t tried the mini-displaylink on the Dell; so will try that when I can find the right calble for that.

At work we have some different docking stations (some DisplayLink, but those I will avoid like the plague) and some USB-c/TB docks… will check those as well, but that will probably be in the new year!

Still wondering if this shouldn’t be using the xe kernel module instead of the i915!

Regards, Bloged

I was able to compile your patch but I am not sure which package do I need to install to Dom0 out kf the output RPMs.

Like you I choose Docker for convenience.
Everything was mostly straightforward.

Please share which RPMs did you install in Dom0.

On the topic of Docks, I’ve tried again. Funny thing is , TB dock always works at bios and LUKS(Plymouth stage).

After unlocking the encrypted disk, then the signal disappears.

However I fiddled a bit with my BIOS a bit. I disabled Rebar and SR-IOV. And enabled PCIE over USB4 tunnelling and changed the USB4 router.

Not sure if that changed anything.
System hanged afterwards on restart and needed poweroff from cable.(reset/power button not working)

Afterwards, when I booted, signal again disappeared after unlocking disk. However around half a minute later, monitors started working again.

No problems so far. I will try reverting my BIOS settings and retry.

I notice the same thing with my two docks. Signal until disk encryption and at (a part of) the shutdown sequence.

To bad my BIOS isn’t that advanced in what can be set… so for now I seem to be stuck!

For libvirt I simply replaced the current packages. I queried wich were installed using rpm -qa | grep libvirt and installed those.

Regards, Bloged

Afaik, it means the Xorg driver is messed up. Plymouth I think uses the simple frame buffer device.
So you have image before Xorg.

Did you try waiting for a while to see if image would appear? Like a minute or so?

Anyhow, I don’t the problem is with i915. Rather I think it sounds like a Xorg issue.

Another suggestion:
Try setting Xorg to use the generic modesetting instead of the Intel driver. That could very well solve it.

Also try using thunderbolt utils in Dom0.

And check if you’re assigning the TB to a VM like sys-usb. That could also be the reason. Since VMs only start after login and stop on logout.

On the RPM part, could you paste your
rpm -qa | grep libvirt output.

I already installed too much of those RPMs but I don’t know which to remove. And the fix doesn’t seem to work.

These are the rpm’s I’ve installed from the patched build:

libvirt-libs-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-common-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-lock-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-plugin-lockd-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-driver-interface-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-driver-libxl-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-driver-nodedev-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-proxy-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-xen-10.5.0-2.6.fc41.x86_64.rpm
python3-libvirt-10.5.0-2.6.fc41.x86_64.rpm
libvirt-daemon-10.5.0-2.6.fc41.x86_64.rpm
libvirt-client-10.5.0-2.6.fc41.x86_64.rpm

Hopefully that helps!

Regards, Bloged

Thank you so much for these hints. I go way further than with any other method I tried before. However, i am still not at the end.

Right now, i just try to re-compile the normal libvirt before your patch. After the compilation and the testing phase, I get the error below.

18:10:33 [qb] An error occurred: core-libvirt:host-fedora-41.x86_64:libvirt.spec: Failed to build RPMs: Failed to run 'sudo mkdir -p -- /builder /builder/build /builder/plugins /builder/distfiles&&sudo chown -R -- user:user /builder&&sed -i 's#@BUILDER_DIR@#/builder#g' /builder/plugins/chroot_rpm/mock/fedora-41-x86_64.cfg&&cd /builder/repository&&createrepo_c .&&sudo chown -R user:mock /builder/build&&sudo chown -R root:mock /builder/cache/mock&&sudo --preserve-env=DIST,PACKAGE_SET,USE_QUBES_REPO_VERSION /usr/libexec/mock/mock --no-cleanup-after --verbose --rebuild /builder/build/libvirt-10.5.0-2.2.fc41.src.rpm --root /builder/plugins/chroot_rpm/mock/fedora-41-x86_64.cfg --resultdir=/builder/build --isolation=simple --enablerepo=qubes-current --enablerepo=qubes-current-testing --plugin-option=root_cache:age_check=False --define 'dist .2.fc41' --no-clean&&sudo --preserve-env=DIST,PACKAGE_SET,USE_QUBES_REPO_VERSION,BIND_MOUNT_ENABLE /usr/libexec/mock/mock --root /builder/plugins/chroot_rpm/mock/fedora-41-x86_64.cfg --chroot /plugins/build_rpm/scripts/rpmbuildinfo /builddir/build/SRPMS/libvirt-10.5.0-2.2.fc41.src.rpm > /builder/build/libvirt-10.5.0-2.2.fc41.x86_64.buildinfo&&/builder/plugins/build_rpm/scripts/filter-packages-by-dist-arch /builder/build /builder/build/rpm 2.fc41 x86_64' (status=1)..
18:10:33 [qb] Additional information from 20251221T164803-core-libvirt-host-fc41.log line 6960:
18:10:33 [qb] >>>     Macro expanded in comment on line 373: %{epoch}:%{version}-%{release}
18:10:33 [qb] >>>     Macro expanded in comment on line 374: %{epoch}:%{version}-%{release}
18:10:33 [qb] >>>     Macro expanded in comment on line 569: %{epoch}:%{version}-%{release}
18:10:33 [qb] >>>     Macro expanded in comment on line 570: %{epoch}:%{version}-%{release}
18:10:33 [qb] >>>     Macro expanded in comment on line 571: %{epoch}:%{version}-%{release}
18:10:33 [qb] >>>     Macro expanded in comment on line 572: %{epoch}:%{version}-%{release}
18:10:33 [qb] >>>     Bad exit status from /var/tmp/rpm-tmp.Rtu6Pq (%check)
18:10:33 [qb] >>> RPM build warnings:
18:10:33 [qb] >>> RPM build errors:
18:10:33 [qb] >>> Child return code was: 1
18:10:33 [qb] >>> EXCEPTION: [Error("Command failed: \n # bash --login -c '/usr/bin/rpmbuild -bb --noclean --target x86_64 --nodeps /builddir/build/SPECS/libvirt.spec'\n", 1)]

The really bad part is that I don’t find the compiled libraries that are to be put in the rpm, as if I found them, I could try to manually install them in dom0.

Does someone have an idea to help me…?

Thanks,
Bertrand

On those lines mentioned escape those % with another one in the spec.in-file. So %{epoch}:%{version}-%{release} becomes %%{epoch}:%%{version}-%%{release}. Just do it on those lines mentioned!

Regards, Bloged

Sadly, it does not improve that much…

19:38:27 [qb] An error occurred: core-libvirt:host-fedora-41.x86_64:libvirt.spec: Failed to build RPMs: Failed to run 'sudo mkdir -p -- /builder /builder/build /builder/plugins /builder/distfiles&&sudo chown -R -- user:user /builder&&sed -i 's#@BUILDER_DIR@#/builder#g' /builder/plugins/chroot_rpm/mock/fedora-41-x86_64.cfg&&cd /builder/repository&&createrepo_c .&&sudo chown -R user:mock /builder/build&&sudo chown -R root:mock /builder/cache/mock&&sudo --preserve-env=DIST,PACKAGE_SET,USE_QUBES_REPO_VERSION /usr/libexec/mock/mock --no-cleanup-after --verbose --rebuild /builder/build/libvirt-10.5.0-2.3.fc41.src.rpm --root /builder/plugins/chroot_rpm/mock/fedora-41-x86_64.cfg --resultdir=/builder/build --isolation=simple --enablerepo=qubes-current --enablerepo=qubes-current-testing --plugin-option=root_cache:age_check=False --define 'dist .3.fc41' --no-clean&&sudo --preserve-env=DIST,PACKAGE_SET,USE_QUBES_REPO_VERSION,BIND_MOUNT_ENABLE /usr/libexec/mock/mock --root /builder/plugins/chroot_rpm/mock/fedora-41-x86_64.cfg --chroot /plugins/build_rpm/scripts/rpmbuildinfo /builddir/build/SRPMS/libvirt-10.5.0-2.3.fc41.src.rpm > /builder/build/libvirt-10.5.0-2.3.fc41.x86_64.buildinfo&&/builder/plugins/build_rpm/scripts/filter-packages-by-dist-arch /builder/build /builder/build/rpm 3.fc41 x86_64' (status=1)..
19:38:27 [qb] Additional information from 20251221T181812-core-libvirt-host-fc41.log line 6862:
19:38:27 [qb] >>> Expected Fail:      1
19:38:27 [qb] >>> Fail:               0
19:38:27 [qb] >>> Unexpected Pass:    0
19:38:27 [qb] >>> Skipped:            1
19:38:27 [qb] >>> Timeout:            1
19:38:27 [qb] >>> Full log written to /builddir/build/BUILD/libvirt-10.5.0-build/libvirt-10.5.0/redhat-linux-build/meson-logs/testlog.txt
19:38:27 [qb] >>> error: Bad exit status from /var/tmp/rpm-tmp.5CFdiq (%check)
19:38:27 [qb] >>>     Bad exit status from /var/tmp/rpm-tmp.5CFdiq (%check)
19:38:27 [qb] >>> RPM build errors:
19:38:27 [qb] >>> Child return code was: 1
19:38:27 [qb] >>> EXCEPTION: [Error("Command failed: \n # bash --login -c '/usr/bin/rpmbuild -bb --noclean --target x86_64 --nodeps /builddir/build/SPECS/libvirt.spec'\n", 1)]

Any other idea?

By the way, do anyone know why the compilation cannot be done on Qubes R4.3.0-rc4 with fedora-42? With a fedora-42 based template, it fails way before, at the ./tools/generate-container-image.sh step, with an error line saying ERROR: failed to build: failed to solve: failed to extract layer sha256:4180[...]9418: failed to get reader from content store: content digest sha256:7b06[...]3bbb: not found.

Thanks,
Bertrand

@Bloged
Thanks for the RPM list, will try again soon.

@bertrand
I did have to reformat the patch from @Bloged to get it compile. Look at the existing patches and make sure it looks similar.
White space and ending of the file is important.

I am not yet at applying the patch, I just try to compile it, just to test the compilation chain… and it does not work totally…

Thanks for your time!
Bertrand

You’re welcome.

For me, it did build immediately.
I just copied the sample builder for 4.3.
But as soon as I added the patch, I had errors.
So I had to reformat it.
But after supposedly stuffing the RPMs in Dom0, I didn’t get it to work. Possibly something else I messed up.

(one thing coming to mind is that, afaik most Docks(TB/USB/whatever) want to put your USB devices on the main USB controller, meaning 00:80.14, so if you do successfully pass that controller to a VM that might mess things up)

Btw I used Docker env.

Possibly a bad builder.yml in your case then?
Everything else should come from the builder.

I will see if I can upload my core-libvirt as fork to github.com tomorrow. Maybe I’ve done some other changes I can’t remember anymore!

I build it initially on fedora 41 appvm on Qubes 4.2.4 as that was my previous laptop…

Regards, Bloged

So I am definitively unlucky…

I am using a Qubes R4.2.4 with fedora-41-xfe as the base and did as @Bloged shown above.
Just after installation of qubesbuilderv2, I just try to ./qb -c core-libvirt package fetch prep build and I get the previous error.

Are you using the same versions?

Bertrand

But it’s a version that is no more supported, I get some warnings quite often. It’s strange that a fedora-42 version does not exist yet…
In the meantime before that, I will work to find where i my mistake…

Did one of you increased some disk space or memory in the AppVM?

Bertrand

I did use a standalone VM based on Fedora 42 or 43 I think. I did give it plenty of storage.
I did this on Qubes 4.3-RC4 btw.

Because it’s a docker build, you don’t need the builder to be Fedora 41.

  1. After checking out the builder via git clone, in it’s directory, I did
sudo dnf install $(cat dependencies-fedora.txt)

test -f /usr/share/qubes/marker-vm && sudo dnf install qubes-gpg-split
  1. Then:
systemctl enable docker
sudo usermod -aG docker user
  1. Reboot VM.

  2. Then run

tools/generate-container-image.sh docker

Now you should have a docker image ready to build.

  1. Then add a builder.yml file.
# include configuration relevant for the current release
include:
- example-configs/qubes-os-r4.2.yml

# which repository to use to fetch sources
use-qubes-repo:
  version: 4.2
  testing: true

# each package built will have local build number appended to package release
# number. It makes it easier to update in testing environment
increment-devel-versions: true

# reduce output
debug: false

# this can be set to true if you do not want sources to be automatically
# fetched from git
skip-git-fetch: false

# executor configuration
executor:
  type: docker
  options:
    image: "qubes-builder-fedora:latest"
  1. Fetch the libvirt source code
./qb -c core-libvirt package fetch
  1. Modify adding libvirt sourcethe patch
    Check the spec.in file and the existing patches. Adding a new patch should be the same basically.
    (link the patch in the spec.in or whatever it was called file)
  2. Build the libvirt
./qb -c core-libvirt package fetch prep build