Virtualized hardware acceleration on QubesOS using Intel Arc B50
Setting up the Arc Pro B50
Update the Arc Pro firmware
The Arc Pro B50, out of factory, does not include a firmware that supports SR-IOV. We thus have to update it. Unfortunately, it looks like newer version of the firmware artifically limits to VF count to 2 rather than 12, when the feature was first supported. You might want to flash to older version, in this case.
Driver overview for the B50:
- Driver 32.0.101.8331 for Intel Arc < max VFs = 2
- Driver 32.0.101.8306 for Intel Arc Pro < max VFs = 2
- Driver 32.0.101.6979 for Intel Arc Pro < max VFs = 12
The last driver in the list is still the one to get to have access to all Virtual Functions. The easy way to flash the new drivers is by installing, in a windows environment, the Intel Arc Pro Graphic driver of the version you desire. Unfortunately, this requires running windows on bare-metal to flash safely.
There is a way to update the firmware using fwupd, but
this guide has not documented this way yet on QubesOS.
Determine the device address
$ lspci -vv | grep B50
06:00.0 VGA compatible controller: Intel Corporation Battlemage G21 [Arc Pro B50] (prog-if 00 [VGA controller])
For the rest of the guide, I will reference the B50 with 0000:06:00.0. Update the snippets accordingly.
$ lspci -vv -s 06:00.0
06:00.0 VGA compatible controller: Intel Corporation Battlemage G21 [Arc Pro B50] (prog-if 00 [VGA controller])
Subsystem: Intel Corporation Device 1114
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin ? routed to IRQ 228
IOMMU group: 13
Region 0: Memory at 13e0c000000 (64-bit, prefetchable) [size=16M]
Region 2: Memory at 13400000000 (64-bit, prefetchable) [size=16G]
Expansion ROM at cdc00000 [disabled] [size=2M]
Capabilities: <access denied>
Kernel driver in use: xe
Kernel modules: xe
If everything went well the last two lines should point to the xe driver.
Query max Virtual Functions
$ cat /sys/bus/pci/devices/0000:06:00.0/sriov_totalvfs
2
Boot process
Hardware
Not all hardware will support the SR-IOV use case. The following needs to be enabled in BIOS:
- ResizeBar
- IOMMU / SR-IOV
- ASPM (optional, but advised by Intel)
In my case, I have a Supermicro X10-based system, which means ResizeBar is not supported. To unlock, I thus leveraged xCurio0’s ReBarUEFI to patch in ResizeBar support. How to do this is out-of-scope of this guide.
Kernel
This also requires a newer kernel. At the time of writing this guide, kernel 6.19 works, but kernel 6.17 theoretically includes SR-IOV support in xe drivers
Disabling auto probing
There is a currently a bug with Xen, where unbinding xe
from virtual functions after creation leads to a kernel crash. To
mitigate this issue, we can disable automatic probing by leveraging the
sriov_drivers_autoprobe sysfs parameter:
echo 0 | sudo tee /sys/bus/pci/devices/"$DEVICE"/sriov_drivers_autoprobe
This will ensure that the virtual function will be able to attach the device when starting the VM.
That said, the following udev rule can be created to do this automatically:
ACTION="add", SUBSYSTEM="pci", ATTR{sriov_totalvfs}=="*", ATTR{sriov_drivers_autoprobe}="0"
Enable virtual function creation
Due to how the driver works, when the virtual functions are created, whatever VRAM is not currently in use will be split up between the functions. Thus, to keep some VRAM for the host, we have to allocate some memory, before creating the VFs. There isn’tan elegant way to do so, so this guide proposes the use of vramfs to pre-allocate VRAM for the host, then drop the vram filesystem after creation of the virtual functions.
Unfortunately, vramfs is not packaged in Fedora, so it
is provided by myself via my qubes-pkgs repo, and
installable through dnf using this
package.
To facilitate setting up the virtual functions, I took vitabis’
script and wrapped it in a udev rule. So, on dom0, you can create
the following file under
/usr/local/bin/spawn_xe_vfs.sh:
#!/bin/bash
###################################################################
# Helper script to automate the initialization of Virtual Functions
# The idea is to quickly allocate memory space on the Arc Pro GPU,
# before the Virtual Functions are created. After VF creation,
# this memory is released and will remain available to the PF.
###################################################################
### VARIABLES FOR USER TO SET (REQUIRED)
# The Physical Function's address (eg from lspci, domain:bus:device.function)
DEVICE="$1"
# Number of Virtual Functions to create
NUM_VFS="$2"
### VARIABLES FOR USER TO OVERRIDE (OPTIONAL)
# Amount of memory that will remain available to the Physical Function after
# Virtual Functions have been created (in KB/MB/GB).
VRAMFS_SIZE="$3"
# Entry path into the vramfs filesystem
VRAMFS_PATH="/tmp/vram"
# Delay until the vramfs filesystem is mounted (in seconds)
DELAY_VFS=3
# Create vramfs storage of requested size.
if [ ! -e "$VRAMFS_PATH" ]; then
/usr/bin/mkdir $VRAMFS_PATH
fi
/usr/bin/vramfs $VRAMFS_PATH $VRAMFS_SIZE &
# Wait for the filesystem to mount (in the background) before spawning VFs
sleep $DELAY_VFS
# Create Virtual Functions
echo "creating vfs."
/usr/bin/echo $NUM_VFS > "/sys/bus/pci/devices/"$DEVICE"/sriov_numvfs"
# Tear down the vramfs filesystem
echo "terminating vramfs."
Make it executable:
chmod +x /usr/local/bin/spawn_xe_vfs.sh
Finally, create the udev rule under
/etc/udev/rules.d/81-enable-sriov-numvfs.rules:
ACTION="add", SUBSYSTEM=="pci", ATTR{subsystem_device}=="0x1114", ATTR{subsystem_vendor}=="0x8086", RUN+="/usr/local/bin/spawn_xe_vfs.sh %k 2 1GB"
This rule, when adding the Intel Arc B50, executes
spawn_xe_vfs.sh and feeds the device address, tells the
script to create 2 virtual functions, while pre-allocating 1GB of VRAM
to the host. You can adjust these arguments depending on your needs, and
which firmware you used.
Assign VF to VM
After this, you should be able to assign the virtual functions to the VM like any other PCI device. You should use, at least, the kernel version used in dom0. The VM should also be an HVM, like any other VM you attach devices to.
References
- Vitabis’ guide on virtualization workstation with the Inter Arc Pro B50
- Level1Tech forums thread on the Intel Arc Pro B50 and SR-IOV support with many many comments
- QubesOS forum thread on using SR-IOV in QubesOS contact
Known issues
- Fans can sometimes get stuck at 100% when there is no monitor connected. Workaround is to plug a headless displayport adapter. (read more)
- Using the Intel Arc B50 as dom0’s GPU is problematic. After a while, artifacts appear (flickering black bars, black boxes). This seems to be a bug with Xen when dom0 is in PV mode (qubes os ticket, upstream report). My workaround is to use a different GPU for dom0, which defeats the purpose of pre-allocating VRAM, but alas… hopefully this is fixed soon. (update 2026/05/20 - since update to linux 7.0, these artifacts happen a lot less frequently)
- Quite often, VM hangs for a moment, and kernel log shows:
xe 0000:00:08.0: [drm] *ERROR* TLB invalidation fence timeout, seqno=287 recv=286. Still investigating a workaround. (seems to be related to gitlab.freedesktop.org/drm/i915#14469 and gh/strongtz/i915-sriov-dkms#332)