Thanks to: https://forum.proxmox.com/threads/s...1340h-igpu-passthrough-on-proxmox-ve-9.180742
HARDWARE
Model: Mini PC with Intel N100 or Fujitsu Esprimo Q957 with Intel i5 7500
iGPU: Intel UHD Graphics, no additional GPU installed
Host OS: Proxmox VE 9.1.5
Guest: Debian (VMID 100)
Goal: Use the NUC as a Proxmox host AND as a local Debian desktop via HDMI.
Enter BIOS (F2 at boot)
Display: Auto
Secure Boot → disabled
UEFI Boot → enabled
CSM → Disabled (if present)
Save and exit.
STEP 1 – ENABLE IOMMU
Open Proxmox shell on Host.
nano /etc/default/grub
Replace the line starting with GRUB_CMDLINE_LINUX_DEFAULT with:
N100/Esprimo:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction initcall_blacklist=sysfb_init video=simplefb
ff video=vesafb
ff video=efifb
ff video=vesa
ff disable_vga=1 vfio_iommu_type1.allow_unsafe_interrupts=1 kvm.ignore_msrs=1 modprobe.blacklist=radeon,nouveau,nvidia,nvidiafb,nvidia-gpu,snd_hda_intel,snd_hda_codec_hdmi,i915"
Esprimo:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt video=efifb
ff video=vesafb
ff initcall_blacklist=sysfb_init"
update-grub
reboot
cat /proc/cmdline
You must see: intel_iommu=on and iommu=pt in the output.
dmesg | grep -e DMAR -e IOMMU
You must see: [0.067203] DMAR: IOMMU enabled
STEP 2 – BIND THE IGPU TO VFIO
Esprimo:
------------------------------------
lspci -nn | grep VGA
lspci -nn | grep Audio
For the ESPRIMO you should see 8086:5912 and 806:a2f0:
00:02.0 VGA compatible controller [0300]: Intel Corporation HD Graphics 630 [8086:5912] (rev 04)
00:1f.3 Audio device [0403]: Intel Corporation 200 Series PCH HD Audio [8086:a2f0]
Create the VFIO config:
nano /etc/modprobe.d/vfio.conf
# don't load driver for iGPU and sound card
blacklist i915
blacklist snd_hda_intel
blacklist snd_sof_pci_intel_cnl
# load vfio-pci driver instead
options vfio-pci ids=8086:5912,8086:a2f0 disable_vga=1
#
#options kvm ignore_msrs=1
#options vfio_iommu_type1 allow_unsafe_interrupts=1
Execute: update-initramfs -u
------------------------------------
N100/Esprimo:
------------------------------------
nano /etc/modules
# Modules required for PCI passthrough
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
update-initramfs -u -k all
------------------------------------
Reboot
lspci -nnk
You must see for Video and Audio device:
Kernel driver in use: vfio-pci or nothing, no kernel in use
you don't want to see anything like: Kernel driver in use: i915 but Kernel modules: i915 is ok!
STEP 3 – DOWNLOAD AND INJECT INTEL GOP ROM
This is possibly required for Alder Lake / Raptor Lake / N100) mobile.
Install git if needed:
apt update
apt install git -y
STEP 4 – CREATE Debian VM (VM100)
Create VM normally in the GUI:
N100:
VM ID 100
BIOS: OVMF incl EFI disk
Display: Default
Install Debian completely via Console/Shell
Start Debian
sudo shutdown -h now
Esprimo:
VM ID: 100
BIOS: OVMF incl EFI disk
Display: Default
Install Debian completely via Console/Shell
Start Debian and install (Bug: if not installed, Debian will not boot on Esprimo –> Black Screen)
sudo apt update && apt upgrade -y
sudo apt install --reinstall linux-image-generic linux-headers-generic
sudo shutdown -h now
After installation, shut down in VM100.
STEP 5 – APPLY FINAL WORKING CONFIGURATION
Stop the VM if running:
qm stop 100
Edit the VM config in GUI:
N100:
VM ID 100
BIOS: OVMF incl EFI disk
Display: Default
CPU: host
Machine: q35
PCI Device VGA: Raw device, 0000:00:02.0, Primary GPU, All Functions, Rom Bar, PCI Express
PCI Device Audio: Raw device, 0000:00:1f.0, All Functions, Rom Bar, PCI Express
Add USB Vendor/Devices Ids of devices needed
Esprimo:
VM ID: 100
BIOS: OVMF incl EFI disk
Display: none
CPU: Default kvm64
Machine: pc
PCI Device VGA: Raw device, 0000:00:02.0, Rom Bar
PCI Device Audio: Raw device, 0000:00:1f.3,
Add USB Vendor/Devices Ids of devices needed
STEP 6 – APPLY AUDIO WORKAROUND CONFIGURATION
The command
pvesh get /nodes/<your_node_name_in_PROXMOX>/hardware/pci --pci-class-blacklist ""
shows, that PCI devices use sometimes the same IOMMU Group. That why Audio device handover to VM doesn’t work without woraround:
On Proxmox Host:
crontab -e
@reboot /root/passthrough-tweak.sh
nano /root/passthrough-tweak.sh
N100:
#!/usr/bin/bash
#
# put `0:1f.*` into separate iommu groups
#
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.0/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.3/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.4/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.5/remove
echo 1 > /sys/bus/pci/rescan
#
# `0:1f.6` is NIC. Need restart networking
#
#systemctl restart networking
#systemctl restart netbird
sleep 10
ESPRIMO:
#!/usr/bin/bash
#
# put `0:1f.*` into separate iommu groups
#
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.0/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.2/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.3/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.4/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.5/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.6/remove # Bei N100 auskommentieren
echo 1 > /sys/bus/pci/rescan
#
# `0:1f.6` is NIC. Need restart networking
#
systemctl restart networking # Bei N100 auskommentieren
systemctl restart netbird # Bei N100 auskommentieren
sleep 10
Make it executable:
chmod +x passthrough-tweak.sh
nano /var/lib/vz/snippets/vm100-hooks.sh
#!/usr/bin/bash
# ref: https://gist.github.com/kiler129/215e2c8de853209ca429ad5ed40ce128
set -e -o errexit -o pipefail -o nounset
# Do not modify these variables (set by Proxmox when calling the script)
vmId="$1"
runPhase="$2"
echo "Entering $runPhase on VM=$vmId"
case "$runPhase" in
pre-start)
;;
post-start)
;;
pre-stop)
echo "
- Running $runPhase hook on VM=$vmId"
source /root/passthrough-tweak.sh
echo "
- Finished $runPhase hook on VM=$vmId"
;;
post-stop)
;;
*)
echo "Unknown run phase \"$runPhase\"!"
;;
esac
# qm set 100 --hookscript local:snippets/vm100-hooks.sh
chmod +x /var/lib/vz/snippets/vm100-hooks.sh
With all these steps, the DP audio output issue is most like resolved, with the following limitations:
- To restart the VM, one needs to execute qm stop 100 && qm start 100 on the pve host; Reboot from VM itself does not trigger the hooks.
- Each time the VM stops, the host network will be reset once (and re-enabled short after). So far ssh connection seems not broken during the reset, but it may impact critical network traffic. Adding a USB NIC for the host (and leaving 0:1f.6 un-used) might be a choice.
STEP 6 – FULL POWER OFF
Do NOT just reboot.
Run: shutdown -h now
Wait 20 seconds.
Power the NUC back on.
Start the VM:
qm start 100
Activate Video HW acceleration and driver compatibility while boot in der VM in Debian
sudo apt update
sudo apt install -y intel-media-va-driver-non-free intel-gpu-tools vainfo intel-media-va-driver i965-va-driver-shaders firmware-misc-nonfree
Error: No installation candidate exists for package »intel-media-va-driver-non-free«.
Error: No installation candidate exists for package »i965-va-driver-shaders«.
You need the following entries: main contribute non-free non-free firmware.
Edit file: Open the file with an editor, e.g. sudo nano/etc/apt/sources.list.d/debian.sources or sudo nano/etc/apt/sources.list
Customize rows: Add the repositories. A typical line then looks like this:
deb http://deb.debian.org/debian/ trixie main contribute non-free non-free firmware
sudo apt update
sudo apt install -y intel-gpu-tools vainfo intel-media-va-driver i965-va-driver-shaders firmware-misc-nonfree
Optional intel-media-va-driver-non-free if intel-media-va-driver is not already installed
then check if the hardware acceleration is enabled with:
vainfo
Hint: TFT-Monitor-USB-HUB on USB3.0 port can crash he system. USB2.0 port needs to be used.
Configs:
N100:
--------
balloon: 0
bios: ovmf
boot: order=ide2;scsi0;net0
cores: 4
cpu: host
efidisk0: local-lvm:vm-101-disk-0,efitype=4m,ms-cert=2023,pre-enrolled-keys=1,size=4M
hostpci0: 0000:00:02,pcie=1,x-vga=1
hostpci1: 0000:00:1f,pcie=1
ide2: none,media=cdrom
machine: q35
memory: 12000
meta: creation-qemu=10.1.2,ctime=1770902363
name: Debian-VGAN100
net0: virtio=BC:24:11:C5:8A:EB,bridge=vmbr0,firewall=1
numa: 0
onboot: 1
ostype: l26
scsi0: local-lvm:vm-101-disk-1,discard=on,iothread=1,size=128G,ssd=1
scsihw: virtio-scsi-single
smbios1: ...
sockets: 1
usb0: host=046d:c52b
usb1: host=0573:1573
usb2: host=0bda:b85b
usb3: host=05e3:0732
usb4: host=1-4
usb5: host=1-5
usb6: host=1-6
usb7: host=0951:1666
ESPRIMO:
--------
agent: 0,type=isa
bios: ovmf
boot: order=scsi0;ide2;net0
cores: 3
efidisk0: local-lvm:vm-100-disk-0,efitype=4m,ms-cert=2023w,pre-enrolled-keys=1,size=4M
hostpci0: 0000:00:02.0
hostpci1: 0000:00:1f.3,rombar=0
ide2: local:iso/debian-13.3.0-amd64-netinst.iso,media=cdrom,size=754M
machine: pc
memory: 8000
meta: creation-qemu=10.1.2,ctime=1771193357
name: Debian-Esprimo-VGA
net0: virtio=BC:24:11:8E:8D:FA,bridge=vmbr0,firewall=1
numa: 0
ostype: l26
scsi0: local-lvm:vm-100-disk-1,discard=on,iothread=1,size=128G,ssd=1
scsihw: virtio-scsi-single
smbios1: ...
sockets: 1
usb0: host=0c45:7403
usb1: host=1-2
vga: none
HARDWARE
Model: Mini PC with Intel N100 or Fujitsu Esprimo Q957 with Intel i5 7500
iGPU: Intel UHD Graphics, no additional GPU installed
Host OS: Proxmox VE 9.1.5
Guest: Debian (VMID 100)
Goal: Use the NUC as a Proxmox host AND as a local Debian desktop via HDMI.
Enter BIOS (F2 at boot)
Display: Auto
Secure Boot → disabled
UEFI Boot → enabled
CSM → Disabled (if present)
Save and exit.
STEP 1 – ENABLE IOMMU
Open Proxmox shell on Host.
nano /etc/default/grub
Replace the line starting with GRUB_CMDLINE_LINUX_DEFAULT with:
N100/Esprimo:
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt pcie_acs_override=downstream,multifunction initcall_blacklist=sysfb_init video=simplefb
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on iommu=pt video=efifb
update-grub
reboot
cat /proc/cmdline
You must see: intel_iommu=on and iommu=pt in the output.
dmesg | grep -e DMAR -e IOMMU
You must see: [0.067203] DMAR: IOMMU enabled
STEP 2 – BIND THE IGPU TO VFIO
------------------------------------
lspci -nn | grep VGA
lspci -nn | grep Audio
For the ESPRIMO you should see 8086:5912 and 806:a2f0:
00:02.0 VGA compatible controller [0300]: Intel Corporation HD Graphics 630 [8086:5912] (rev 04)
00:1f.3 Audio device [0403]: Intel Corporation 200 Series PCH HD Audio [8086:a2f0]
Create the VFIO config:
nano /etc/modprobe.d/vfio.conf
# don't load driver for iGPU and sound card
blacklist i915
blacklist snd_hda_intel
blacklist snd_sof_pci_intel_cnl
# load vfio-pci driver instead
options vfio-pci ids=8086:5912,8086:a2f0 disable_vga=1
#
#options kvm ignore_msrs=1
#options vfio_iommu_type1 allow_unsafe_interrupts=1
Execute: update-initramfs -u
------------------------------------
N100/Esprimo:
------------------------------------
nano /etc/modules
# Modules required for PCI passthrough
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
update-initramfs -u -k all
------------------------------------
Reboot
lspci -nnk
You must see for Video and Audio device:
Kernel driver in use: vfio-pci or nothing, no kernel in use
you don't want to see anything like: Kernel driver in use: i915 but Kernel modules: i915 is ok!
STEP 3 – DOWNLOAD AND INJECT INTEL GOP ROM
This is possibly required for Alder Lake / Raptor Lake / N100) mobile.
Install git if needed:
apt update
apt install git -y
STEP 4 – CREATE Debian VM (VM100)
Create VM normally in the GUI:
N100:
VM ID 100
BIOS: OVMF incl EFI disk
Display: Default
Install Debian completely via Console/Shell
Start Debian
sudo shutdown -h now
Esprimo:
VM ID: 100
BIOS: OVMF incl EFI disk
Display: Default
Install Debian completely via Console/Shell
Start Debian and install (Bug: if not installed, Debian will not boot on Esprimo –> Black Screen)
sudo apt update && apt upgrade -y
sudo apt install --reinstall linux-image-generic linux-headers-generic
sudo shutdown -h now
After installation, shut down in VM100.
STEP 5 – APPLY FINAL WORKING CONFIGURATION
Stop the VM if running:
qm stop 100
Edit the VM config in GUI:
N100:
VM ID 100
BIOS: OVMF incl EFI disk
Display: Default
CPU: host
Machine: q35
PCI Device VGA: Raw device, 0000:00:02.0, Primary GPU, All Functions, Rom Bar, PCI Express
PCI Device Audio: Raw device, 0000:00:1f.0, All Functions, Rom Bar, PCI Express
Add USB Vendor/Devices Ids of devices needed
Esprimo:
VM ID: 100
BIOS: OVMF incl EFI disk
Display: none
CPU: Default kvm64
Machine: pc
PCI Device VGA: Raw device, 0000:00:02.0, Rom Bar
PCI Device Audio: Raw device, 0000:00:1f.3,
Add USB Vendor/Devices Ids of devices needed
STEP 6 – APPLY AUDIO WORKAROUND CONFIGURATION
The command
pvesh get /nodes/<your_node_name_in_PROXMOX>/hardware/pci --pci-class-blacklist ""
shows, that PCI devices use sometimes the same IOMMU Group. That why Audio device handover to VM doesn’t work without woraround:
On Proxmox Host:
crontab -e
@reboot /root/passthrough-tweak.sh
nano /root/passthrough-tweak.sh
N100:
#!/usr/bin/bash
#
# put `0:1f.*` into separate iommu groups
#
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.0/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.3/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.4/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.5/remove
echo 1 > /sys/bus/pci/rescan
#
# `0:1f.6` is NIC. Need restart networking
#
#systemctl restart networking
#systemctl restart netbird
sleep 10
ESPRIMO:
#!/usr/bin/bash
#
# put `0:1f.*` into separate iommu groups
#
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.0/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.2/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.3/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.4/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.5/remove
echo 1 > /sys/bus/pci/devices/0000\:00\:1f.6/remove # Bei N100 auskommentieren
echo 1 > /sys/bus/pci/rescan
#
# `0:1f.6` is NIC. Need restart networking
#
systemctl restart networking # Bei N100 auskommentieren
systemctl restart netbird # Bei N100 auskommentieren
sleep 10
Make it executable:
chmod +x passthrough-tweak.sh
nano /var/lib/vz/snippets/vm100-hooks.sh
#!/usr/bin/bash
# ref: https://gist.github.com/kiler129/215e2c8de853209ca429ad5ed40ce128
set -e -o errexit -o pipefail -o nounset
# Do not modify these variables (set by Proxmox when calling the script)
vmId="$1"
runPhase="$2"
echo "Entering $runPhase on VM=$vmId"
case "$runPhase" in
pre-start)
;;
post-start)
;;
pre-stop)
echo "
- Running $runPhase hook on VM=$vmId"
source /root/passthrough-tweak.sh
echo "
- Finished $runPhase hook on VM=$vmId"
;;
post-stop)
;;
*)
echo "Unknown run phase \"$runPhase\"!"
;;
esac
# qm set 100 --hookscript local:snippets/vm100-hooks.sh
chmod +x /var/lib/vz/snippets/vm100-hooks.sh
With all these steps, the DP audio output issue is most like resolved, with the following limitations:
- To restart the VM, one needs to execute qm stop 100 && qm start 100 on the pve host; Reboot from VM itself does not trigger the hooks.
- Each time the VM stops, the host network will be reset once (and re-enabled short after). So far ssh connection seems not broken during the reset, but it may impact critical network traffic. Adding a USB NIC for the host (and leaving 0:1f.6 un-used) might be a choice.
STEP 6 – FULL POWER OFF
Do NOT just reboot.
Run: shutdown -h now
Wait 20 seconds.
Power the NUC back on.
Start the VM:
qm start 100
Activate Video HW acceleration and driver compatibility while boot in der VM in Debian
sudo apt update
sudo apt install -y intel-media-va-driver-non-free intel-gpu-tools vainfo intel-media-va-driver i965-va-driver-shaders firmware-misc-nonfree
Error: No installation candidate exists for package »intel-media-va-driver-non-free«.
Error: No installation candidate exists for package »i965-va-driver-shaders«.
You need the following entries: main contribute non-free non-free firmware.
Edit file: Open the file with an editor, e.g. sudo nano/etc/apt/sources.list.d/debian.sources or sudo nano/etc/apt/sources.list
Customize rows: Add the repositories. A typical line then looks like this:
deb http://deb.debian.org/debian/ trixie main contribute non-free non-free firmware
sudo apt update
sudo apt install -y intel-gpu-tools vainfo intel-media-va-driver i965-va-driver-shaders firmware-misc-nonfree
Optional intel-media-va-driver-non-free if intel-media-va-driver is not already installed
then check if the hardware acceleration is enabled with:
vainfo
Hint: TFT-Monitor-USB-HUB on USB3.0 port can crash he system. USB2.0 port needs to be used.
Configs:
N100:
--------
balloon: 0
bios: ovmf
boot: order=ide2;scsi0;net0
cores: 4
cpu: host
efidisk0: local-lvm:vm-101-disk-0,efitype=4m,ms-cert=2023,pre-enrolled-keys=1,size=4M
hostpci0: 0000:00:02,pcie=1,x-vga=1
hostpci1: 0000:00:1f,pcie=1
ide2: none,media=cdrom
machine: q35
memory: 12000
meta: creation-qemu=10.1.2,ctime=1770902363
name: Debian-VGAN100
net0: virtio=BC:24:11:C5:8A:EB,bridge=vmbr0,firewall=1
numa: 0
onboot: 1
ostype: l26
scsi0: local-lvm:vm-101-disk-1,discard=on,iothread=1,size=128G,ssd=1
scsihw: virtio-scsi-single
smbios1: ...
sockets: 1
usb0: host=046d:c52b
usb1: host=0573:1573
usb2: host=0bda:b85b
usb3: host=05e3:0732
usb4: host=1-4
usb5: host=1-5
usb6: host=1-6
usb7: host=0951:1666
ESPRIMO:
--------
agent: 0,type=isa
bios: ovmf
boot: order=scsi0;ide2;net0
cores: 3
efidisk0: local-lvm:vm-100-disk-0,efitype=4m,ms-cert=2023w,pre-enrolled-keys=1,size=4M
hostpci0: 0000:00:02.0
hostpci1: 0000:00:1f.3,rombar=0
ide2: local:iso/debian-13.3.0-amd64-netinst.iso,media=cdrom,size=754M
machine: pc
memory: 8000
meta: creation-qemu=10.1.2,ctime=1771193357
name: Debian-Esprimo-VGA
net0: virtio=BC:24:11:8E:8D:FA,bridge=vmbr0,firewall=1
numa: 0
ostype: l26
scsi0: local-lvm:vm-100-disk-1,discard=on,iothread=1,size=128G,ssd=1
scsihw: virtio-scsi-single
smbios1: ...
sockets: 1
usb0: host=0c45:7403
usb1: host=1-2
vga: none
Last edited: