Ubuntu 26.04 on the Dell XPS 13 9350: TPM, Snap, and the Return of LUKS

The Hardware

The Dell XPS 13 9350 with the Intel Core Ultra 7 (Lunar Lake). Thin, light & sleek, silent under load, and sporting the latest Intel silicon. On paper it’s the ideal Linux laptop, and for the most part it is, but the path from fresh install to working daily driver was anything but as smooth as was promised.

24.04: Certified but Broken

This laptop is Ubuntu certified for 24.04 LTS. That certification gave me confidence going in, but the reality was dire. The Intel IPU6/7 camera would work once per boot. Any subsequent use in the same session turned the video feed white. A reboot would give you one more shot, then white again on re-use.

After being told by Dell that support for Ubuntu was null and void, given that I purchased the laptop with Windoze (in Australia where Ubuntu is not a present option), I gave up on 24.04 and waited for 26.04, hoping the newer kernel and camera stack would sort the Ipu issues. Well… it sorta did, but not quite.

First Attempt: TPM-backed Encryption and Snap

Ubuntu 26.04 ships with a fresh install option: TPM-backed full disk encryption. The promise is seamless, your disk is encrypted, your TPM handles the unlock at boot, no passphrase required.

In practice, on this machine, it was a cage. The TPM encryption path is tightly coupled to Snap-based system management. The root filesystem layout is opinionated and inflexible. When things started going sideways with missing drivers and the need to load out-of-tree kernel modules via DKMS, the Snap confinement model fast became a frustrating obstacle rather than a helpful guardrail.

While it’s clear that tighter application sandboxing is the direction Ubuntu is heading, it is not evident at the surface that selecting TPM encryption means you’re getting a sandboxed snapd pc-kernel under the hood. You can understand why this needs to be rigorously restricted and validated prior to admission, but you’d expect for a major producer in Intel and an Ubuntu partner in Dell, that if the wifi worked when using the installer, it would work when booting the TPM installed pc-kernel. As you have already guessed, this disappointingly turned out not to be the case.

The wifi (iwlwifi for the Lunar Lake wireless) required firmware that wasn’t present in the stock install media. The Intel IPU7 camera stack was entirely absent. Both problems demanded the kind of low-level module loading, PPA additions, and DKMS builds that don’t play nicely with the TPM-sealed, Snap-centric disk layout.

After burning a day fighting permission boundaries and sealed PCR states that broke on every kernel module change, I made the call.

Second Attempt: Legacy LUKS + LVM

Wipe. Reinstall. This time selecting the classic LUKS + LVM encrypted option with a passphrase at boot. Old school, battle-tested, and it gets out of your way when you need to work.

The install itself was clean. From there, the real work began.

WiFi: iwlwifi Firmware

The Lunar Lake wireless needed the OEM kernel and associated firmware. Stock kernel had the module but lacked the microcode:

sudo apt install linux-image-oem-26.04 linux-headers-oem-26.04

Reboot into the OEM kernel and wifi comes up without drama.

Camera: The Intel IPU7 Stack

This was the bigger battle. The Dell XPS 13 uses an Intel IPU7 with an OV02C10 sensor connected via MIPI/CSI-2. Stock Ubuntu 26.04 has no idea what to do with it. The Dell OEM 24.04 image had a pre-integrated camera stack that simply isn’t present in the stock 26.04 release.

The root cause chain:

  1. Missing userspace camera HAL - stock libcamera 0.7.0 lacks an IPU7 pipeline handler
  2. Missing Intel CVS (vision) driver - INTC10DE device has no driver, preventing sensor ownership handshake
  3. Boot race condition - USB-IO bridge (Lattice INTC10B5) loads late over USB; int3472 power controller times out waiting for GPIO chip
  4. Suspend/resume breaks camera - USB-IO bridge enters hung state after suspend

The Fix

# IPU7 kernel modules
sudo apt install linux-modules-ipu7-generic intel-ipu7-dkms

# Camera HAL from OEM PPAs
sudo add-apt-repository ppa:oem-solutions-group/intel-ipu6
sudo add-apt-repository ppa:oem-solutions-group/intel-ipu7
sudo apt install libcamhal-ipu7x

# Vision/CVS driver
sudo apt install intel-vision-dkms

# User must be in video group
sudo usermod -aG video $USER

The ppa:oem-solutions-group/intel-ipu6 provides the shared libcamhal0 dependency. The intel-ipu7 PPA provides the actual IPU7 Lunar Lake camera HAL. intel-vision-dkms handles the CVS driver for the INTC10DE sensor ownership via GPIO handshake.

For Secure Boot, the DKMS modules get signed with MOK keys at /var/lib/shim-signed/mok/MOK.priv and MOK.der.

Suspend/Resume Workaround

Camera dies after suspend due to the USB-IO bridge not recovering. While the use once then white is now fixed, once you suspend the camera light stays lit, and all you get from the camera is a still.

For now, I’m experimenting with a systemd sleep hook at /usr/lib/systemd/system-sleep/camera-resume.sh which attempts to handle the reset, which is better than nothing but far far from perfect. Will update here if I can find a solution soon enough.

#!/bin/bash
set -x

echo "=== Starting camera recovery test ==="

modprobe -r ov02c10 intel_skl_int3472_discrete intel_cvs 2>/dev/null
sleep 1

echo 0 > /sys/bus/usb/devices/3-2/authorized
sleep 2
echo 1 > /sys/bus/usb/devices/3-2/authorized
sleep 4

modprobe -r gpio_usbio 2>/dev/null
sleep 1
modprobe gpio_usbio
sleep 2

modprobe intel_cvs
sleep 3
modprobe intel_skl_int3472_discrete
sleep 3
modprobe ov02c10
sleep 2

echo "=== Result: ov02c10 refcnt = $(cat /sys/module/ov02c10/refcnt) ==="

This attempts to reset the Lattice USB-IO bridge (2ac1:20c9) as well as attemtping to negotiate the gpio handshake before it reloads the camera module chain in the correct order. Most resume cycles still require a full reboot. Upstream issue tracked at https://github.com/intel/vision-drivers/issues/32 and https://bugs.launchpad.net/ubuntu/+source/linux-oem-7.0/+bug/2158255

Diagnostics

# Check sensor binding
cat /sys/module/ov02c10/refcnt

# Check CVS driver
ls /sys/bus/i2c/devices/i2c-INTC10DE:00/driver

# Check int3472 binding
find /sys/bus/platform/drivers/int3472-discrete -type l

# Boot errors
journalctl -b -k | grep -i "ov02c10\|int3472\|cvs\|usbio\|GPIO"

# Test camera
cam --list
wpctl status

DNS: Quad9 over HTTPS

Some ISP’s blocks port 853 (DNS over TLS), mine happens to be one of them. The workaround is dnscrypt-proxy fronting systemd-resolved, routing through Quad9 DoH on port 443:

Apps -> systemd-resolved (127.0.0.53:53) -> dnscrypt-proxy (127.0.2.1:8853) -> Quad9 DoH (443)

Key config in /etc/dnscrypt-proxy/dnscrypt-proxy.toml:

  • Listen on 127.0.2.1:8853
  • Resolvers: doh-ip4-port443-filter-pri and doh-ip4-port443-filter-alt
  • ignore_system_dns = true

And /etc/systemd/resolved.conf.d/quad9.conf:

[Resolve]
DNS=127.0.2.1:8853
Domains=~.

Verify with:

dig +short txt proto.on.quad9.net.
# Should return "doh"

Local DHCP DNS (e.g. .lan domains) still resolves via link-local DNS from NetworkManager.

VPN: OpenVPN Password Storage

NetworkManager’s OpenVPN plugin in 26.04 finally supports storing the password separately from the MFA token entry. Previous versions would only persist the saved password if MFA was not configured on the connection. With MFA enabled, it would prompt for both on every connect, making stored credentials useless.

The fix is a new password-flags separation in the connection profile that distinguishes the static password from the dynamic token field. Passwords can now be stored in the keyring while the token prompt still appears at connect time. I’d been waiting for this one for quite a while…

sudo apt install network-manager-openvpn network-manager-openvpn-gnome

Reflections

The TPM encryption story in Ubuntu 26.04 appears to be targeted toward the corporate fleet management, with lower maintenance needed for hardening of operating systems to improve security. For everyone else, that are running machines where the driver support hasn’t made the cut, the classic LUKS + LVM path remains the pragmatic choice.

It’s a bit disappointing that the installer doesn’t make this trade-off clearer. The TPM option is presented with all it’s perfectly positive features, but without much warning or detail about the constraints that imposes. Despite a machine like the XPS 9350 being certified by Ubuntu, where you’re expecting it to be supported, it’s simply the wrong choice at the moment.

The good news: once you’re past the encryption decision and find your way onto the OEM kernel with the right PPAs, this machine runs beautifully. Lunar Lake is fast & efficient, the display is crisp & gorgeous, battery is quite good (6-8 hours) and with the camera stack mostly sorted, it’s a sweet daily driver. Not quite a sweet as my pine green 5 door 1982 Saab 900 turbo, where the repairs are not quite so readilly accessed, but I digress, love is love …