Windows у VM з реальним GPU, майже нативна швидкість: Керівництво з налаштування IOMMU

Було корисно?

«У мене на десктопі працює» — мило, поки ви не намагаєтеся запускати Windows у VM з реальним GPU, реальним навантаженням і реальними користувачами, які пишуть тикети, коли мишка лагає.

GPU passthrough — це проєкт, який здається простою галочкою («увімкнути IOMMU»), але перетворюється на тиждень полювання за єдиним відсутнім перемикачем BIOS, некоректним скиданням PCIe або драйвером Windows, що відмовляється співпрацювати. Це керівництво — про те, як зробити все без перетворення хоста на науковий стенд.

Що ви будуєте (і що ні)

Ви будуєте Windows VM на Linux-хості (стек KVM/QEMU), яка використовує фізичний GPU напряму через VFIO/IOMMU. VM є власником цього GPU. Ні «трохи», ні «поділено ввічливо». Хост повинен ставитись до цього GPU так, ніби він відключений.

Це не те саме, що:

  • Прискорення через віддалений робочий стіл (RDP, VNC, SPICE). Корисно, але зазвичай не «майже нативно» для 3D або інтенсивної інтерактивної роботи з низькою затримкою.
  • vGPU / медіаційні пристрої (поділ GPU за типом SR-IOV). Чудово, коли доступно, але апаратні та ліцензійні обмеження можуть бути суворими.
  • WSL2 GUI прискорення (приємна, але інша проблема).

«Майже нативна» швидкість означає, що ви прибрали типові вузькі місця віртуалізації: емуляцію пристроїв, погане маршрутизування переривань, штрафи за синхронізацію сховища та хаос із плануванням CPU. GPU — головна зірка, але допоміжні компоненти (прошивка, ізоляція чіпсету, сховище, таймери) вирішують, чи вдало все пройде.

Факти й історичний контекст (щоб дивності стали зрозумілі)

  1. IOMMU не створювали для геймерів. AMD-Vi та Intel VT-d активно просували для серверної консолідації й ізоляції DMA — щоб пристрої не «писали» по пам’яті, яка їм не належить.
  2. VFIO — це відносно «сучасний Linux». До появи VFIO присвоєння пристроїв було можливим, але крихким і менш безпечним; VFIO стандартизував безпечніший інтерфейс у простір користувача для passthrough.
  3. PCIe ACS — неочевидний лиходій/герой. Access Control Services визначають, чи може комутатор ізолювати peer-to-peer трафік. Багато споживчих плат економлять тут, і ваші IOMMU групи це показують.
  4. UEFI (OVMF) змінив правила гри. Поведінка BIOS ROM і ініціалізації GPU у спадку була хаотичною. OVMF зробив інсталяцію Windows і ініціалізацію GPU більш передбачуваними.
  5. Ера «Code 43» від NVIDIA була реальною. Споживчі драйвери історично карали віртуалізаційні сигнали. Багато проблем сьогодні менше проявляються, але фольклор має під собою підстави.
  6. Поведінка скидання — це апаратне питання, а не настрій. Деякі GPU не можуть коректно скидатись без повного скидання шини; тому симптом «працює один раз після завантаження» з’являється знову й знову.
  7. VirtIO — це не хак продуктивності; це філософія. Паравіртуальні пристрої зменшують накладні витрати емуляції, створюючи інтерфейс спеціально для VM.
  8. MSI/MSI-X переривання важать більше, ніж ви хочете визнавати. Вони зменшують шаринг переривань і можуть покращити затримку. Але вони також можуть виявити зламані таблиці прошивки та припущення драйверів.

Рішення щодо апаратного забезпечення, що визначають успіх passthrough

Виберіть CPU/платформу, що коректно працює з IOMMU

Більшість сучасних платформ AMD Ryzen і Intel Core підтримують IOMMU/VT-d, але насправді ви купуєте реалізацію на материнській платі. Якщо є вибір, віддавайте перевагу платам, відомим своїми адекватними IOMMU групами та стабільними оновленнями прошивки. Плата з трьома оновленнями BIOS за шість місяців — або чудова команда, або попереджувальний знак.

Два GPU роблять життя простішим

Так, можна передати єдиний GPU і працювати з хостом без дисплея. Але це складніше для діагностики та набагато незручніше відновлювати, коли ви щось зламали. Використовуйте iGPU (Intel) або дешеву другу карту для консолі хоста. Це перетворює «я забрикнув завантаження» у «я можу SSH і виправити».

Проводка слотів PCIe: читайте дрібний шрифт

Верхній слот x16 не завжди означає «лінії CPU напряму». Деякі плати маршрутизують через чіпсет або ділять пропускну здатність з M.2 слотами. Для passthrough вам потрібно:

  • GPU у слоті зі стабільним link training (Gen4/Gen5 може бути примхливим).
  • Мінімальний шеринг з іншими високошвидкісними пристроями.
  • IOMMU групи, що не зливають ваш GPU з половиною чіпсету.

Стратегія для USB і аудіо

Вирішіть на початку: будете передавати весь USB-контролер чи пересилати окремі пристрої? Передача повного контролера чистіша і стабільніша для клавіатур, мишей, VR-шоломів і аудіоінтерфейсів. Але вона вимагає, щоб контролер був у власній IOMMU групі.

Жарт №1: USB passthrough схожий на офісну політику: усе добре, поки не з’явився гарнітура — і тоді нічого не працює.

Мережа: тримайте усе банальним

virtio-net NIC на Linux-бриджі часто насичує 10GbE. Не передавайте NIC, якщо немає серйозної причини (спеціальні драйвери, сувора ізоляція). Кожен пристрій passthrough додає режими відмов і залежності при перезавантаженні.

BIOS/UEFI налаштування: нудні перемикачі, що вирішують вашу долю

Більшість тем типу «GPU passthrough не працює» — це просто «IOMMU насправді не увімкнено». Маркування BIOS відрізняється, значення за замовчуванням відрізняються, і оновлення прошивки можуть тихо скидати налаштування. Занотуйте свої параметри. Серйозно.

Параметри, які потрібно ввімкнути

  • Intel: VT-d (IOMMU), VT-x (віртуалізація). Іноді «DMA remapping».
  • AMD: SVM (віртуалізація), IOMMU (AMD-Vi). Іноді «IOMMU Controller».
  • Режим завантаження UEFI (надавайте перевагу UEFI, а не CSM/legacy).
  • Above 4G decoding (часто потрібно для сучасних GPU, розмірів BAR і коректного відображення).
  • Resizable BAR (опційно; тестуйте обережно — може допомогти або ускладнити).

Параметри, які варто розглянути для відключення (якщо шукаєте дивні помилки)

  • CSM (Compatibility Support Module). Може створювати дивні шляхи ініціалізації ROM.
  • Fast boot (приховує POST-інформацію і іноді пропускає кроки ініціалізації пристроїв, які потрібні для коректного скидання).
  • PCIe ASPM (енергозбереження, що може викликати затримки або нестабільність на деяких платформах).

Оновлення прошивки: ставтесь до них як до змін у проді

Оновлюйте BIOS, якщо потрібно покращити ACS grouping або стабільність. Але робіть це як патч роутера: вікно техобслуговування, план відкату і спосіб повернутися, якщо хост не завантажиться. Ви змінюєте платформу, від якої залежить ваша межа безпеки (IOMMU).

Конфігурація хоста Linux: IOMMU, VFIO та ізоляція

Параметри завантаження ядра: IOMMU увімкнено і фактично використовується

На Intel зазвичай додають intel_iommu=on. На AMD — amd_iommu=on. Багато конфігурацій також додають iommu=pt, щоб зменшити накладні витрати на пристрої хоста, використовуючи passthrough-мепінг там, де це безпечно.

Якщо ви женетеся за продуктивністю: прив’язуйте CPU, ізолюйте «шум» хоста і уникайте емуляційних пристроїв. Якщо ви женетеся за стабільністю: тримайте конфігурацію простою і відтворюваною перед тим, як тонко налаштовувати.

Підв’яжіть GPU до VFIO рано

Ви не хочете, щоб хост коли-небудь завантажив звичайний GPU-драйвер для пристрою, що передається. Це означає прив’язку до vfio-pci при завантаженні, використовуючи IDs пристрою (vendor:device). Також прив’яжіть HDMI-аудіо функцію GPU — більшість дискретних GPU мають щонайменше дві PCI-функції.

Не забудьте про initramfs

Багатьом дистрибутивам потрібно включити модулі VFIO в initramfs, щоб ядро могло прив’язати пристрої до того, як «справжні» драйвери GPU їх захоплять. Пропустите це — і ви витратите день, дивуючись, чому GPU «використовується», навіть якщо ви заборонили драйвери.

Безпека і радіус ураження

IOMMU — це ізоляція, а не магія. DMA-атаки — причина існування IOMMU, і неправильна конфігурація може скомпрометувати хост. Якщо ця система важлива, тримайте хост «легким», мінімізуйте сторонні модулі ядра і ставтесь до passthrough як до надання VM прямої смуги в апаратні ресурси.

Ось коротка цитата на пам’ять. Вона коротка, але сильна:

«Надія — не стратегія.» — Gen. Gordon R. Sullivan

IOMMU групи: інтерпретуйте їх як місце події

IOMMU групи визначають, що можна безпечно ізолювати. Якщо ваш GPU в групі з SATA-контролером, у вас не «класний passthrough». У вас майбутній звіт про інцидент.

Як виглядає «добре»

  • GPU і його аудіо-функція в одній групі (це нормально), але не з не пов’язаними пристроями.
  • USB-контролер, призначений для passthrough, у власній групі.
  • NVMe-диски, які ви хочете передати, ізольовані чисто (або ви просто не передаєте їх і тримаєте сховище віртуалізованим).

Як виглядає «погано»

  • GPU ділить групу з мостовими пристроями чіпсету та кількома контролерами.
  • Усе за PCIe-комутатором злилося в одну групу (часто на споживчих платах без ACS).

ACS override: інструмент, а не рішення

Ядро має патч/параметр ACS override в деяких середовищах. Він може штучно розбити IOMMU групи. Також він може створити хибне відчуття безпеки, кажучи стеку програмного забезпечення «все ізольовано», коли апарат усе ще може виконувати peer-to-peer DMA. Використовуйте його лише тоді, коли розумієте ризик і приймаєте його. У проді: уникайте залежності від нього.

Створення Windows VM: OVMF, Q35, VirtIO і здоровий глузд

Тип машини і прошивка

Використовуйте Q35 (емуляція сучасного чіпсету) і OVMF (UEFI). Це узгоджується з очікуваннями сучасного Windows, топологією PCIe і ініціалізацією GPU.

Диски та мережеві пристрої

Використовуйте VirtIO для диска й мережі. Встановіть VirtIO драйвери під час інсталяції Windows (або інжектуйте їх). Емуляція SATA/IDE підходить для завантаження, але коштує вам у плані продуктивності й іноді стабільності під навантаженням.

Модель CPU і можливості

Передавайте адекватну модель CPU. «host-passthrough» часто використовують, оскільки це дає Windows той самий набір інструкцій, що й хост, зменшуючи накладні витрати трансляції. Але це знижує портативність VM. Для однохостового робочого місця/сервера це зазвичай прийнятно.

TPM і Secure Boot

Windows 11 вимагає TPM 2.0 і Secure Boot. Використовуйте віртуальний TPM (swtpm) і OVMF Secure Boot, якщо платформа це підтримує. Якщо ви робите це для контрольованого середовища, виконайте вимоги замість обхідних шляхів. Хаки стають політикою. Потім приходять аудити.

Передача GPU (та його аудіофункції)

Передавайте обидві функції, або насолоджуйтеся напівпрацюючим HDMI-аудіо

Дискретні GPU зазвичай представляють:

  • VGA/3D контролер
  • HDMI/DP аудіо-функцію
  • Іноді USB-C контролер (на деяких картах)

Передавайте весь набір функцій, що належить пристрою. Змішування власності між хостом і гостем створює плутанину драйверів і скидання пристроїв, які не спрацьовують очікувано.

Баги зі скиданням і синдром «працює один раз»

Якщо VM стартує один раз після завантаження хоста, але не стартує вдруге — ймовірно, це проблема зі скиданням. Деякі AMD GPU історично вимагали vendor-reset; деякі NVIDIA карти також можуть бути примхливими. Виправлення може бути в модулі ядра, іншому PCIe слоті, відключенні ASPM або зміні того, як QEMU виконує скидання пристрою. Іноді вирішення — «використайте інший GPU», що емоційно не приємно, але операційно коректно.

Жарт №2: Баги зі скиданням GPU — це спосіб природи нагадати нам, що «вимкни і ввімкни знову» — це апаратна функція, а не філософія життя.

Порядок встановлення драйверів у Windows

Спочатку встановіть VirtIO (сховище/мережа), потім драйвери GPU, коли VM буде стабільною. Якщо встановити драйвери GPU занадто рано і VM нестабільна, ви витратите час на налагодження Windows, тоді як корінна причина може бути в VFIO прив’язках або PCIe групуванні.

Сховище і продуктивність: не саботуйте себе

Налаштування passthrough GPU часто «провалюють» обіцянку «майже нативно», бо сховище сконфігуроване як демон-VM з 2009 року.

Вирішіть: віртуальний диск чи passthrough пристрій

  • Віртуальний диск (qcow2/raw на NVMe, VirtIO-blk/scsi): простіший для snapshot-ів, міграцій, бекапів і моніторингу. Зазвичай достатньо швидкий.
  • NVMe passthrough: висока продуктивність, але знижується керованість і ускладнюється відновлення. Також вимагає чистої IOMMU ізоляції.

ZFS на хості: потужно, але поважайте sync

Якщо диск VM знаходиться на ZFS, ви зіткнетеся з семантикою sync. Гостьова Windows з кешуванням і flush-викликами може спричиняти синхронні записи. Якщо ваш ZFS пул немає SLOG або має слабкий SLOG, сплески затримки проявляться як «зависання VM».

Правило: не вимикайте sync, якщо не можете дозволитися корупцію. Якщо ви будуєте VM лише для ігор і можете втратити сесію — можливо, ви ризикнете. Для будь-чого, що пахне роботою: зберігайте sync і інвестуйте в якісний SLOG або приймайте затримку.

Trim/Discard

Увімкніть discard там, де доречно, щоб SSD звільнявся. Але перевірте це. Неправильно налаштований discard може викликати періодичні сплески затримки залежно від стеку сховища і прошивки.

Затримка і «майже нативно»: де ховається останні 10%

Прив’язка CPU і шум планувальника

Прив’язуйте vCPU до фізичних ядер. Тримайте емуляторні потоки поза вашими прив’язаними ядрами. Якщо ви запускаєте фонові задачі хоста на тих же ядрах, що й render thread VM, виникнуть мікро-лазери, які майже неможливо пояснити тим, хто хоче просту відповідь.

Hugepages: іноді виграш, іноді пастка

Hugepages можуть зменшити TLB-місіі і покращити доступ до пам’яті. Водночас вони роблять виділення пам’яті крихким. Якщо у вас багато сервісів, резервуйте hugepages обережно і слідкуйте за фрагментацією. Якщо це одноцільова машина, hugepages частіше варто використовувати.

Переривання: MSI/MSI-X і ізоляція

Коли продуктивність «приблизно, але не плавно», перевірте маршрутизацію переривань і чи використовують пристрої MSI. Лінійні поділені переривання можуть давати затримки під навантаженням. Виправлення не завжди в тому, щоб форсувати MSI; іноді треба виправити топологію, оновити прошивку або перемістити пристрій в інший слот.

Захоплення кадру проти прямого виводу

Якщо хочете зберегти монітор на хості, але бачити вихід VM, інструменти як Looking Glass допоможуть через спільну пам’ять (ivshmem). Це красиво. Це ще один рухомий елемент. Спочатку домогіться базового passthrough; потім додавайте зручності.

Три корпоративні історії з практики

Інцидент: неправильне припущення про «ідентичні сервери»

Компанія вирішила стандартизувати невелику ферму «ідентичних» робочих станцій для CAD-підрядників: той самий CPU, той самий RAM, та ж модель GPU, той самий образ Linux. План — хостити Windows VM з GPU passthrough, щоб підрядники могли віддалено заходити у свої VM звідусіль.

Тиждень розгортання пройшов гладко. Потім половина машин почала падати при завантаженні VM після планового ребуту. Симптоми були непослідовні: деякі хости запускали VM один раз, потім наступні старти падали; інші взагалі показували відсутність GPU. Команда подумала, що це регрес ядра, і відкатала. Без змін.

Справжня причина була принизливо фізичною. «Ідентичні» машини були куплені двома партіями. Друга партія мала іншу ревізію материнської плати з іншим PCIe-комутатором. IOMMU групи змінилися, і GPU опинився в групі з USB-контролером, який хост використовував для завантажувального носія та віддаленого KVM. Скрипти passthrough автоматично прив’язували всю групу до VFIO.

Виправлення: інвентаризація ревізій апаратури, точна фіксація критичних пристроїв за PCI-адресою і відмова від автоматичної прив’язки всієї групи, якщо в ній є критичні для хоста пристрої. Також вони почали валідувати макет IOMMU груп як частину приймального тестування, як ви тестували б прошивку NIC.

Оптимізація, що дала відкат: полювання за бенчмарками на сховищі

Ще одна команда запускала Windows VM для GPU-прискореного відеооброблення. VM жили на ZFS пулі. Хтось помітив, що інгест іноді зависає, і захотів швидших записів. Вони переключили dataset property, щоб зменшити синхронні витрати (і потиснули собі руку, адже графік бенчмарку піднявся).

Декілька тижнів все виглядало нормально. Потім стався короткий brownout, який змусив UPS організувати хард-шатдаун. Після підняття деякі VM завантажились із пошкодженими NTFS томами. Проєкти відновили з джерел, а деякі робочі напівфабрикати були втрачені.

Постмортем був неприємним, бо «оптимізація» була не зламаною — це був поширений інтернет-порада. Проблема в тому, що порядок записів і семантика надійності мають значення у віртуалізації, адже гості часто припускають, що гіпервізор виконує flush як належить.

Виправлення: відновити безпечну поведінку sync, додати справжній SLOG для затримки і документувати правило: зміни продуктивності, що впливають на надійність сховища, вимагають того ж шляху погодження, що й зміни безпеки. Бенчмарки не підписують інцидентні звіти; люди підписують.

Нудна, але правильна практика, що врятувала день: детермінований pinning і контроль версій

Команда, що керувала невеликою «GPU-фермою» для Windows-рендерингу, мала майже бюрократичну звичку: кожен хост мав повну конфігурацію passthrough у контролі версій, включно з PCI IDs, QEMU аргументами і параметрами ядра. Зміни проходили рев’ю. Також був односторінковий runbook, як ідентифікувати GPU і його аудіофункцію та підтвердити прив’язку VFIO.

Настав звичайний вікно техобслуговування: оновлення ядра, мікрокоду, оновлення BIOS на двох машинах і заміна GPU через поламаний вентилятор. Саме той день, коли «згадаю, що робив минулого разу» перетворюється на імпровізацію.

Одна з оновлених машин повернулась з GPU на іншій PCI-адресі (зміна слота). VM не стартувала, бо конфіг посилався на стару адресу. Паніки не було. Інженер на виклику слідував runbook: list пристроїв, map IOMMU груп, оновити конфіг, переприв’язати VFIO, регенерувати initramfs, перезавантажитись. Через 30 хвилин VM працювала. Нікому не довелось заново відкривати, як усе працювало під тиском.

Нудна практика — не геройство. Це просто ставлення до passthrough як до продакшн-інфраструктури: детермінована, перевірна і тестована. Ось і весь трюк.

План швидкої діагностики

Коли продуктивність не майже нативна або VM не стартує, не блукайте. Тріажуйте як SRE: підтвердіть граничні умови спочатку, потім звужуйте коло пошуку.

По-перше: підтвердьте фундаментальні речі (10 хвилин)

  1. IOMMU увімкнено і активне (в логах ядра видно DMAR/AMD-Vi, і існують IOMMU групи).
  2. GPU прив’язаний до vfio-pci на хості до старту VM.
  3. VM використовує OVMF + Q35 (сучасна прошивка і модель чіпсету).
  4. Windows бачить GPU без помилок драйверів (Device Manager, нема Code 12/43).

По-друге: ідентифікуйте клас вузького місця

  • Затримки під навантаженням → планування CPU / переривання / затримка сховища.
  • VM не стартує → IOMMU групи, VFIO binding, ROM/reset проблеми.
  • Стартує один раз, потім падає → поведінка скидання GPU, управління живленням, стан драйвера.
  • Низький FPS, але стабільно → неправильний шлях виводу (використовується віртуальний GPU), неправильний драйвер, ширина/швидкість PCIe.

По-третє: виміряйте очевидні сигнали

  1. Стан PCIe link (GPU на x16 Gen4, або він навчився на x4 Gen1?).
  2. Затримка сховища (чи синхронні записи гальмують?).
  3. CPU steal time і навантаження хоста (чисто боретеся з планувальником?).
  4. Розподіл переривань (чи одне ядро обробляє всі переривання?).

Якщо не можете сказати, до якої категорії відноситесь, ви ще не діагностуєте — ви оглядаєтесь.

Типові помилки: симптом → корінь → виправлення

VM не стартує; QEMU каже «device is in use»

Симптоми: VM негайно падає; логи згадують, що GPU зайнятий.

Корінь: Драйвер хоста (nouveau/amdgpu/nvidia) захопив пристрій до vfio-pci.

Виправлення: Прив’язуйте за vendor/device ID до vfio-pci при завантаженні; забезпечте наявність VFIO модулів в initramfs; blacklist драйверів — другорядний захід.

Windows показує Code 12 («not enough resources») для GPU

Симптоми: GPU видно, але він не стартує; помилка виділення ресурсів.

Корінь: Проблеми з BAR mapping/ресурсними обмеженнями; часто відсутній «Above 4G decoding» або некоректна топологія PCIe в VM.

Виправлення: Увімкніть Above 4G decoding в BIOS; використовуйте Q35; спочатку вимкніть Resizable BAR; передавайте всі функції GPU.

Працює один раз після завантаження хоста, потім GPU зникає при рестарті VM

Симптоми: Перший запуск VM OK; наступні старти падають до перезавантаження хоста.

Корінь: GPU не підтримує чистого скидання на рівні функції; драйвер залишає його в поганому стані.

Виправлення: Спробуйте різні версії ядра/QEMU; відключіть енергоменеджмент PCIe; використайте vendor-reset, якщо доступно; для критичних випадків обирайте GPU, відомий стабільністю скидання.

Низький FPS і велике навантаження CPU у гості

Симптоми: Windows схожий на софтверне рендерення; CPU підскакує.

Корінь: Ви фактично не використовуєте переданий GPU (Windows показує Microsoft Basic Display Adapter або віртуальний GPU), або вивід рендериться через повільний шлях ремоуту.

Виправлення: Переконайтеся, що Device Manager показує правильний GPU; встановіть коректні драйвери; підключіть монітор до переданого GPU або використайте низькозатратний метод захоплення як ivshmem.

Аудіо потріскує під навантаженням

Симптоми: Попи/тріски, особливо при компіляції або копіюванні файлів.

Корінь: DPC-затримка через планування CPU, переривання або енергоменеджмент; інколи спричинена передачею лише частини аудіо-ланцюга.

Виправлення: Прив’яжіть vCPU; зменшіть фонове навантаження хоста; забезпечте MSI/MSI-X там, де потрібно; передайте окремий USB-контролер для аудіо, якщо потрібно.

Продуктивність диска VM жахлива на «швидкому» пулі

Симптоми: FPS падає під час завантаження ресурсів; відео рендери підтискаються; IO wait скачки.

Корінь: Покарання за sync-записи, фрагментація thin-provisioning, накладні витрати qcow2 або відсутність кеш/SLOG налаштувань.

Виправлення: Віддавайте перевагу raw на швидкому SSD/NVMe для продуктивності; використовуйте VirtIO з правильним queueing; на ZFS тримайте sync=standard і забезпечте відповідний SLOG при необхідності.

USB-пристрої випадково відключаються

Симптоми: Клавіатура/миша відключається; VR-пристрої зникають; Windows видає звуки «пристрій видалено».

Корінь: Флаппінг USB passthrough; енергоменеджмент хоста; пересилка окремих пристроїв замість контролера; погане IOMMU групування змушує компроміси.

Виправлення: Передавайте повний USB-контролер в ізольованій групі; відключіть USB autosuspend на хості за потреби; уникайте концентраторів там, де можна.

Практичні завдання з командами, виводами та рішеннями

Це перевірки, які я виконую, коли хочу швидкі відповіді. Кожне завдання включає: команду, що означає вивід, і яке рішення прийняти далі.

Завдання 1: Підтвердити наявність розширень віртуалізації

cr0x@server:~$ lscpu | egrep -i 'Virtualization|Flags'
Virtualization:                  AMD-V
Flags:                           fpu vme de pse tsc ... svm ...

Значення: У вас є апаратна віртуалізація (SVM на AMD, VT-x на Intel). Це необхідно, але не достатньо для IOMMU.

Рішення: Якщо відсутня віртуалізація, спочатку виправте налаштування BIOS (SVM/VT-x). VFIO поки не чіпайте.

Завдання 2: Підтвердити, що IOMMU/DMAR фактично увімкнено в ядрі

cr0x@server:~$ dmesg | egrep -i 'DMAR|IOMMU|AMD-Vi' | head -n 12
[    0.812345] AMD-Vi: IOMMU performance counters supported
[    0.812678] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
[    0.813210] AMD-Vi: Interrupt remapping enabled

Значення: IOMMU ініціалізовано і перерозподіл переривань увімкнено (добрий знак для стабільності).

Рішення: Якщо нічого релевантного не бачите, додайте amd_iommu=on або intel_iommu=on до GRUB/systemd-boot і перезавантажтесь.

Завдання 3: Підтвердити, що модулі VFIO завантажені

cr0x@server:~$ lsmod | egrep 'vfio|kvm' | head
vfio_pci               65536  0
vfio_pci_core          90112  1 vfio_pci
vfio_iommu_type1       40960  0
vfio                   45056  2 vfio_pci_core,vfio_iommu_type1
kvm_amd               139264  0
kvm                  1105920  1 kvm_amd

Значення: Ядро VFIO присутнє. Якщо цього немає — passthrough не станеться.

Рішення: Якщо відсутні модулі, встановіть відповідні пакети і переконайтеся, що initramfs включає модулі VFIO.

Завдання 4: Ідентифікувати GPU і його функції (VGA + audio)

cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|audio' 
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)

Значення: Дві функції: GPU (01:00.0) і аудіо GPU (01:00.1). Майже завжди передавайте обидві.

Рішення: Запишіть PCI-адреси і device ID. Вони керують прив’язкою vfio-pci.

Завдання 5: Перевірити членство IOMMU групи для GPU

cr0x@server:~$ for d in /sys/kernel/iommu_groups/*/devices/*; do echo "$d" | sed 's/.*iommu_groups\/\([0-9]*\).*/Group \1/'; lspci -nns "${d##*/}"; done | egrep -A2 '01:00\.' 
Group 12
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1)
Group 12
01:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)

Значення: GPU і його аудіо в Group 12 і ніяких інших пристроїв у цьому відфільтрованому виводі не видно. Потрібно підтвердити повний вміст групи.

Рішення: Якщо Group 12 містить не пов’язані пристрої, ви не зможете безпечно передати лише GPU без вирішення ізоляції (змінити слот/плату або прийняти ризик).

Завдання 6: Вивести повну IOMMU групу (без хитрощів)

cr0x@server:~$ find /sys/kernel/iommu_groups/12/devices -maxdepth 1 -type l -printf '%f\n' | sort
0000:01:00.0
0000:01:00.1

Значення: Чиста, мінімальна група. Це те, що вам потрібно.

Рішення: Продовжуйте з VFIO binding. Якщо група переповнена — зупиніться і перегляньте апаратну топологію.

Завдання 7: Прив’язати GPU до vfio-pci за vendor:device IDs

cr0x@server:~$ sudo tee /etc/modprobe.d/vfio.conf >/dev/null <<'EOF'
options vfio-pci ids=10de:2484,10de:228b disable_vga=1
EOF

Значення: Це каже vfio-pci, які пристрої захоплювати. disable_vga=1 може допомогти з архаїчними VGA quirk-ами.

Рішення: Після цього треба перебудувати initramfs (наступне завдання) і перезавантажитись, щоб прив’язка стала ранньою.

Завдання 8: Забезпечити раннє завантаження модулів VFIO (initramfs) і регенерувати

cr0x@server:~$ echo -e "vfio\nvfio_pci\nvfio_iommu_type1\nvfio_pci_core" | sudo tee /etc/initramfs-tools/modules
vfio
vfio_pci
vfio_iommu_type1
vfio_pci_core
cr0x@server:~$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.8.0-41-generic

Значення: Initramfs тепер містить модулі VFIO, щоб вони могли прив’язати пристрої до того, як драйвери GPU їх захоплять.

Рішення: Перезавантажте. Якщо пропустити цей крок, ви практично тестуєте удачу.

Завдання 9: Після перезавантаження перевірити, що GPU використовує vfio-pci

cr0x@server:~$ lspci -k -s 01:00.0
01:00.0 VGA compatible controller: NVIDIA Corporation GA104 [GeForce RTX 3070] (rev a1)
	Subsystem: Micro-Star International Co., Ltd. [MSI] Device 3901
	Kernel driver in use: vfio-pci
	Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia

Значення: «Kernel driver in use: vfio-pci» — головна ознака. Наявність інших модулів у «Kernel modules» нормально; це перелік можливих модулів, не активної прив’язки.

Рішення: Якщо в «driver in use» бачите nouveau/amdgpu/nvidia, повертайтесь назад: порядок initramfs, vfio IDs і blacklists.

Завдання 10: Підтвердити, що хост не захопив GPU для виводу

cr0x@server:~$ loginctl seat-status seat0 | head -n 20
seat0
	Devices:
		/sys/devices/pci0000:00/0000:00:02.0/drm/card0
cr0x@server:~$ ls -l /dev/dri/by-path | head
total 0
lrwxrwxrwx 1 root root  8 Feb  4 10:12 pci-0000:00:02.0-card -> ../card0

Значення: Активний DRM-пристрій — iGPU на 00:02.0, не passthrough GPU на 01:00.0.

Рішення: Якщо хост використовує passthrough GPU для DRM, вам потрібен другий GPU/iGPU для хоста або бездисплейна конфігурація з ретельною прив’язкою.

Завдання 11: Перевірити ширину/швидкість PCIe (сана продуктивності)

cr0x@server:~$ sudo lspci -vv -s 01:00.0 | egrep -i 'LnkCap|LnkSta'
LnkCap:	Port #0, Speed 16GT/s, Width x16, ASPM L1, Exit Latency L1 <64us
LnkSta:	Speed 16GT/s (ok), Width x16 (ok)

Значення: GPU правильно натренувався (тут Gen4 x16). Якщо бачите x4 або Gen1 — очікуйте вузьких місць пропускної здатності і дивного стуттера.

Рішення: Якщо link деградований, перепідключіть карту, змініть слот, оновіть BIOS або зафіксуйте генерацію PCIe в BIOS для тестування стабільності.

Завдання 12: Перевірити, що доступне KVM прискорення

cr0x@server:~$ sudo kvm-ok
INFO: /dev/kvm exists
KVM acceleration can be used

Значення: У вас є апаратне прискорення віртуалізації, доступне для QEMU.

Рішення: Якщо це не працює, виправляйте BIOS віртуалізації або завантаження модулів ядра до того, як тинати passthrough.

Завдання 13: Підтвердити, що QEMU бачить VFIO device node

cr0x@server:~$ ls -l /dev/vfio
total 0
crw-rw---- 1 root root  10, 196 Feb  4 10:15 vfio
crw-rw---- 1 root root  10, 140 Feb  4 10:15 12

Значення: Для Group 12 існує VFIO device node. Саме QEMU відкриває цей вузол, щоб отримати доступ до групи.

Рішення: Якщо вузол групи відсутній — IOMMU групування не активне або проблеми з permissions/udev правилами.

Завдання 14: Спостерігати IOMMU faults під час завантаження VM

cr0x@server:~$ sudo dmesg -w | egrep -i 'vfio|iommu|fault|DMAR|AMD-Vi'
[  312.123456] vfio-pci 0000:01:00.0: enabling device (0000 -> 0003)
[  312.456789] vfio-pci 0000:01:00.1: enabling device (0000 -> 0002)

Значення: Нормальні рядки enable — це добре. Фактичні IOMMU faults будуть містити «fault» і адресу.

Рішення: Якщо бачите faults — підозрюйте багату прошивку, небезпечний ACS override або пристрій, який виконує DMA за межами призначених діапазонів.

Завдання 15: Перевірити тиск планування CPU хоста і симптоми типу steal

cr0x@server:~$ top -b -n 1 | head -n 12
top - 10:22:01 up 12 days,  3:11,  2 users,  load average: 7.82, 6.11, 5.44
Tasks: 382 total,   2 running, 380 sleeping,   0 stopped,   0 zombie
%Cpu(s): 62.1 us,  3.4 sy,  0.0 ni, 33.9 id,  0.4 wa,  0.0 hi,  0.2 si,  0.0 st
MiB Mem :  64239.0 total,   812.5 free,  28410.2 used,  35016.3 buff/cache

Значення: Навантаження високе, але idle ≈34%. Це вказує на runnable pressure, але не повну насиченість. Якщо wa стрибає — підозрюйте затримки сховища.

Рішення: Якщо бачите тривалі високі wa, йдіть до перевірки сховища. Якщо sy високе — підозрюйте шторми переривань або важку мережеву нагрузку.

Завдання 16: Виміряти сигнали затримки сховища на ZFS (якщо застосовно)

cr0x@server:~$ sudo zpool iostat -v 1 3
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
rpool                       1.20T  2.40T    220    980  28.0M  96.5M
  nvme0n1                   1.20T  2.40T    220    980  28.0M  96.5M

Значення: Висока кількість записів може включати синхронні гостеві навантаження. Цей вивід не дає прямої інформації про затримку, але показує патерни тиску.

Рішення: Якщо write ops стрибають під час стуттера, досліджуйте поведінку ZFS sync, SLOG і flush-патерни гостя.

Контрольні списки / покроковий план

Фаза 1: Апаратне забезпечення і прошивка (зробіть перед зміною налаштувань Linux)

  1. Встановіть другий GPU або увімкніть iGPU для виводу хоста.
  2. Оновіть BIOS/UEFI до стабільного релізу (не обов’язково найновішого бета).
  3. Увімкніть VT-d/AMD-Vi (IOMMU), VT-x/SVM, Above 4G decoding.
  4. Вимкніть CSM; завантажуйтесь у чистому UEFI режимі.
  5. Розмістіть GPU у слоті, ймовірно з прямим підключенням до CPU; уникайте шерінгу з критичними контролерами.

Фаза 2: Базова конфігурація хост OS

  1. Встановіть недавнє LTS ядро, відоме стабільністю з VFIO для вашого дистрою.
  2. Увімкніть IOMMU параметри ядра (intel_iommu=on або amd_iommu=on; опційно iommu=pt).
  3. Встановіть KVM/QEMU, libvirt (або ваш стек гіпервізора) і переконайтесь, що /dev/kvm існує.
  4. Ідентифікуйте функції GPU з lspci -nn.
  5. Перевірте IOMMU групи. Якщо групи «погані», виправляйте топологію зараз (слот/плата), а не пізніше.

Фаза 3: VFIO binding

  1. Створіть конфіг vfio-pci IDs (/etc/modprobe.d/vfio.conf).
  2. Додайте VFIO модулі в initramfs, регенеруйте initramfs, перезавантажтесь.
  3. Перевірте «Kernel driver in use: vfio-pci» для GPU та його аудіофункції.
  4. Підтвердіть, що хост не використовує passthrough GPU для виводу.

Фаза 4: Створення VM

  1. Створіть VM з Q35 + OVMF.
  2. Використовуйте VirtIO диск + VirtIO мережу; приєднайте ISO з драйверами VirtIO.
  3. Встановіть Windows; встановіть VirtIO драйвери; потім інсталюйте GPU драйвери.
  4. Передайте GPU + аудіо, і опційно USB-контролер.
  5. Перезавантажте VM кілька разів. Якщо воно працює лише один раз — ви не закінчили.

Фаза 5: Тюнінг продуктивності (тільки після стабільності)

  1. Прив’яжіть vCPU; ізолюйте CPU хоста за потреби.
  2. Оцініть hugepages, якщо навантаження отримує вигоду.
  3. Перевірте швидкість і ширину PCIe link.
  4. Виміряйте поведінку сховища під навантаженням; правильно усуньте затримки sync.

FAQ

1) Чи потрібні мені два GPU?

Потрібно? Ні. Хочете? Так. Два GPU (або iGPU для хоста) значно полегшують відновлення і відлагодження. Варіант headless можливий, але менш пробачливий.

2) Чи можу я отримати майже нативну ігрову продуктивність?

Часто — так. Частина з GPU може бути майже нативною; решта розриву — зазвичай планування CPU, затримки сховища і шлях виводу/USB. Якщо ви налаштуєте це — отримаєте дуже близький результат.

3) Чи варто передавати NVMe диск для максимальної швидкості?

Тільки якщо у вас є причина, яка переважає операційну вартість. Raw віртуальний диск на швидкому NVMe з VirtIO вже відмінний. NVMe passthrough ускладнює бекапи, snapshots і відновлення.

4) Чому Windows показує Code 12 або Code 43?

Code 12 зазвичай означає проблеми з ресурсами/BAR — часто виправляється увімкненням Above 4G decoding і правильною прошивкою/чипсетом VM. Code 43 історично був пов’язаний із виявленням віртуалізації драйверами, але сучасні причини — це misconfiguration і нестабільний стан пристрою.

5) Чи допомагає Resizable BAR?

Може допомогти залежно від гри/робочого навантаження і платформи. Також може додати складності в мепінгу. Отримайте стабільну базу з вимкненим Resizable BAR, а потім тестуйте його цілеспрямовано.

6) Чи безпечний ACS override?

Він може змусити ядро вважати, що ви маєте кращу ізоляцію, ніж апарат реально дає. Для домашнього робочого місця ризик може бути прийнятний. Для всього важливого — використовуйте його як крайній засіб і віддавайте перевагу справжній апаратній ізоляції.

7) Який чистіший спосіб обробляти клавіатуру/мишу і USB-пристрої?

Передавайте повний USB-контролер у власній IOMMU групі. Пересилання індивідуальних USB-пристроїв працює, але більш схильне до скидань і дивних перепідключень при високому обміні.

8) Як зрозуміти, де вузьке місце: сховище, CPU чи GPU?

Перевірте стан PCIe link і підтвердіть, що GPU реально використовується. Потім погляньте на host CPU wa і статистику сховища під час стуттера. Якщо IO wait стрибає — це сховище. Якщо CPU насичений або переривання збираються на одному ядрі — це планування/переривання.

9) Чи можу я запускати кілька Windows VM з кількома GPU?

Так, якщо у вас достатньо PCIe ліній, живлення, охолодження і чисті IOMMU групи. Операційно це ближче до міні-кластеру: детерміновані конфіги і контроль змін окупаються.

10) Краще використовувати libvirt, Proxmox чи сирий QEMU?

Використовуйте те, що можете оперувати. Libvirt дає структуру і простіше керування; сирий QEMU дає повний контроль. Proxmox зручний, але все одно спирається на ту саму реальність kernel/VFIO внизу.

Наступні кроки, які варто зробити

  1. Проінвентаризуйте апарат: ревізія материнської плати, версія BIOS, модель GPU і розклад PCIe. Не припускайте, що «та сама модель» означає «така сама поведінка».
  2. Перевірте IOMMU групи перед купівлею додаткових частин або перед тим, як почати тюнінг ядра. Якщо групи некрасиві — поміняйте слоти або плату зараз.
  3. Зробіть VFIO binding детермінованим: device IDs, initramfs і перевірка після перезавантаження, що хост не керує GPU.
  4. Створіть VM з сучасними налаштуваннями: Q35 + OVMF + VirtIO. Уникайте шляху ностальгії.
  5. Спочатку стабілізуйте, потім тюніть: перевірте цикли перезавантаження, старт/стоп VM і suspend/resume (якщо це важливо) перед гонитвою за мікросекундами.
  6. Напишіть runbook: ті 10 команд, які ви використовували сьогодні, будуть тими самими, які знадобляться о 2:00 ночі.

Якщо ви зробите ці шість речей, ви витратите час на реальний тюнінг продуктивності замість суперечок з BIOS-перемикачем, що тихо відключився.

← Попередня
Пакети Linux: безпечна стратегія оновлень, яка не ламає продакшн
Наступна →
Встановлення AlmaLinux 10: корпоративний Linux із чітким шляхом оновлення

Залишити коментар