Ви переключили відповідні тумблери в BIOS. Linux повідомляє, що IOMMU увімкнено. Ви навіть бачите DMAR або AMD-Vi в dmesg. І все одно: ваша GPU ділить IOMMU‑групу з USB-контролером, SATA HBA і тим, що виглядає як половина материнської плати. VFIO тихо сміється в кутку.
Саме тут більшість «гайдів по passthrough GPU» зупиняються і починають радити випадкові параметри ядра, ніби це спеції. Не робіть так. Спільні IOMMU‑групи — це не примха; це проблема топології. Виправте топологію — і ізоляція стане нудною. Нудне — це добре.
Ментальна модель: що таке IOMMU‑група насправді
IOMMU‑група — це набір PCIe‑функцій, які неможливо надійно ізолювати одна від одної щодо DMA. Якщо один пристрій у групі може ініціювати DMA‑транзакції, що потрапляють до мапінгів пам’яті іншого пристрою без блокування, ядро трактує їх як нероздільні. VFIO не «хоче» груп; воно реалізує ізоляцію, яку може довести апарат.
Чому «IOMMU увімкнено» — не та перемога, яку ви думаєте
Увімкнення IOMMU (Intel VT‑d / AMD‑Vi) дає платформі здатність транслювати та обмежувати DMA. Це не гарантує, що кожен PCIe‑ендпоінт отримає свій окремий чистий сандбокс. Ізоляція залежить від ланцюга довіри між ендпоінтом і CPU: root port, будь‑які низхідні порти, PCIe‑комутатори та наявність відповідних Access Control Services (ACS) і пов’язаних керувань на цьому шляху.
Межа групи зазвичай відповідає межі моста
На практиці межі IOMMU‑груп часто збігаються з PCIe‑мостами/портами, які можуть забезпечити розділення. Якщо у вас є один низхідний порт, що живить кілька ендпоінтів (або комутатор, який не оголошує чи не вмикає ACS належним чином), Linux може об’єднати їх. Це не тому, що Linux злий. Це тому, що Linux відмовляється обіцяти ізоляцію, яку він не може довести.
Перефразована ідея від James Hamilton (Amazon): «Вимірюй усе, не припускай нічого». Вона болісно добре підходить до IOMMU‑груп — припущення про топологію призводять до того, що ви виведете USB‑контролер разом із GPU.
Швидкий план діагностики (що перевірити насамперед)
Перше: підтвердіть, що IOMMU дійсно активний, а не просто «налаштований»
- Перевірте
dmesgна наявність рядків про DMAR/AMD‑Vi та статус ремапінгу. - Переконайтеся, що IOMMU‑групи існують у
/sys/kernel/iommu_groups.
Друге: ідентифікуйте конкретні пристрої, які вас цікавлять, і їхній шлях вверх по шині
- Зіставте GPU/HBA/NIC до PCI‑адрес за допомогою
lspci -nn. - Пройдьте дерево PCIe з
lspci -tvіlspci -vv. - Знайдіть upstream‑міст і чи присутній/увімкнений на ньому ACS.
Третє: вирішіть, чи це можна виправити апаратно/прошивкою або лише «виправити» через оверрайди
- Якщо пристрої ділять групу через те, що вони під’єднані за одним низхідним портом без ACS: змініть слот, увімкніть BIOS‑опції або змініть платформу.
- Якщо пристрої ділять групу тому, що виробник материнської плати провів кілька слотів за одним root‑портом: прийміть реальність, переробіть дизайн або використайте ACS override, усвідомлюючи компроміси.
Правило: якщо ви робите це для продукційної надійності або відповідності, розглядайте ACS override як останній засіб і документуйте його як контрольований ресурс.
Факти й історія, що пояснюють сучасний безлад
- VT‑d і AMD‑Vi з’явилися значно пізніше за CPU‑віртуалізацію. Рання віртуалізація зосереджувалася на рівнях привілеїв CPU; ізоляція DMA прийшла пізніше і поволі прогресувала в чіпсетах.
- PCIe ACS — опціональна можливість. ACS — це здатність, яку пристрої/порти можуть або не можуть реалізувати. Опціональні функції — це місце, де мрії вмирають.
- IOMMU‑групи — це політика Linux поверх апаратних реалій. Ядро формує групи на основі гарантій ізоляції; це не «функція passthrough», а межа безпеки.
- Багато споживчих материнських плат оптимізують лінії, а не ізоляцію. Розподіл x16 у x8/x8 через той самий root complex може бути нормальним для продуктивності, але жахливим для групування.
- PCIe‑комутатори не є магічними боксами ізоляції. Деякі комутатори реалізують ACS добре; інші — ні, або прошивка залишає його відключеним. Те саме позначення деталі на різних платах дає різний результат.
- Багатофункційні пристрої можуть бути нероздільними за дизайном. GPU з аудіо‑функцією зазвичай — один фізичний пристрій з кількома функціями; ці функції часто залишаються в одній IOMMU‑групі.
- «ACS override» з’явився тому, що люди постійно просили. Ядро отримало регулятори для пом’якшення групування в випадках віртуалізації. Це практично, а не святе.
- Thunderbolt і зовнішній PCIe добавляють додаткову топологічну складність. Мости гарячого підключення та рівні безпеки ускладнюють довіру до DMA і поведінку групування.
- SR‑IOV змінив очікування. Після того як мережеві карти почали надавати багато VFs, всі очікували охайної ізоляції — і виявили, що платформа все ще вирішує групи.
Практичні завдання: команди, виводи та рішення (12+)
Це перевірки, які я виконую, коли хтось питає: «IOMMU увімкнено, але групи все ще спільні». Кожне завдання включає: команду, що ви можете побачити, і що робити далі.
Завдання 1: Підтвердити, що ядро бачить активний IOMMU (Intel)
cr0x@server:~$ dmesg | grep -E "DMAR|IOMMU"
[ 0.012345] DMAR: IOMMU enabled
[ 0.012678] DMAR: Host address width 39
[ 0.013210] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[ 0.015432] DMAR: Intel(R) Virtualization Technology for Directed I/O
Значення: рядок «IOMMU enabled» — те, чого ви шукаєте. Якщо ви бачите лише таблиці DMAR, але без увімкнення, реального ремапінгу DMA немає.
Рішення: Якщо відсутній, виправте BIOS (VT‑d) і параметри ядра (intel_iommu=on) перш ніж витрачати час на групи.
Завдання 2: Підтвердити, що ядро бачить активний IOMMU (AMD)
cr0x@server:~$ dmesg | grep -E "AMD-Vi|IOMMU"
[ 0.010101] AMD-Vi: IOMMU performance counters supported
[ 0.010202] AMD-Vi: Found IOMMU at 0000:00:00.2 cap 0x40
[ 0.010303] AMD-Vi: Interrupt remapping enabled
Значення: наявність AMD‑Vi і ввімкненого ремапінгу переривань — хороший знак для безпечного делегування пристрою.
Рішення: Якщо ремапінг переривань вимкнений, розгляньте оновлення прошивки та BIOS‑параметри; деякі конфігурації стають крихкими без нього.
Завдання 3: Перевірити наявність IOMMU‑груп
cr0x@server:~$ ls -1 /sys/kernel/iommu_groups | head
0
1
2
3
4
5
6
7
8
9
Значення: Групи існують. Якщо директорія порожня або відсутня, у вас немає активного групування IOMMU.
Рішення: Відсутність груп означає зупинитися й виправити увімкнення (BIOS/ядро). Групи є — перейдіть до топології.
Завдання 4: Вивести групи з іменами пристроїв (швидкий інвентар)
cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group ${g##*/}"; for d in $g/devices/*; do lspci -nns ${d##*/}; done; echo; done | sed -n '1,35p'
Group 0
00:00.0 Host bridge [0600]: Intel Corporation Device [8086:1234]
00:01.0 PCI bridge [0604]: Intel Corporation Device [8086:5678]
Group 1
00:14.0 USB controller [0c03]: Intel Corporation Device [8086:a36d]
00:14.2 RAM memory [0500]: Intel Corporation Device [8086:a36f]
Group 2
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2484]
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:228b]
Значення: Це покаже, чи GPU ізольований (часто він ділить групу з аудіофункцією, що нормально) або потрапив у групу з несумісними пристроями (погано).
Рішення: Якщо цільовий пристрій ділиться з несумісними контролерами, потрібно зрозуміти upstream‑порт і ACS.
Завдання 5: Ідентифікувати пристрій і драйвер ядра (хто ним володіє)
cr0x@server:~$ lspci -nnk -s 01:00.0
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2484] (rev a1)
Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:xxxx]
Kernel driver in use: nouveau
Kernel modules: nouveau, nvidiafb
Значення: Якщо пристрій прив’язаний до драйвера хоста, VFIO‑passthrough буде конфліктувати під час завантаження або старту VM.
Рішення: Прив’язуйте до vfio-pci (або stub) тільки після підтвердження, що група прийнятна. Не «виправляйте» групування переназначенням драйверів — це не допоможе.
Завдання 6: Показати топологію PCIe як дерево (знайти батьківський міст)
cr0x@server:~$ lspci -tv
-+-[0000:00]-+-00.0 Host bridge
| +-01.0-[01]----00.0 VGA compatible controller
| | \-00.1 Audio device
| +-14.0 USB controller
| +-17.0 SATA controller
| \-1d.0-[02]----00.0 Ethernet controller
Значення: Ваш GPU знаходиться за 00:01.0. Якщо кілька ендпоінтів знаходяться під тим самим низхідним сегментом і згруповані — upstream‑порт, ймовірно, не ізолює.
Рішення: Якщо слот GPU і вбудований контролер знаходяться під тим самим мостом у дереві, у вас, ймовірно, обмеження проводки/топології. Розгляньте переміщення карт/слотів.
Завдання 7: Перевірити ACS‑можливості на upstream‑порті
cr0x@server:~$ sudo lspci -vv -s 00:01.0 | grep -A8 -i "Access Control Services"
Access Control Services
ACSCap: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl+ DirectTrans+
ACSCtl: SrcValid+ TransBlk- ReqRedir- CmpltRedir- UpstreamFwd- EgressCtrl- DirectTrans-
Значення: Можливість існує, але керування може бути вимкненим. Деякі платформи залишають ACSCtl біти вимкненими.
Рішення: Якщо ACSCap відсутній зовсім на відповідних портах, вам навряд чи вдасться отримати чисті розбивки без оверрайдів або іншого апаратного рішення. Якщо можливість є, але вимкнена — прошивка/ядро може дозволяти її вмикати.
Завдання 8: Перевірити режим трансляції платформи
cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.0 root=UUID=... ro quiet intel_iommu=on iommu=pt
Значення: intel_iommu=on вмикає ремапінг. iommu=pt встановлює passthrough для хостових пристроїв (часто покращує продуктивність для неделегованих пристроїв).
Рішення: Для налагодження ізоляції тримайте налаштування простими: увімкніть IOMMU явно, уникайте екзотичних параметрів поки не зрозумієте базову конфігурацію.
Завдання 9: Підтвердити стан ремапінгу переривань / posted interrupts
cr0x@server:~$ dmesg | grep -E "Interrupt Remapping|IR|x2apic" | head -n 20
[ 0.013333] DMAR-IR: Enabled IRQ remapping in x2apic mode
[ 0.013444] DMAR-IR: Queued invalidation will be enabled to support x2apic and Intr-remapping.
Значення: Ремапінг IRQ зменшує ймовірність доставляння переривань не туди при делегуванні.
Рішення: Якщо він вимкнений, вважайте passthrough більш ризикованим; для продукції пріоритезуйте оновлення прошивки або зміну платформи.
Завдання 10: Перевірити, чи GPU в групі з мостом, яким ви не керуєте
cr0x@server:~$ readlink -f /sys/bus/pci/devices/0000:01:00.0/iommu_group
/sys/kernel/iommu_groups/2
Значення: Підтверджує номер групи з точки зору пристрою.
Рішення: Якщо група містить пристрої, які ви не можете передати разом, наступний крок — усунення топології, а не підправлення конфігурації VFIO.
Завдання 11: Ідентифікувати, хто ще в групі (перевірка «хто ще в кімнаті»)
cr0x@server:~$ G=$(basename $(readlink /sys/bus/pci/devices/0000:01:00.0/iommu_group)); for d in /sys/kernel/iommu_groups/$G/devices/*; do lspci -nnk -s ${d##*/}; echo; done
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation Device [10de:2484] (rev a1)
Kernel driver in use: nouveau
Kernel modules: nouveau, nvidiafb
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:228b] (rev a1)
Kernel driver in use: snd_hda_intel
Kernel modules: snd_hda_intel
Значення: GPU + його аудіо‑функція лише? Це зазвичай нормально. GPU + USB + SATA? Це конструкційне обмеження.
Рішення: Якщо бачите несумісні пристрої, вирішуйте між: перемістити карти/слоти, змінити BIOS‑настройки, вибрати іншу плату/CPU або застосувати ACS override (із ризиком).
Завдання 12: Перевірити наявність PCIe‑комутатора в шляху (часто в серверах, іноді в робочих станціях)
cr0x@server:~$ lspci -nn | grep -i "PCI bridge\|PLX\|Broadcom\|PEX"
00:01.0 PCI bridge [0604]: Intel Corporation Device [8086:5678]
03:00.0 PCI bridge [0604]: Broadcom / PLX Device [10b5:8725]
03:01.0 PCI bridge [0604]: Broadcom / PLX Device [10b5:8725]
Значення: Комутатори часто відображаються як кілька функцій мосту. Чи ізолюють вони — залежить від ACS та конфігурації.
Рішення: Якщо в шляху є комутатор, потрібно перевіряти ACS саме на тих низхідних портах, а не тільки на root‑порті.
Завдання 13: Підтвердити вигляд ізоляції через цілеспрямований ACS‑скан ядра
cr0x@server:~$ for dev in 00:01.0 03:00.0 03:01.0; do echo "== $dev =="; sudo lspci -vv -s $dev | grep -A6 -i "Access Control Services"; done
== 00:01.0 ==
Access Control Services
ACSCap: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl+ DirectTrans+
ACSCtl: SrcValid+ TransBlk- ReqRedir- CmpltRedir- UpstreamFwd- EgressCtrl- DirectTrans-
== 03:00.0 ==
Access Control Services
ACSCap: SrcValid+ TransBlk- ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl- DirectTrans-
ACSCtl: SrcValid+ TransBlk- ReqRedir- CmpltRedir- UpstreamFwd- EgressCtrl- DirectTrans-
Значення: Можливості відрізняються на кожному порті. Деякі порти можуть робити перенаправлення запитів, але не контролювати upstream‑пересилання і т.д.
Рішення: Якщо потрібні порти не мають ACS — безпечної ізоляції ви не отримаєте. Плануйте зміну апаратної частини або прийміть групування.
Завдання 14: Перевірити, чи платформа примусово використовує «Above 4G decoding» / вплив Resizable BAR
cr0x@server:~$ dmesg | grep -iE "Resizable BAR|Above 4G|pci 0000"
[ 0.222222] pci 0000:01:00.0: BAR 0: assigned [mem 0x8000000000-0x800fffffff 64bit pref]
[ 0.222333] pci 0000:01:00.0: BAR 2: assigned [mem 0x8010000000-0x8011ffffff 64bit pref]
Значення: Великі BAR‑мапінги не є проблемою групування, але можуть виявити баги прошивки та проблеми виділення ресурсів, які маскуються під проблеми VFIO.
Рішення: Якщо бачите помилки виділення ресурсів або відсутні BAR, виправте це перш за все; некоректна ініціалізація пристрою може змусити вас ганятися за фантомними «IOMMU‑проблемами».
Завдання 15: Підтвердити придатність VFIO без остаточної прив’язки (думка «сухого прогону»)
cr0x@server:~$ sudo dmesg | tail -n 20
[ 120.123456] vfio-pci 0000:01:00.0: enabling device (0000 -> 0003)
[ 120.123789] vfio-pci 0000:01:00.0: vfio_bar_restore: reset recovery - restoring BARs
[ 120.124111] vfio-pci 0000:01:00.1: enabling device (0000 -> 0002)
Значення: Коли ви прив’язуєте, ядро логує свої дії. Помилки тут часто вказують на особливості скидання, а не на групування.
Рішення: Якщо прив’язка працює чисто, але група спільна, не радійте. Ви все ще не можете безпечно делегувати частину спільної групи.
Жарт #1: IOMMU‑група як бронювання конференц‑кімнати: якщо ваш USB‑контролер з’явився, усі вийдуть із маркерами з вашої дошки.
Клініка PCIe‑топології: root port, мости, комутатори і ACS
Починайте з upstream‑шляху, а не з ендпоінта
Люди захоплюються моделлю GPU і забувають про нудну частину: PCIe‑фабрику. Ваш ендпоінт можна ізолювати лише настільки, наскільки найслабший міст між ним і CPU це підтримує. До уваги входять:
- Root port / root complex на CPU або чіпсеті.
- Низхідні порти (часто частина комутатора або чіпсетної структури).
- PCIe‑комутатори (PLX/Broadcom, ASMedia і т. п.).
- Інтегровані ендпоінти (вбудоване аудіо, USB‑контролери, SATA, Wi‑Fi).
ACS: що воно робить і чому змінює групування
Access Control Services — набір функцій, що допомагають запобігти або контролювати peer‑to‑peer трафік і забезпечують коректне маршрутування запитів вгору, де IOMMU може застосувати політику. Простими словами: ACS допомагає зупинити пристрої за одним комутатором/портом від прямого обміну між собою поза контролем IOMMU.
Linux використовує інформацію про ACS (та інші підказки топології), щоб вирішувати, чи можна розділити пристрої на різні IOMMU‑групи. Якщо платформа не може гарантувати ізоляцію, група лишається великою.
Типові патерни «чому мій GPU згрупований з X?»
- Низхідний порт чіпсета з фанов‑аулайном: кілька вбудованих контролерів під’єднані за одним портом чіпсета без ACS — тому їх групують.
- Спільний комутатор: два фізичні слоти фактично під одним PCIe‑комутатором без правильної ACS‑конфігурації.
- Мультиплексування ліній на материнській платі: увімкнення другого слота M.2 перенаправляє лінії і змінює, які пристрої ділять root‑порт.
- Багатофункційні пристрої: GPU video + GPU audio ділять групу. Це нормально і зазвичай бажано для passthrough.
Що насправді означає «виправити топологію»
Це не містика. Це одне з таких рішень:
- Перемістити карту в інший слот, що підключений до іншого root‑порту (найкраще — прикріпленого до CPU).
- Не використовувати слот/M.2, що змушує спільне використання ліній з тим, що потрібно ізолювати.
- Увімкнути опції прошивки, що показують ACS або коректний ремапінг (коли вони доступні).
- Використати апарат, що справді підтримує ізоляцію: робочі/серверні плати, перевірені комутатори, CPU з достатньою кількістю ліній.
- Прийняти групування і передати всю групу, якщо це безпечно і прийнятно операційно.
Більшість «проблем з IOMMU‑групами» — це ваша материнська плата, яка тихо каже, що вона розроблена для ігрового RGB, а не для надійних DMA‑меж.
BIOS/прошивка: налаштування, що мають значення (і ті, що ні)
Налаштування, які зазвичай важливі
- Intel: VT‑d (Directed I/O) має бути увімкнено. Тільки VT‑x — недостатньо.
- AMD: SVM увімкнює віртуалізацію CPU; IOMMU (або «AMD‑Vi») вмикає ремапінг DMA. Зазвичай потрібні обидва для passthrough.
- Above 4G decoding: часто потрібне для сучасних GPU і кількох PCIe‑пристроїв; також впливає на розподіл ресурсів прошивкою.
- SR‑IOV: увімкнення може змінити конфігурацію downstream‑портів і ARI; не обов’язково для passthrough, але важливо для VF NIC.
- Параметри PCIe ACS / «PCIe ARI»: якщо BIOS має опції, схожі на ACS, увімкніть їх. Якщо є ARI — увімкніть його при інтенсивному використанні SR‑IOV.
Налаштування, які люди переключають з відчаю
- CSM (Compatibility Support Module): вимкнення може допомогти ініціалізації сучасних GPU і розмірам BAR, але не розділить IOMMU‑групи.
- Примусова швидкість PCIe Gen: іноді допомагає стабільності лінку; рідко впливає на групування.
- «Gaming mode»: якщо такий режим є — відійдіть повільно.
Оновлення прошивки: непривабливе, але ефективне
Оновлення BIOS материнської плати та BMC/UEFI серверів може змінити експозицію ACS, пом’якшити проблеми ремапінгу та змінити розподіл ресурсів PCIe. Це не весело. Але це різниця між «працює місяцями» та «рандомним DMA‑фаултом о 3‑й ранку».
Параметри ядра, ACS override і коли їх не використовувати
Параметри, які ви побачите в природі
intel_iommu=on/amd_iommu=on: явне увімкнення.iommu=pt: passthrough‑режим для хост‑пристроїв (компроміс продуктивність/латентність).pcie_acs_override=downstream,multifunction: змушує ядро трактувати деякі порти так, ніби ACS‑розділення існує.
Що насправді робить ACS override
Воно змінює рішення Linux щодо групування, прикидаючись, що певні PCIe‑компоненти надають межі ізоляції, навіть коли вони не рекламують відповідні ACS‑можливості. Це може дати менші IOMMU‑групи і зробити VFIO щасливішим.
Але воно також може створити межу ізоляції, якої насправді немає. У сценарії з ворогуючим або скомпрометованим пристроєм це неприйнятно. У домашній лабораторії люди ризикують. У продукції потрібна серйозна розмова з власниками безпеки та ризиків.
Коли я використаю ACS override
- У лабораторіях, де єдиний «зловмисник» — моя власна нетерплячість.
- Для тимчасової валідації на платформі, яку ми вже плануємо замінити, щоб довести працездатність навантаження.
- Коли passthrough‑пристрій — єдиний значущий DMA‑ендпоінт у групі, а решта практично інертні (рідко).
Коли я відмовлюся від ACS override
- У мульти-орендних середовищах.
- У будь‑яких випадках з вимогами відповідності щодо ізоляції.
- У системах, де спільна група містить сховище або мережу, від яких залежить робота хоста.
Жарт #2: ACS override — як повісити стрічку «Не заходити» на дверях без дверей. Вона дає відчуття безпеки, поки хтось не пройде через неї.
Особливості стеку віртуалізації: Proxmox/KVM, bare metal та «корпоративні» системи
Перевірка реальності KVM/VFIO
VFIO суворе, бо воно — останній дорослий у кімнаті. Якщо група містить кілька пристроїв, VFIO хоче, щоб ви присвоїли всю групу одному гостю, бо її розділення призводить до невизначеної поведінки і дір у безпеці.
На практиці «потрібно передати лише GPU» означає, що група GPU має містити тільки функції GPU (і можливо USB‑контролер, якщо ви свідомо передаєте цілий контролер для введення).
Proxmox та подібні стеки
Proxmox полегшує перегляд груп і конфігурацію VFIO, але не може виправити материнську плату, яка «зварила» ваш слот GPU з тим самим низхідним портом, що й SATA‑контролер. Якщо Proxmox показує велетенську групу — повірте йому.
Робоча станція проти серверних плат
Сервери часто мають кращий розподіл ліній і передбачуваніший дизайн PCIe‑комутаторів. Робочі станції теж можуть бути добрі. Споживчі плати — це дикий захід: іноді пощастить, іноді чіпсетна фабрика — як автобус‑вечірка.
Примітка інженера зберігання: не діліться групами з HBA легковажно
Якщо група містить ваш HBA або NVMe‑контролер, який використовує хост, ви на один невдалий крок від передачі контролера сховища VM. Це не «налаштування продуктивності». Це рулетка з втратою даних.
Три корпоративні історії з практики
1) Інцидент через неправильне припущення
Вони збирали невеликий внутрішній кластер GPU для прискорення збірок і деякого ML‑інференсу. Нічого екзотичного: KVM, VFIO, кілька середніх GPU і стандартизована материнська плата, бо закупівля любила «стандартизацію». Хтось перевірив IOMMU у BIOS і побачив DMAR у dmesg. Оголосили платформу «passthrough‑ready».
Перші два вузли працювали, бо GPU стояли в слотах, підключених прямо до root‑портів CPU. Третій вузол зібрали трохи інакше — та сама плата, але додали NVMe‑карта‑носій. Цей накопичувач змінив біфуркацію ліній і пересунув слот GPU за шляхом через чіпсетний комутатор. Ніхто не помітив, бо GPU все ще відображалися в lspci.
На тому вузлі GPU опинився в тій же IOMMU‑групі, що USB‑контролер і SATA‑контролер. Інженер, що конфігурував VFIO, припустив, що «групи — це лише Linux‑штука», і примусово застосував ACS override, щоб їх розділити. Система пройшла початкові тести. Через тиждень під час інтенсивного навантаження на збірки хост зазнав періодичних помилок SATA, і потім файлову систему перевели в режим лише для читання. Розслідування було непоказним: вони створили фальшиву межу ізоляції, і інтенсивний DMA від GPU корелював з дивною поведінкою хост‑I/O.
Виправлення було болісно буденним: перемістити GPU в інший слот, відключити опцію спільного використання ліній і стандартизувати збірку так, щоб у кожного вузла була одна й та сама PCIe‑топологія. Також заборонили ACS override у продукції без погодження. Справжній урок не в тому, що «ACS override зло». Він у тому, що «IOMMU увімкнено» — не те саме, що «досягнута ізоляція IOMMU», а дрейф топології — це баг на надійності.
2) Оптимізація, що обернулася проти
Команда хотіла зменшити латентність для VM з високою пропускною здатністю пакетної обробки. Планували передати NIC і GPU для на‑літу інференсу. На хості також був швидкий NVMe для локального кешу. Хтось помітив, що NIC і NVMe в одній IOMMU‑групі на певній генерації платформи.
Замість зміни апаратури вони зробили «хитрий» крок: передали всю групу в VM, аргументуючи, що VM — це «реальне навантаження», а хост може завантажитися з дзеркального SATA DOM. На папері це знизило накладні витрати і уникнуло розділення груп. Навіть бенчмарки виглядали добре.
Потім прийшли операційники з нудними питаннями. Як ви будете патчити хост, якщо VM володіє контролером сховища для кешу і логів? Як зібрати дампи після збоїв? Що станеться, якщо VM зависне і триматиме PCIe‑функцію в поганому стані скидання? Відповідь була: перезавантажуйте і сподівайтеся. Це не план, це ритуал.
Оптимізація обернулася проти, коли в VM стався збій драйвера і вона перестала відповідати. Хост лишився «up», але втратив доступ до переданих пристроїв, включно з кеш‑NVMe. Моніторинг заволав, і вузол почав миготіти в сервісах. Повернулися до менш «ефективного» дизайну: розділили IOMMU‑групи, вибравши інше розташування слотів і платформу з більшою кількістю root‑портів, тримали критичне для хоста сховище поза будь‑якою passthrough‑групою. Продуктивність трохи впала. Аптайм значно виріс. Героїв ніхто не сумував.
3) Нудна, але правильна практика, що врятувала день
Інша організація працювала зі змішаними навантаженнями: деякі VM з NIC‑passthrough (SR‑IOV VFs), інші з повним passthrough пристроїв для спеціалізованих прискорювачів. Їх уже колись «спалили», тому була політика: для кожного SKU апаратури мався «манифест PCIe‑топології», закомічений у той же репозиторій, що й код провізії.
Коли прибув новий партія серверів, закупівельна команда підмінила «сумісну» ревізію материнської плати через проблеми з постачанням. Той самий сімейство CPU, той самий шасі, для неспеціаліста — все те саме. CI‑перевірка порівняла очікувані макети IOMMU‑груп з тими, що повідомив свіжезавантажений вузол. Вона відразу провалилася.
Замість виявлення проблеми в продукції після нічного оновлення ядра — вони помістили партію в карантин. Причина виявилася в іншій конфігурації PCIe‑комутатора на новій ревізії: слот прискорювача і вбудований RAID‑контролер тепер ділили низхідний порт без корисного ACS‑розділення. Постачальник міг надати прошивку для деяких плат, для інших — вирішення було в іншому райзері.
Практика була нудною: завантажити, зібрати lspci, зібрати мапінги груп, зробити diff з очікуваним, швидко фейлити. Це зекономило дні дебагу і запобігло повільному інциденту. Ось така «паперова робота» реально підвищує доступність системи — тому її ненавидять допоки вона не врятує.
Поширені помилки: симптом → корінь проблеми → виправлення
1) «Я увімкнув IOMMU, але /sys/kernel/iommu_groups порожній»
Симптом: Немає записів у директорії груп, VFIO скаржиться, гайди радять «увімкніть IOMMU».
Корінь проблеми: VT‑d/AMD‑Vi вимкнено в BIOS, або параметри завантаження ядра не вмикають його, або ви в режимі прошивки, що ховає ремапінг.
Виправлення: Увімкніть VT‑d/AMD IOMMU у BIOS; додайте intel_iommu=on або amd_iommu=on; оновіть BIOS, якщо таблиці DMAR пошкоджені.
2) «Мій GPU ділить групу з USB/SATA/NIC на материнській платі»
Симптом: Група містить GPU плюс несумісні вбудовані контролери.
Корінь проблеми: Пристрої сидять за тим самим низхідним портом/комутатором без ACS‑ізоляції; проводка материнської плати оптимізована під розподіл ліній, а не під ізоляцію.
Виправлення: Перемістіть GPU в слот, підключений до CPU; відключіть функції спільного використання ліній; уникайте M.2/райзерів, що перенаправляють лінії; оберіть плату з кращим розподілом root‑портів.
3) «Я використав ACS override, і воно працює, але з’являються випадкові помилки I/O на хості»
Симптом: Passthrough працює, але хост отримує періодичні PCIe/SATA/NVMe неполадки під навантаженням.
Корінь проблеми: Примусове розбиття груп створило межу, яку апарат не підтримує; peer‑to‑peer та DMA‑взаємодії стали невизначеними.
Виправлення: Приберіть ACS override; переробіть топологію; ізолюйте через реальні ACS‑здатні порти або передайте всю реальну групу, якщо це безпечно.
4) «Проблеми зі скиданням GPU виглядають як проблеми IOMMU»
Симптом: Після вимкнення VM GPU стає непридатним, наступний запуск VM не вдається, в dmesg помилки про reset.
Корінь проблеми: Особливості скидання GPU (FLR може не підтримуватися), поведінка драйвера вендора або обробка багатофункційності — не групування IOMMU.
Виправлення: Використовуйте підтримувані вендором механізми скидання (де застосовно), розгляньте інші моделі GPU, переконайтеся, що обидві функції GPU правильно прив’язані, уникайте гарячої переназначення в продукції.
5) «SR‑IOV VFs в великих групах і їх не можна чисто призначити»
Симптом: VFs ділять групи з PF і іншими пристроями несподівано.
Корінь проблеми: ARI/ACS/прошивка; платформа групує їх, бо ізоляцію гарантувати не можна.
Виправлення: Увімкніть SR‑IOV і ARI у BIOS якщо доступно; переконайтеся, що прошивка актуальна; використовуйте NIC і платформи, які відомі хорошою поведінкою з VFIO.
6) «Усі пристрої в одній групі на ноутбуку/mini PC»
Симптом: Одна гігантська група, немає чистих розривів, мрії про зовнішній GPU тануть.
Корінь проблеми: Інтегрована топологія з обмеженим ACS, чіпсет‑корінна фабрика і модель безпеки, що не розрахована на детерміновану ізоляцію.
Виправлення: Прийміть обмеження; використайте паравіртуалізовані пристрої; або перейдіть на апарат, розроблений для цього.
Контрольні списки / покроковий план
Покроково: від «спільної групи» до «чистої ізоляції»
- Базове увімкнення: підтвердьте DMAR/AMD‑Vi у
dmesgі наявність груп. - Визначте цілі: перелічіть PCI‑адреси пристроїв, які хочете передати.
- Мапуйте групи: виведіть членство груп і підтвердіть, хто з ким ділиться.
- Намалюйте upstream‑ланцюг: використайте
lspci -tv, щоб знайти upstream‑мости/порти. - Перевірте ACS на кожному релевантному порті:
lspci -vvна root/низхідних портах у шляху. - Спробуйте просте виправлення топології: перемістіть карту в інший слот; видаліть/перемістіть M.2/райзери, що викликають перенаправлення ліній.
- Перевіряйте групи після кожної фізичної зміни: не робіть масових змін — втратите причинно‑наслідковий зв’язок.
- Налаштування прошивки: увімкніть VT‑d/AMD IOMMU, Above 4G decoding, SR‑IOV/ARI за потреби; оновіть BIOS.
- Визначте ставлення до ризику: якщо потрібно ACS override — зафіксуйте чому, що саме в групі і який радіус ураження.
- Прив’язуйте драйвери тільки після коректної ізоляції: присвоюйте пристрої
vfio-pci, коли групи стали «нормальними». - Протестуйте шляхи скидання: старт/стоп VM кілька разів і слідкуйте за «зависанням» пристрою.
- Оперешналізуйте: зберігайте топологію + маппінг груп як артефакт для виявлення дрейфу в майбутньому.
Чекліст: готовність до продукції для passthrough
- Критично важливі для хоста сховище/мережеві пристрої не знаходяться в жодній групі, яку плануєте призначити.
- Жодного ACS override у продукції, якщо він не схвалений і ризик не прийнятий.
- Версії прошивок зафіксовані і протестовані на регресії топології під час оновлень.
- Поводження з скиданням пристроїв перевірено (холодний старт, теплий ребут, цикли старт/стоп VM).
- Моніторинг включає PCIe AER помилки, IOMMU‑faults і скидання драйверів пристроїв.
Чекліст: коли варто зупинитися і купити інше залізо
- Цільовий пристрій ділить групу з чипсетним SATA/USB/NVMe, який потрібен хосту, і немає альтернативного слоту/root‑порту.
- Upstream‑порти не мають ACS‑можливостей і ви не можете змінити топологію.
- Прошивка не має відповідних перемикачів і оновлення не змінюють поведінку.
- Система вимагає ACS override для роботи, і у вас мульти‑орендне або регламентоване середовище.
FAQ
1) Якщо IOMMU увімкнено, чому мої пристрої все ще в одній групі?
Тому що увімкнення ≠ ізоляція. Групування відображає, чи може PCIe‑фабрика забезпечити розділення (поведінка мостів/ACS), а не лише наявність ремапінгу DMA.
2) Чи нормально, що GPU і його аудіо‑функція ділять групу?
Так. Це один фізичний пристрій, що експонує кілька PCI‑функцій. Зазвичай їх передають разом.
3) Чи можна передати лише один пристрій із спільної групи?
Не безпечно. VFIO вимагає призначення на рівні групи, бо будь‑який пристрій у групі може виконувати DMA, що вплине на інших. Якщо ви розділите її «взламом», ви погоджуєтеся на невизначену поведінку і ризики безпеки.
4) Чи розділить мої IOMMU‑групи увімкнення «Above 4G decoding»?
Зазвичай ні. Це допомагає у виділенні ресурсів і мапінгу BAR для великих пристроїв, що може виправити проблеми ініціалізації, але саму ізоляцію не створює.
5) Чи впливає iommu=pt на групування?
Ні. Це впливає на те, як хост мапить DMA для пристроїв, що залишаються у хості, часто покращуючи продуктивність. Формування груп пов’язане з топологією і ACS, а не з passthrough vs translated mapping.
6) Яка найбезпечніша альтернатива, якщо не вдається отримати чисті групи?
Не використовуйте повний passthrough. Використайте паравіртуалізовані пристрої (virtio), шаровий доступ до GPU через API (де доступно) або перейдіть на апарат з кращою PCIe‑ізоляцією.
7) Чому мої IOMMU‑групи змінюються при додаванні NVMe або використанні іншого слота M.2?
Через спільне використання ліній і біфуркацію. Багато плат перенаправляють лінії залежно від заповненості сокетів. Це може пересунути пристрої за різні мости/комутатори і змінити ізоляцію.
8) Чи завжди небезпечний ACS override?
Воно послаблює припущення ядра про ізоляцію. У строгій моделі загроз — так, воно підриває гарантії. У одно‑користувацькій лабораторії багато хто погоджується на ризик. Головне — бути чесним щодо межі, яку ви прикидаєтесь існуючою.
9) Мої групи в порядку, але passthrough все одно не працює. Що робити далі?
Перевірте прив’язку драйверів, поведінку скидання пристрою, помилки виділення ресурсів прошивкою і чи пристрій підтримує FLR. Групування є необхідною умовою, але не достатньою.
10) Чому сервери «просто працюють» частіше, ніж десктопи?
Більше root‑портів, кращий бюджет ліній, послідовніший дизайн комутаторів PCIe і прошивка, що серйозніше ставиться до ACS і SR‑IOV. Також постачальники серверів очікують гучні скарги від віртуалізаційних клієнтів.
Висновок: наступні кроки, що дійсно рухають ситуацію
Якщо IOMMU увімкнено, але ваші пристрої все ще ділять групу — припиніть поводитися так, ніби це головоломка з параметрами ядра. Це розслідування PCIe‑топології. Виконайте нудну роботу: змапуйте дерево, визначте upstream‑порти, перевірте можливості ACS і змініть фізичне розміщення або платформу, доки апарат не зможе довести ізоляцію.
Наступні кроки:
- Запустіть команду інвентаризації груп і виділіть точних небажаних співмешканців у цільовій групі.
- Використайте
lspci -tvіlspci -vv, щоб знайти upstream‑ланцюг і чи існує ACS там, де це важливо. - Спробуйте одне змінення топології за раз: перемістіть карту в інший слот, змініть населення M.2, перемикайте біфуркацію/настройки PCIe, оновіть прошивку.
- Якщо все ще потрібен ACS override — зафіксуйте ризики, які пристрої ділять фабрику і як виглядає збій — і тоді приймайте рішення свідомо.
- Оперешналізуйте: зберігайте відому‑добру мапу IOMMU‑груп як регресійний тест, щоб «дрібна апаратна ревізія» не стала наступним інцидентом.