Ви зробили «просто» — передали GPU в ВМ. ВМ завантажується. Монітор залишається чорним. Гість може бути живим — RDP працює, SSH працює, але локальний дисплей мертвий, ніби екран у конференц-залі з неправильним входом.
Passthrough GPU в Proxmox не є складним. Він просто нещадний. Одна невірна прошивка, одне хибне припущення про ROM/GOP, одна дивна поведінка скидання GPU — і ви отримуєте той самий симптом: нічого на екрані.
Швидка діагностика (спочатку перевірте це)
Ця послідовність — «зупиніться з хаотичними діями». Вона оптимізована для отримання першого сигналу і уникає зайвих відгалужень, наприклад, копирсання в випадкових прапорцях QEMU до підтвердження базових речей.
1) Підтвердіть, що гість живий чи мертвий
- Якщо Windows завантажується і ви можете підключитися по RDP: ймовірно, проблема з ініціацією дисплея (прошивка/ROM/первинний дисплей), а не повна невдача passthrough.
- Якщо ВМ зовсім не завантажується: підозрюйте IOMMU, прив’язку до VFIO або проблему жорсткого скидання/зависання.
2) Перевірте, чи IOMMU дійсно увімкнено і чи групи мають сенс
Якщо IOMMU не увімкнено, ви не робите passthrough; ви просто танцюєте у вакуумі.
3) Переконайтесь, що GPU на хості прив’язано до vfio-pci
Чорні екрани часто виникають, коли драйвер хоста перехопив карту першим, залишивши VFIO з крихтами (або напівініціалізованим пристроєм).
4) Підберіть прошивку відповідно до вимог GPU: OVMF для карт з UEFI GOP
Сучасні GPU, особливо якщо ви хочете, щоб GPU був первинним дисплеєм у гості, зазвичай працюють найкраще з OVMF + Q35.
5) Вирішіть, чи потрібен файл ROM
Якщо GPU ніколи не показує вивід до завантаження драйвера гостя (або ніколи не показує взагалі), можливо, потрібно надати чистий ROM з дійсним GOP, або заборонити хосту «постити» його.
6) Якщо колись працювало, але після перезавантаження ВМ — ні: підозрюйте баг скидання
Успіх при першому завантаженні, а потім чорний екран при наступних — класика «GPU не скидається». Ставтеся до цього, як до основної гіпотези, поки не доведено інше.
Що насправді означає «чорний екран» при passthrough
«Чорний екран» — це розмита ознака. Потрібно визначити, який із наступних варіантів ви бачите:
- Немає сигналу на моніторі: GPU ніколи не штовхає сигнал через роз’єм (ініціалізація не відбулася, неправильний первинний пристрій або GPU все ще належить хосту/прошивці).
- Є сигнал, але чорне зображення: лінк піднятий, але фреймбуфер не виводиться (несумісність драйвера/прошивки, помилка роздільності, гість завис до графічної передачі управління).
- Показує заставку OVMF, а потім чорний екран: прошивка ініціалізувала карту; передача керування ОС/драйверу гостя провалюється (конфлікти драйверів Windows, Code 43, проблеми modesetting в Linux).
- Працює лише після холодного старту: баг скидання або проблема станів живлення (відсутній FLR, переходи до D3cold, специфічна поведінка вендора).
- Працює лише з dummy HDMI донглом: проблеми EDID/детекції монітора, особливо при віддалених сесіях або безголовому налаштуванні.
Операційне правило: відокремлюйте «успішне призначення пристрою» від «успішного виводу на дисплей». VFIO може ідеально призначити GPU, але гість ніколи не зуміє освітити екран.
Точна цитата, бо вона тут доречна: reliability comes from disciplined operations and eliminating classes of failure, not hero debugging at 2 a.m.
— James Hamilton.
Цікаві факти та історичний контекст (бо в цього безладу є передісторія)
- PCI passthrough існує задовго до «homelab GPU passthrough». Підприємницькі гіпервізори використовували пряме призначення пристроїв для NIC і HBA задовго до того, як геймери відкрили для себе VFIO.
- UEFI GOP змінив гру для раннього завантаження дисплея. Опціональні ROMи для VGA в епоху BIOS були достатні; UEFI віддає перевагу ROM з підтримкою GOP для чистої ініціалізації графіки.
- OVMF — це фактично UEFI для QEMU. Це відкрита прошивка, що робить UEFI-ВМ практичними в KVM-середовищах.
- IOMMU був зумовлений безпекою DMA так само, як і віртуалізацією. Без DMA remapping пристрій може записувати пам’ять довільно. Passthrough без IOMMU — це кошмар безпеки.
- ACS (Access Control Services) існує для ізоляції трафіку PCIe. Побутові плати часто економлять на цьому, тому люди вдаються до ACS override і потім дивуються, коли ізоляція неповна.
- «Скидання» — це не один механізм. FLR, bus reset, переходи живлення та вендор-специфічні скидання GPU поводяться по-різному.
- Деякі GPU — це багатофункціональні пристрої. Аудіофункція (HDMI/DP audio) та USB-контролер (на деяких картах) треба передавати разом, інакше виникає дивна поведінка.
- Історія Code 43 від NVIDIA сформувала культуру passthrough. Поведінка драйверів у віртуалізованих середовищах штовхнула людей до обхідних рішень, а потім до краще підтримуваних конфігурацій.
- Resizable BAR змінила очікування. Великі відображення BAR можуть навантажувати прошивку/налаштування хоста і іноді виявляти баги в ініціалізації платформи.
Жарт 1: Passthrough GPU — це єдине хобі, де «Я змінив один рядок у GRUB і перезавантажився вісім разів» вважається тихим вечором.
UEFI/OVMF vs SeaBIOS: виберіть те, що відповідає реальності
Якщо запам’ятати одне: не обирайте SeaBIOS тільки тому, що він здається «простішим». Обирайте прошивку відповідно до того, чого очікують GPU і гостьова ОС.
Коли OVMF — правильний вибір
- Вам потрібен Windows 11, Secure Boot увімкнений/вимкнений або сучасне UEFI-завантаження.
- Ви хочете, щоб переданий GPU був первинним дисплеєм.
- Опціональний ROM вашої карти орієнтований на UEFI (поширено для нових карт).
- Ви бажаєте більш передбачувану поведінку з Q35 та топологією PCIe.
Коли SeaBIOS ще може працювати
- Старі GPU з надійними legacy VGA ROM.
- Старі інсталяції ОС, які були створені для BIOS-завантаження.
- Специфічні крайові випадки, де UEFI GOP ініціалізація створює проблему, а legacy ініціалізація працює.
Типові підводні камені OVMF, що виглядають як «GPU зламався»
- Неправильний порядок пристроїв дисплея: якщо ви залишили віртуальний VGA (наприклад SPICE/QXL), гість може використовувати його як первинний, і ваш переданий GPU може не показати зображення, поки не завантажаться драйвери — або взагалі не показати.
- Проблеми з OVMF variable store: пошкоджений NVRAM-файл може загнати в дивні стани завантаження. Перегенеруйте його замість безрезультатних спроб виправити.
- CSM-очікування: UEFI-only гість може не завантажуватися з BIOS-форматованих дисків; це може маскуватися під «немає відеовиходу».
Файли ROM, GOP і чому ваш GPU іноді «потребує ROM»
GPU ROM (option ROM) — це прошивка, яка ініціалізує карту під час раннього завантаження. У passthrough QEMU може спробувати використати ROM пристрою, але є кілька перешкод:
- Прошивка хоста може вже опублікувати (posted) GPU, залишивши його в стані, якого очікує інша прошивка гостя.
- Пристрій може не відкрити читальний регіон ROM, як тільки драйвер хоста прикріпиться до нього.
- Деякі ROM вендорів містять і legacy VGA, і UEFI GOP; деякі — лише одне; деякі — «креативні».
Коли надання ROM файлу — перевірене рішення
- Чорний екран під час завантаження, але GPU працює на інших машинах або на bare metal.
- OVMF ніколи не показує свою заставку на виводі GPU.
- GPU не є первинним дисплеєм при завантаженні і ніколи не ініціалізується належним чином.
- Багаторічні налаштування, де хост постить одну карту, а ви передаєте іншу.
Коли ROM файл погіршує ситуацію
- Ви використовуєте ROM, дампований з іншого SKU або іншої ревізії плати.
- ROM містить специфічні для плати установки (straps), що не відповідають вашій карті.
- Ви обрізали або «поправили» ROM неправильно (особливо на NVIDIA-картах з заголовками).
У виробничому сенсі: ROM файл — це хірургічний інструмент, а не талісман удачі. Якщо в вас немає вагомої причини, не вводьте ще одну змінну.
Баги скидання PCIe: FLR, D3hot/D3cold та хаос з AMD
Скидання — це те, звідки походить більшість історій «вчора працювало». GPU може бути передано чисто, використаний, а потім не повернутися після перезавантаження гостя або зупинки/запуску ВМ.
Три патерни скидання, які ви побачите
- Лише холодний старт: GPU працює після повного вимкнення живлення хоста, але не після рестарту ВМ. Це розрив ініціалізації/скидання.
- Забруднення драйвером хоста: драйвер хоста прикріплюється один раз (навіть ненадовго), ініціалізує GPU, а потім VFIO передає дивно сконфігурований пристрій гостю.
- Часткове скидання функції: графічна функція скидається, але аудіофункція (або USB) — ні, що викликає проблеми з перерахуванням або дивну поведінку драйверів.
FLR — це не гарантія
Function Level Reset є опціональним. Деякі GPU його заявляють, деякі некоректно реалізують, а платформи іноді не передають його чисто. Ви не можете «вірити» в FLR замість перевірки.
Реальність «AMD reset bug»
Старі AMD карти (і деякі не надто старі) відомі тим, що не скидаються в чистий стан для повторного використання VFIO. Обхідні шляхи спільноти варіюються від модулів vendor-reset до перемикання станів живлення; результати залежать від версії ядра, покоління карт і материнської плати.
Жарт 2: Найшвидший спосіб перевірити, чи у вас баг скидання — перезавантажити ВМ: ваша GPU миттєво подасть на розлучення.
Прив’язка на хості, vfio-pci і боротьба драйверів
Хост не повинен «допомагати». Якщо хост перехоплює GPU з nvidia, amdgpu або nouveau до того, як VFIO зробить це, ви часто отримаєте чорний екран або, гірше, GPU, який напівпрацює і потім зависає.
Як має виглядати правильно
- Під час завантаження функції GPU прив’язані до
vfio-pci. - Консоль хоста використовує інший GPU, iGPU або серійну консоль.
- Proxmox запускає ВМ, QEMU захоплює PCIe-пристрій, і драйвер гостя бачить чистий ексклюзивний GPU.
Як виглядає майже правильно
- GPU прив’язано до
vfio-pci, але драйвер framebuffer хоста все ще має його змепленим. - Аудіофункція HDMI все ще прив’язана до
snd_hda_intel. - Існує IOMMU група з USB-контролером або SATA-контролером «прив’язаними» до GPU, а ви передали лише GPU.
Q35 vs i440fx, первинний GPU і пристрої дисплея, які вам шкодять
У Proxmox ви обираєте тип машини. Сприймайте це як апаратне забезпечення.
Q35 зазвичай раціональний вибір
Q35 моделює сучасніший чіпсет з PCIe root ports. Це важливо для GPU, які очікують поведінки PCIe, і може впливати на скидання та порядок перерахування пристроїв.
i440fx — спадкова сумісність
Іноді ви використовуєте його, бо старий гість очікує саме цього. Для сучасного passthrough GPU Q35 зазвичай зменшує кількість дивних ситуацій.
Passthrough первинного GPU: прибирайте конкурентні віртуальні дисплеї
Якщо ви хочете, щоб переданий GPU був екраном завантаження, не залишайте віртуальний VGA як очевидний первинний пристрій. В термінах Proxmox: встановіть vga: none, якщо ви серйозно налаштовані використовувати фізичний GPU для консолі.
Практичні завдання (команди, що означає вивід і яке рішення прийняти)
Це реальні операційні завдання. Запускайте їх на хості Proxmox, якщо не зазначено інше. Кожен містить «що далі» рішення, бо вивід без рішення — це просто логування заради забави.
Завдання 1: Підтвердіть, що CPU і ядро бачать розширення віртуалізації
cr0x@server:~$ egrep -m1 '(vmx|svm)' /proc/cpuinfo
flags : fpu vme de pse tsc ... vmx ...
Значення: повинен бути vmx (Intel) або svm (AMD). Якщо його немає, жодна подорож IOMMU/VFIO не матиме гарного кінця.
Рішення: Якщо відсутній — виправте налаштування BIOS (VT-x/AMD-V) перш ніж міняти конфіги Proxmox.
Завдання 2: Підтвердіть, що IOMMU увімкнено в командному рядку ядра
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.12-2-pve root=/dev/mapper/pve-root ro quiet intel_iommu=on iommu=pt
Значення: Шукайе intel_iommu=on або amd_iommu=on. iommu=pt часто використовується, щоб зменшити накладні витрати для пристроїв без passthrough.
Рішення: Якщо відсутній — відредагуйте GRUB і перезавантажте; не продовжуйте поки цього немає.
Завдання 3: Перевірте, чи DMAR/IVRS показує, що IOMMU дійсно ініціалізовано
cr0x@server:~$ dmesg | egrep -i 'DMAR|IOMMU|IVRS' | head -n 8
[ 0.824112] DMAR: IOMMU enabled
[ 0.824980] DMAR: Host address width 39
[ 0.835010] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
Значення: Хочете бачити «IOMMU enabled» і відсутність фатальних помилок.
Рішення: Якщо бачите повідомлення про відключення або помилки, виправте BIOS (VT-d/AMD-Vi) або параметри ядра перед продовженням.
Завдання 4: Ідентифікуйте GPU та всі його функції (графіка + аудіо + додатки)
cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|audio|nvidia|amd'
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184]
01:00.1 Audio device [0403]: NVIDIA Corporation TU116 High Definition Audio Controller [10de:1aeb]
Значення: Зауважте ідентифікатори пристроїв та функцій. Аудіофункція на практиці не є необов’язковою — її теж треба передати.
Рішення: Плануйте передати і 01:00.0, і 01:00.1.
Завдання 5: Перевірте IOMMU групи (істина ізоляції)
cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do echo "$(basename "$(dirname "$d")") $(lspci -nns ${d##*/})"; done | sort -n | sed -n '1,18p'
1 00:01.0 Host bridge [0600]: Intel Corporation Device [8086:1237]
12 01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184]
12 01:00.1 Audio device [0403]: NVIDIA Corporation TU116 High Definition Audio Controller [10de:1aeb]
Значення: Ваші функції GPU мають ідеально бути в групі самі по собі (або принаймні тільки одна з одною).
Рішення: Якщо група включає невідносні пристрої (USB/SATA), потрібно інше розташування/налаштування материнської плати або прийняття ризику ACS override (див. далі).
Завдання 6: Підтвердіть, який драйвер зараз володіє GPU
cr0x@server:~$ lspci -nnk -s 01:00.0
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU116 [GeForce GTX 1660] [10de:2184]
Subsystem: Micro-Star International Co., Ltd. [MSI] TU116 [1462:12a3]
Kernel driver in use: vfio-pci
Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
Значення: «Kernel driver in use» має бути vfio-pci. Модулі в списку — це просто доступні модулі, не обов’язково завантажені.
Рішення: Якщо вказано nvidia або amdgpu, виправте прив’язку драйверів (Завдання 7/8).
Завдання 7: Завантажте модулі VFIO і перевірте їх наявність
cr0x@server:~$ lsmod | egrep 'vfio|kvm'
vfio_pci 16384 0
vfio_pci_core 90112 1 vfio_pci
vfio_iommu_type1 40960 0
vfio 69632 2 vfio_iommu_type1,vfio_pci_core
kvm_intel 376832 0
kvm 1105920 1 kvm_intel
Значення: Якщо модулі VFIO не завантажені, Proxmox може завантажити їх по вимозі, але явний підхід краще за містичний.
Рішення: Якщо відсутні — додайте vfio модулі в /etc/modules і перебудуйте initramfs.
Завдання 8: Прив’яжіть GPU до vfio-pci за ID пристроїв (надійний метод)
cr0x@server:~$ cat /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:2184,10de:1aeb disable_vga=1
Значення: Це каже ядру прив’язати ці PCI ID до VFIO рано. disable_vga=1 може зменшити конфлікти арбітрації legacy VGA.
Рішення: Якщо ви змінили цей файл, перебудуйте initramfs і перезавантажте (Завдання 9).
Завдання 9: Перебудуйте initramfs і підтвердіть оновлення
cr0x@server:~$ update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-6.8.12-2-pve
Running hook script 'zz-proxmox-boot'..
Re-executing '/etc/kernel/postinst.d/zz-proxmox-boot' in new private mount namespace..
Значення: Ваш ранній середовище завантаження тепер знає про правила прив’язки VFIO.
Рішення: Перезавантажте перед наступним тестом; гарячі зміни ненадійні для таких експериментів.
Завдання 10: Перевірте, чи хост все ще використовує framebuffer на GPU
cr0x@server:~$ dmesg | egrep -i 'fb0|framebuffer|efifb|simplefb|vesafb' | tail -n 8
[ 0.612345] simple-framebuffer simple-framebuffer.0: framebuffer at 0xe0000000, 0x300000 bytes
[ 0.612400] fb0: simplefb registered!
Значення: Якщо хост використовує переданий GPU для framebuffer-консолі, ви можете отримати чорні екрани або скидання, що ніколи не працюють повністю.
Рішення: Віддавайте перевагу безголовій консолі (серійній), iGPU або другому GPU для хоста. Якщо потрібно, відключіть використання framebuffer хостом (залежить від платформи).
Завдання 11: Підтвердіть, що конфіг ВМ використовує OVMF + Q35 і не краде первинний дисплей
cr0x@server:~$ qm config 101
boot: order=scsi0;ide2;net0
bios: ovmf
machine: q35
scsi0: local-lvm:vm-101-disk-0,size=128G
hostpci0: 0000:01:00.0,pcie=1,x-vga=1
hostpci1: 0000:01:00.1,pcie=1
vga: none
Значення: bios: ovmf і machine: q35 — звичайна комбінація, що «частіше працює». vga: none запобігає додаванню Proxmox конкурента дисплея.
Рішення: Якщо бачите bios: seabios і сучасну GPU/ОС — перейдіть на OVMF і перевстановіть або конвертуйте режим завантаження при потребі.
Завдання 12: Слідкуйте за помилками QEMU/VFIO під час старту ВМ
cr0x@server:~$ journalctl -u pvedaemon -u pve-qemu-server --since "10 min ago" | tail -n 60
... vfio-pci 0000:01:00.0: vfio_bar_restore: reset recovery - restoring BARs
... qemu-system-x86_64: vfio: Unable to power on device, stuck in D3
... start failed: QEMU exited with code 1
Значення: «stuck in D3» — це проблема стану живлення/скидання. Це не проблема драйвера Windows; це поведінка хоста/пристрою при скиданні.
Рішення: Розглядайте як баг скидання: оновлення ядра, зміна слоту, відключення ASPM або підходи vendor-reset (Завдання 16/17).
Завдання 13: Дамп ROM GPU (тільки якщо є причина)
cr0x@server:~$ echo 1 | sudo tee /sys/bus/pci/devices/0000:01:00.0/rom
1
cr0x@server:~$ sudo cat /sys/bus/pci/devices/0000:01:00.0/rom > /root/gpu.rom
cr0x@server:~$ echo 0 | sudo tee /sys/bus/pci/devices/0000:01:00.0/rom
0
cr0x@server:~$ ls -lh /root/gpu.rom
-rw-r--r-- 1 root root 256K Jan 8 12:14 /root/gpu.rom
Значення: Ви отримали ROM-зображення правдоподібного розміру. Якщо це падає з «Operation not permitted» або нульовими байтами, пристрій може бути прив’язаний/posted так, що блокує читання.
Рішення: Якщо можете дампити — використайте як ROM-файл. Якщо не можете — не лізьте грубо: виправте прив’язку/posted стан спочатку.
Завдання 14: Прикріпіть ROM файл до ВМ (цільовий експеримент)
cr0x@server:~$ qm set 101 --hostpci0 0000:01:00.0,pcie=1,x-vga=1,romfile=gpu.rom
update VM 101: -hostpci0 0000:01:00.0,pcie=1,x-vga=1,romfile=gpu.rom
Значення: Proxmox передасть цей ROM до QEMU. ROM має існувати під /usr/share/kvm/ або бути вказаним відповідно до очікувань Proxmox; помістіть його правильно перед перезавантаженням ВМ.
Рішення: Якщо це вирішує ранній вивід, залиште. Якщо це ламає ініціалізацію драйвера, приберіть і переоцініть (невірний ROM або непотрібний ROM).
Завдання 15: Перевірте «споживачів у використанні», що блокують passthrough
cr0x@server:~$ fuser -v /dev/nvidia0 2>/dev/null || true
USER PID ACCESS COMMAND
/dev/nvidia0: root 1321 F.... nvidia-persistenced
Значення: Якщо NVIDIA persistence daemon або дисплей-менеджер використовує GPU, призначення VFIO буде забруднене.
Рішення: Зупиніть/відключіть споживачів на хості. Хости для passthrough не повинні запускати стеки робочого столу на тій самій карті, яку ви передаєте.
Завдання 16: Проінспектуйте можливості скидання і підказки управління живленням
cr0x@server:~$ lspci -vv -s 01:00.0 | egrep -i 'LnkCap|LnkSta|ASPM|FLR|PM' | head -n 30
LnkCap: Port #0, Speed 8GT/s, Width x16, ASPM L0s L1, Exit Latency L0s <1us, L1 <8us
LnkSta: Speed 8GT/s, Width x16
Capabilities: [b0] MSI-X: Enable+ Count=32 Masked-
Capabilities: [d0] Power Management version 3
Kernel driver in use: vfio-pci
Значення: Шукаєте підказки: наявність ASPM, версія управління живленням і чи може платформа форсувати агресивні стани живлення.
Рішення: Якщо в логах повторюються помилки, пов’язані з D3, спробуйте вимкнути ASPM в BIOS або через параметри ядра як тест.
Завдання 17: Виявіть баг «працює один раз» за допомогою керованого циклу перезапусків
cr0x@server:~$ qm start 101
started VM 101
cr0x@server:~$ sleep 30
cr0x@server:~$ qm shutdown 101 --timeout 90
stopping VM 101 (shutdown)
cr0x@server:~$ qm start 101
started VM 101
Значення: Якщо перший запуск дає вивід, а другий — чорний екран, ви щойно відтворили баг скидання без містики.
Рішення: Перейдіть до пом’якшення скидання: оновлення ядра, зміна слоту, уникайте постання хостом, або vendor-reset модуль для AMD.
Завдання 18: Підтвердьте, що ви передали всю IOMMU групу коли треба
cr0x@server:~$ ls -l /sys/kernel/iommu_groups/12/devices/
total 0
lrwxrwxrwx 1 root root 0 Jan 8 12:20 0000:01:00.0 -> ../../../../devices/pci0000:00/0000:00:01.0/0000:01:00.0
lrwxrwxrwx 1 root root 0 Jan 8 12:20 0000:01:00.1 -> ../../../../devices/pci0000:00/0000:00:01.0/0000:01:00.1
Значення: Тільки GPU і його аудіо в групі. Це добре. Якщо там більше — passthrough може вимагати і їх теж (часто неприйнятно).
Рішення: Якщо в групі є «інші речі», або передайте їх всі (часто неприйнятно), або змініть апарат/топологію.
Три корпоративні міні-історії (анонімізовані, правдоподібні, технічно точні)
Інцидент через хибне припущення: «UEFI — опціонально»
Компанія середнього розміру хотіла GPU-ВМ для команди CAD. Команда віртуалізації мала Proxmox і хтось раніше вже успішно передавав HBA, тож настрої були «те саме, інший PCI-пристрій». Вони створили шаблон ВМ з SeaBIOS, бо це збігалося зі старими серверними шаблонами. Він завантажувався через SPICE, тому все вважали зробленим.
На день розгортання додали GPU. Чорні екрани на фізичних моніторах, але RDP працював. Вони звинувачували драйвери, потім кабелі, потім монітори, потім оновлення Windows — класична спіраль відхилення відповідальності.
Справжня проблема була проста: переданий GPU ніколи не ставав раннім дисплеєм, бо шлях прошивки не відповідав очікуванням карти. SeaBIOS + поведінка ROM карти + конкурентний віртуальний VGA означали, що гість ніколи не ініціалізував вивід у спосіб, потрібний їхньому фізичному робочому потоку.
Виправлення було нудним: перейти на OVMF, встановити Q35, прибрати віртуальний VGA (vga: none) і передати GPU як первинний з x-vga=1. Також вони перебудували шаблон ВМ, щоб не повторити помилку. В постмортемі була одна ключова фраза: «Ми припустили, що вибір прошивки — косметика».
Оптимізація, що обернулась проти: ACS override як «швидке рішення»
Інша організація працювала на споживчих платах через бюджет. Їхні IOMMU групи були поганими: GPU в групі з USB-контролером і NVMe за тим самим root complex. Команда хотіла passthrough для AI inference сервісу і хотіла його вчора.
Вони увімкнули ACS override, щоб розділити групи, і святкували, коли GUI показав чисту ізоляцію. Вони швидко запхали це в продукцію. Це працювало. Деякий час.
Через тижні почалися періодичні зависання хоста під час перезапусків ВМ. Логи вказували на помилки PCIe і випадкові проблеми з файловою системою на «розділеному» NVMe. ACS override не додав апаратної ізоляції; він змінив, як ядро прикидається ізольованим. При певних шаблонах трафіку пристрої все ще взаємодіяли в спосіб, який IOMMU намагався ігнорувати.
Кінцеве рішення не було хитрим параметром ядра. Вони перенесли навантаження на платформу з правильною PCIe-ізоляцією і перевірили групи перед розгортанням. ACS override залишився інструментом лабораторних тестів з великим попередженням: «Може працювати; може також створити нові режими відмов».
Нудна, але правильна практика, яка врятувала день: дисципліна холодного старту і контроль змін
Команда, що запускала GPU-ВМ для відеообробки, мала звичку: коли змінювали прив’язку VFIO, тип прошивки або налаштування ROM, вони виконували повний перезавантаження хоста і документували виводи lspci -nnk та конфіг ВМ до/після. Ніяких «гарячих перемикань» низькорівневого устаткування.
Звучало повільно. Так воно і було. Але це і запобігло накладанню кількох неперевірених змін, після чого доводилося гадати, яка з них мала значення.
Коли вони зіштовхнулися з чорним екраном після оновлення ядра Proxmox, їхній відкат був чистим: вони порівняли «відомо добрі» виводи, побачили, що GPU тепер захоплений framebuffer під час раннього завантаження, і виправили це рішуче, а не «спробувати інший ROM бо чому б і ні».
Наслідок — операційний спокій. Вони трактували зміни passthrough як зміни збереження: виміряти, змінити одну річ, перезавантажити, підтвердити власність і лише потім продовжити.
Типові помилки: симптом → корінь → виправлення
1) Симптом: ВМ завантажується (RDP працює), але фізичний монітор залишається чорним
Корінь: Віртуальний VGA є первинним; переданий GPU не ініціалізовано як дисплей завантаження, або гість обирає неправильний адаптер.
Виправлення: Використовуйте bios: ovmf, machine: q35, встановіть vga: none і ввімкніть x-vga=1 для GPU. Переконайтеся, що монітор підключено до переданого GPU, а не до виходу хоста.
2) Симптом: Чорний екран до завантаження ОС, потім іноді працює
Корінь: Відсутня або проблемна GOP ініціалізація на стадії прошивки; драйвер гостя пізніше вмикає вивід.
Виправлення: Віддавайте перевагу OVMF, розгляньте можливість забезпечення ROM файлу з дійсним GOP, і переконайтеся, що ви не використовуєте SeaBIOS з UEFI-first ROM.
3) Симптом: Працює після холодного старту хоста; не працює після перезапуску ВМ
Корінь: Баг скидання (відсутній FLR, пристрій застрягає в D3, неповне скидання функцій).
Виправлення: Оновіть ядро/Proxmox, спробуйте інший PCIe слот, відключіть агресивне управління живленням/ASPM як тест, і переконайтеся, що всі функції GPU передані разом. Для певних поколінь AMD розгляньте vendor-reset підхід.
4) Симптом: ВМ не стартує, «stuck in D3» або помилки відновлення BAR
Корінь: Стан живлення GPU не можна підняти VFIO; платформа відмовляється включити його чисто після попереднього використання.
Виправлення: Уникайте прив’язки драйвером хоста, забезпечте чисте завершення роботи, тестуйте холодний старт, налаштуйте BIOS параметри живлення і розгляньте переміщення GPU в інший слот з іншим керуванням живленням.
5) Симптом: Випадкова нестабільність під навантаженням після включення ACS override
Корінь: Фіктивна ізоляція; пристрої все ще ділять шлях і можуть взаємодіяти; припущення DMA-ізоляції не витримують при навантаженні.
Виправлення: Використовуйте апарат із реальною ізоляцією. Ставте ACS override як останню міру і уникайте для критичних навантажень.
6) Симптом: Гість бачить GPU, але драйвер падає (Windows показує помилку або переключається на fallback)
Корінь: Політика драйвера, виявлення віртуалізації або неправильна топологія пристрою.
Виправлення: Використовуйте Q35 + OVMF, приховуйте KVM де потрібно в налаштуваннях CPU Proxmox, і уникайте суміші віртуальних адаптерів дисплея з первинним passthrough.
7) Симптом: Немає виходу на одному DP/HDMI порту, працює на іншому
Корінь: Порядок ініціалізації портів і тренування лінку на ранньому завантаженні; деякі карти надають перевагу певним портам для виводу до ОС.
Виправлення: Спочатку протестуйте інші порти/кабелі. Серйозно. Це не елегантно, але працює.
8) Симптом: Консоль ВМ в Proxmox нічого не показує після встановлення vga: none
Корінь: Це очікувано — віртуальної консолі немає.
Виправлення: Використовуйте фізичний монітор на GPU або покладайтеся на RDP/SSH. Якщо потрібен аварійний доступ, тимчасово додайте віртуальний дисплей для відладки, потім приберіть його.
Чеклісти / покроковий план
Чекліст A: Перший passthrough GPU з найменшими сюрпризами
- Увімкніть VT-d/AMD-Vi в BIOS/UEFI.
- Увімкніть IOMMU в GRUB (
intel_iommu=onабоamd_iommu=on) і перезавантажтеся. - Підтвердіть IOMMU через
dmesg. - Ідентифікуйте функції GPU через
lspci -nnі занотуйте ідентифікатори GPU + audio. - Перевірте чисті IOMMU групи; якщо групи «брудні», зупиніться і перегляньте апарат/топологію.
- Прив’яжіть функції GPU до
vfio-pciчерез/etc/modprobe.d/vfio.conf. - Перебудуйте initramfs, перезавантажтеся, підтвердіть
Kernel driver in use: vfio-pci. - Створіть ВМ з
bios: ovmfіmachine: q35. - Додайте GPU як
hostpciзpcie=1і (якщо первинний)x-vga=1. - Встановіть
vga: none, якщо хочете, щоб фізичний GPU був консоллю. - Завантажте ВМ, перевірте фізичний вивід і встановіть драйвери гостя.
Чекліст B: Дебаг чорного екрану без культу ритуалів
- Підтвердіть, що гість завантажується через RDP/SSH. Якщо ні — спочатку зосередьтесь на помилках VFIO/IOMMU.
- Перевірте логи Proxmox на предмет скарг VFIO про живлення/скидання.
- Переконайтеся, що GPU прив’язано до
vfio-pciі хост його не використовує як framebuffer. - Приберіть конкуренційний віртуальний VGA (
vga: none) і використовуйте OVMF + Q35. - Передавайте всі функції GPU (аудіо, USB якщо є) разом.
- Якщо працює лише після холодного старту — припиніть мудрувати з ROM і вирішіть питання скидання.
- Тільки після цього спробуйте ROM файл, і лише з точного дампу вашої карти.
- Якщо ви використовували ACS override — розглядайте будь-яку нестабільність як «очікувану» і плануйте апаратні зміни.
Чекліст C: Стабілізація GPU, що схильний до скидання, в експлуатації
- Уникайте циклів зупинка/старт ВМ; віддавайте перевагу suspend/resume лише якщо ви їх верифікували.
- Виконуйте контрольоване завершення і період очікування перед рестартом; деякі карти працюють краще після чистого спокою.
- Тримайте ядро Proxmox актуальним; обробка скидання покращується з часом.
- Документуйте «відомо добрі» комбінації: версія ядра, версія Proxmox, тип машини ВМ, використання ROM, слот.
- Для карт, що «не скидаються», плануйте холодні перезавантаження хоста в рамках вікон обслуговування (негарно, але надійно).
FAQ
1) Чому RDP працює, а фізичний дисплей чорний?
Гостьова ОС працює, але переданий GPU не є первинним дисплеєм або ніколи не ініціалізувався для раннього завантаження. Виправте прошивку/топологію: OVMF + Q35, приберіть віртуальний VGA, використайте x-vga=1 коли потрібно.
2) Чи завжди потрібен ROM файл GPU?
Ні. Більшість стабільних налаштувань не потребують ROM файлу. Використовуйте ROM лише коли маєте конкретну ранню проблему ініціалізації і можете дампнути точний ROM з вашої карти.
3) Що означає «stuck in D3» в логах Proxmox?
GPU знаходиться в низькопотужному стані і VFIO/QEMU не може його включити. Це проблема скидання/живлення/платформи, а не драйвера гостя.
4) Використовувати Q35 чи i440fx?
Використовуйте Q35 для сучасного passthrough GPU, якщо немає специфічних вимог сумісності. Він реалістичніше моделює топологію PCIe.
5) Чи можна передати лише функцію GPU і ігнорувати HDMI audio?
Іноді «працює», але це погана звичка. Передавайте всі функції в IOMMU групі, особливо аудіо. Частковий passthrough — шлях до періодичної дивної поведінки.
6) Чому працює після перезавантаження хоста, але не після рестарту ВМ?
Класичний баг скидання. GPU не скидається чисто між призначеннями. Зосередьтеся на пом’якшенні: оновлення ядра, зміна слота, налаштування живлення і відомі обхідні шляхи для вашого покоління GPU.
7) Чи безпечно використовувати ACS override?
Це компроміс: може зробити passthrough можливим на споживчих платах, але може знизити гарантії ізоляції, які ви очікували. Використовуйте для лабораторій. Будьте обережні в продукції.
8) Я встановив vga: none і тепер консоль Proxmox порожня. Я зламав її?
Ні. Ви прибрали віртуальний дисплей, тому в консолі Proxmox немає чого показувати. Це і є мета, якщо фізичний GPU — консоль.
9) Чи варто вмикати Resizable BAR?
Якщо ви шукаєте стабільності, залиште його вимкненим, поки passthrough не стане стабільним. ReBAR додає ще один рівень складності платформи і прошивки. Увімкніть пізніше як контрольовану зміну.
10) Потрібно прив’язати CPU ядра або налаштувати hugepages, щоб виправити чорний екран?
Майже ніколи. Це налаштування продуктивності. Чорний екран зазвичай пов’язаний з прошивкою, прив’язкою VFIO, IOMMU групами або поведінкою скидання.
Висновок: практичні наступні кроки
Якщо ви дивитесь на чорний екран — припиніть гадати. Почніть зі швидкої діагностики: підтвердіть IOMMU, підтвердіть прив’язку VFIO, підтвердіть OVMF + Q35, приберіть конкурентний віртуальний VGA і передайте всі функції GPU. Ця послідовність вирішує велику частку реальних випадків без фольклору.
Якщо працює один раз і падає при рестарті — розглядайте це як баг скидання, поки не доведено інше. Це не песимізм; це розпізнавання патернів. Стабілізуйте вибором платформи, оновленнями ядра і чистою власністю пристрою. Використовуйте ROM файли як цілеспрямований інструмент, а не ритуал.
Наступні кроки, які можна виконати сьогодні:
- Запустіть Завдання 5 (IOMMU групи) і Завдання 6 (власність драйвера). Якщо будь-яке неправильне — виправте це перед чимось іншим.
- Уніфікуйте ВМ відповідно до Завдання 11 (OVMF/Q35/vga none) і повторно протестуйте.
- Відтворіть поведінку скидання за Завданням 17 і вирішіть, чи ви в режимі «пом’якшення скидання».