Audio Routing Issue with sys-audio AppVM in Qubes OS

Hello,

I am reaching out to seek assistance regarding an audio routing issue I am experiencing with the sys-audio AppVM in Qubes OS.

I have set up a sys-audio AppVM that is connected to a DAC (Digital-to-Analog Converter).
I followed all the instructions outlined here, with the difference of instead of attaching the entire PCI controller to sys-audio, I’ve only attached the USB device corresponding to the DAC.
When the DAC is powered on, audio streams from various AppVMs route correctly through sys-audio and play sound without issues. However, when I power off the DAC, I get no sound output from any AppVM that utilizes sys-audio, and the system defaults to the Dummy Output. Since sys-audio is using dom0 as the audiovm, I was expecting that once the DAC is switched off that sys-audio would default to dom0 and would output the sound back to the builtin speakers, but unfortunately that doesn’t happen. The problem is that sys-audio doesn’t route audio back to internal speakers and I don’t know what else to try.

This is my (quite permissive) qubes policy (50-sys-audio.policy):


# ----------------------------------------------------------------------
# Generic admin events – always allowed
admin.Events                        *   sys-audio    sys-audio              allow   target=dom0
admin.Events                        *   sys-audio    @adminvm               allow   target=dom0
admin.Events                        *   sys-audio    @tag:audiovm-sys-audio allow   target=dom0

# Allow events that come from the USB device VM
admin.Events                        *   sys-usb      sys-usb                allow   target=dom0
admin.Events                        *   sys-usb      sys-audio              allow   target=dom0
admin.Events                        *   sys-audio    sys-audio              allow   target=dom0

# ----------------------------------------------------------------------
# USB device handling
#  – query which USB devices are present (needed for hot‑plug)
admin.vm.device.usb.Available       *   sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.device.usb.Available       *   sys-audio    sys-usb                allow   target=dom0
# optional reverse direction (covers rare back‑ends)
admin.vm.device.usb.Available       *   sys-usb      sys-audio              allow   target=dom0

#  – notify dom0 about a device being added/removed
admin.vm.device.usb.Change          *   sys-audio    @tag:audiovm-sys-audio allow   target=dom0

# ----------------------------------------------------------------------
# VM state / property queries
admin.vm.CurrentState               *   sys-audio    sys-audio              allow   target=dom0
admin.vm.CurrentState               *   sys-audio    @adminvm               allow   target=dom0
admin.vm.CurrentState               *   sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.listening                  *   sys-audio    sys-audio              allow   target=dom0
admin.vm.List                       *   sys-audio    @adminvm               allow   target=dom0
admin.vm.List                       *   sys-audio    @tag:audiovm-sys-audio allow   target=dom0

admin.vm.property.Get               +audiovm   sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.property.Get               +xid      sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.property.Get               +stubdom_xid sys-audio @tag:audiovm-sys-audio allow   target=dom0

# ----------------------------------------------------------------------
# Feature checks (pipewire/audio stack)
#admin.vm.feature.CheckWithTemplate *   sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.feature.CheckWithTemplate  +audio-model                 sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.feature.CheckWithTemplate  +audio                       sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.feature.CheckWithTemplate  +gui                         sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.feature.CheckWithTemplate  +supported-service.pipewire  sys-audio    @tag:audiovm-sys-audio allow   target=dom0
admin.vm.feature.CheckWithTemplate  +audio-low-latency           sys-audio    @tag:audiovm-sys-audio allow   target=dom0

# ----------------------------------------------------------------------
# Full property dump (allowed for all audio VMs)
admin.vm.property.GetAll            *   sys-audio    sys-audio              allow   target=dom0
admin.vm.property.GetAll            *   sys-audio    @adminvm               allow   target=dom0
admin.vm.property.GetAll            *   sys-audio    @tag:audiovm-sys-audio allow   target=dom0

And this is what I see on sys-audio when I ran wpctl:

~$ wpctl status
PipeWire 'pipewire-0' [1.4.9, user@sys-audio, cookie:721664436]
 └─ Clients:
        34. WirePlumber                         [1.4.9, user@sys-audio, pid:1202]
        42. WirePlumber [export]                [1.4.9, user@sys-audio, pid:1202]
        47. pipewire                            [1.4.9, user@sys-audio, pid:1288]
        49. xdg-desktop-portal                  [1.4.9, user@sys-audio, pid:1469]
        50. wpctl                               [1.4.9, user@sys-audio, pid:1525]

Audio
 ├─ Devices:
 │  
 ├─ Sinks:
 │  *   48. Dummy Output                        [vol: 1.00]
 │  
 ├─ Sources:
 │  
 ├─ Filters:
 │  
 └─ Streams:

Video
 ├─ Devices:
 │  
 ├─ Sinks:
 │  
 ├─ Sources:
 │  
 ├─ Filters:
 │  
 └─ Streams:

Settings
 └─ Default Configured Devices:

When I run some audio in sys-audio I got no sound:

~$ speaker-test -t wav -c 2

speaker-test 1.2.14

Playback device is default
Stream parameters are 48000Hz, S16_LE, 2 channels
WAV file(s)
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 64 to 1048576
Period size range from 32 to 524288
Periods = 4
was set period_size = 12000
was set buffer_size = 48000
 0 - Front Left
 1 - Front Right
Time per period = 2.268504
 0 - Front Left
 1 - Front Right
^CWrite error: -4,Interrupted system call
xrun_recovery failed: -4,Interrupted system call
Transfer failed: Interrupted system call

Any idea what I might be missing?

Thank you!

I identified the issue: I had forgotten to install pipewire-qubes, which led to the virtual audio device not being routed correctly to dom0.

To ensure proper audio routing to both the DAC and dom0 even when the DAC is powered off, all relevant packages will need to be installed.

dnf install qubes-audio-daemon pulseaudio-utils notification-daemon pavucontrol qubes-core-admin-client qubes-gui-daemon pipewire **pipewire-qubes**

After this is was just a matter of restart pipewire and the pavcontrol listed the proper Qubes virtual audio sink

systemctl --user restart pipewire

Why won’t you include internal audio in to sys-audio?

You mean the USB controller? My controller hosts several USB devices that I use for more than just audio, given how many few ports I have, I can’t afford to leave any ports idle because the controller is assigned to the system‑audio VM.

Your internal audio is connected to dom0 so connect it to sys-audio instead.

I’m not sure I understand, what’s the benefit of doing that?
I created a sys‑audio device only because I needed a USB DAC to work, and I didn’t want to directly expose sys‑usb to it.

I don’t understand you either.
You add PCI sound audio to sys-audio in devices and usb dac device in Qubes Devices` and that’s it. No need to attach any controllers.
Internal audio is attached all the time and DAC when you attach it by the hand.

What you don’t want to directly expose to sys-usb I don’t understand.

I already explained above that assigning the whole USB‑controller PCI device to sys‑audio would make all USB ports on that controller idle for anything else. I have several devices plugged into those ports, and I can’t afford to lose them just to run a DAC.

sys‑usb and sys‑audio serve different purposes and expose different attack surfaces.

  • sys‑usb – the general‑purpose USB hub I use for keyboards, mice, storage, network adapters, etc.
  • sys‑audio – should handle only the audio peripheral (USB DAC, USB Mics/Headsets…).

Therefore I prefer to keep the controller in sys‑usb and forward the DAC as an individual USB device to sys‑audio. This leaves the remaining ports available for all other peripherals and maintains a cleaner separation between the two sys VMs.

I argee. It’s better this way. The DAC is only used in sys-audio qube anyway.
No other qube is ever going to use it. No reason to go through PCI.

My sys-audio audiovm is set to none and it works.

Out of curiosity: do you keep your DAC persistently attached to sys‑audio? I found that if the DAC is powered off before sys‑audio starts, the USB device isn’t listed and sys‑audio won’t boot until the DAC is powered on again or the device is explicitly detached.
For that reason I keep it detached and only attach it when I need it, but I’m not sure if there’s a different way to address this.

But why you are constantly writing about usb controller? What have in common internal PCI sound device with whole usb controller? You’ve fixed about this usb controller but it’s not needed for sys-audio, only PCI-Adler-Lake-Sound-device or what you have in this laptop.

PS: permanently attached to sys-audio USB device block sys-audio from autostart. Because sys-audio start first and can’t see any usb devices.

PS2: is this a usb controller? Because it’s that tha I have attached permanently to sys-audio

00:1f.3 Audio device: Intel Corporation Alder Lake PCH-P High Definition Audio Controller (rev 01)

You’re conflating two different things.

  1. In Qubes a USB host controller appears as a PCI device on the bus. When you passthrough that controller you give the target VM direct control of the entire controller and therefore all ports/devices on it — you can’t assign a single physical USB port at the PCI level. That limitation comes from PC/VT‑d hardware and how QEMU/Qubes handle PCI device assignment.
  2. The PCI entry you quoted — 00:1f.3 Intel Alder Lake PCH‑P High Definition Audio Controller — is the motherboard’s onboard audio (internal DAC/codecs), not a USB device. External USB DACs appear under lsusb, not as a 00:1f.3 PCI device.

So: if you want onboard audio in sys-audio attach the PCI audio device (00:1f.3). If you want a USB DAC without taking over all USB ports, keep the USB controller in sys-usb and forward the individual USB device to sys-audio when needed (and avoid permanently attaching powered‑off USB devices to sys-audio to prevent autostart issues).

If this isn’t clear, I don’t know what else to tell you.

But I asking about this.
I don’t know, I’m not native speaker, maybe I’m askin in summerian, but I’m asking why you don’t attach this internal PCI sound device to sys-audio.

But I have no chance to get answer, because YOU on every my question are talking about usb controller.

EOT

Attaching the PCI audio controller to sys-audio results in no sound. I wasn’t able to get this to work; the CPU spikes on both the testVM and sys-audio as soon as I set the testVM to use sys-audio.

Due to this, I decided to leave the audio controller in dom0, as I don’t see much issue in not properly isolating the audio controller.

When you set audiovm for sys-audio as dom0 then alsa master device will become this Qubes Virtual Audio sink.
Then you will have no sound.
If in volume mixer you set for your qube your hardware sound device as output you will have sound again, but without keyboard control over volume.

Only workaround I’ve found so far is… to set sys-audio audiovm for sys-audio:

qvm-prefs --set sys-audio audiovm sys-audio

or delete audiovm for sys-audio

qvm-prefs --set sys-audio audiovm ""

PS: only downside is my mic is dom0:mic device and without setting audiovm=dom0 I can’t attach it to anything

I’ve attached the sound controller to sys-audio together with the DAC, and it works now, but the keyboard‑controlled volume tray no longer functions. I have to open pavucontrol or pasystray each time I want to adjust the volume, which is very annoying. I’ve searched the forum and the Qubes documentation without finding a solution.

Do you know how to get the keyboard volume keys working again while still showing a visual indicator in the tray, like the PulseAudio panel plugin?

The microphone is isn’t a priority for me right now, but easy volume adjustment is essential.