Оновлення ядра зламало passthrough? Як швидко діагностувати IOMMU

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

Нічого так не додає вам років, як «дрібне» оновлення ядра, що перетворює PCI passthrough на інтерпретативний танець. Вчора ваша ВМ мала GPU, HBA і заспокійливе відчуття стабільності. Сьогодні вона завантажується так, ніби намагається пригадати своє власне ім’я, а ваші IOMMU-групи виглядають так, ніби їх перемішав кіт.

Це практичний, орієнтований на продукцію посібник для швидкої діагностики регресій IOMMU та VFIO — без ритуальних жертв, розмитих порад з форумів або метання по BIOS-параметрах у надії, що щось «попрацює». Ми перевіримо апаратний шлях, шлях ядра, шлях прив’язки драйвера і шлях віртуалізації — у цьому порядку — щоб ви припинили гадати й почали ухвалювати рішення.

Швидкий план діагностики (робіть це першим)

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

По-перше: підтвердьте, що IOMMU справді ввімкнено і активне

  1. Перевірте параметри завантаження ядра на предмет прапорів IOMMU.
  2. Перегляньте dmesg на наявність ініціалізації IOMMU.
  3. Підтвердіть наявність IOMMU-груп у /sys/kernel/iommu_groups.

Рішення: Якщо IOMMU неактивне, не чіпайте VFIO, libvirt, QEMU чи Proxmox. Спочатку виправте прошивку та аргументи ядра.

По-друге: підтвердьте, що пристрій прив’язано до vfio-pci (а не до драйвера хоста)

  1. Запустіть lspci -nnk і дивіться на «Kernel driver in use».
  2. Переконайтеся, що vfio-pci завантажено і ID пристрою зіставлені.
  3. Перевірте, чи initramfs включає модулі VFIO, якщо потрібна рання прив’язка.

Рішення: Якщо GPU/HBA все ще зайнято amdgpu/nvidia/nouveau/ahci/megaraid_sas, ВМ програє. Виправте прив’язку перед тим, як лізти в групи.

По-третє: перевірте IOMMU-групи та регресії ізоляції

  1. Перелічіть групи і подивіться, що перемістилося.
  2. Шукайте симптоми «група зросла»: ваш GPU тепер ділиться з USB-контролером або аудіопристроєм, який ви не можете безпечно передати.
  3. Перевірте, чи змінилася поведінка ACS/ARI після оновлення ядра.

Рішення: Якщо проблема в групуванні, ви або (a) переміщаєте слоти, (b) налаштовуєте параметри PCIe в BIOS, (c) погоджуєтеся на ризик ACS override, або (d) міняєте материнську плату. Оберіть одне; не «просто перевизначайте» в продакшні без моделі загроз.

По-четверте: перевірте помилки DMA/IOMMU та проблеми зі скиданням

  1. Шукайте в dmesg IOMMU-помилки та DMAR/AMD-Vi помилки.
  2. Перевірте кверки FLR/скидання (особливо для GPU).
  3. Підтвердіть, що конфіг вашої ВМ не запитує неможливих речей (наприклад, невідповідність multifunction).

Рішення: Якщо це кверк скидання, можливо, потрібні параметри ядра, інший GPU або припинити намагатися «гаряче» перезапускати ВМ, ніби це вебсервер.

Короткий жарт №1: IOMMU-група — як офіс відкритого планування: один галасливий сусід — і ніхто не працює.

Що ймовірно змінилося після оновлення ядра

Оновлення ядра не «випадково» ламають passthrough. Воно змінює спосіб, як ядро перелічує пристрої, як застосовує кверки, як обробляє PCIe-функції і інколи як виставляє за замовчуванням безпеку проти зручності. Несправність здається випадковою, бо ваша ментальна модель застаріла.

Поширені тригери регресій passthrough після оновлення ядра

  • Інша енумерація топології PCIe: змінюється драйвер мосту або кверк, і ваш пристрій опиняється за іншим root портом з точки зору поведінки.
  • Зміни в обробці ACS/ARI: групи можуть зливатися або розділятися, коли ядро вирішує, що downstream-порт не можна довіряти для ізоляції.
  • Зміни поведінки VFIO: суворіші перевірки щодо небезпечних переривань, розмірів BAR або скидання пристрою.
  • Відмінності в initramfs: після встановлення ядра ваш initramfs може не включати ранню прив’язку vfio-pci; хост захоплює пристрій першим.
  • Взаємодія підписування модулів / Secure Boot: модуль з поза дерева не завантажується, і fallback-драйвер залишається в управлінні.
  • Прошивка/BIOS оновилися в комплекті: «поки ви тут» оновлення іноді змінюють налаштування віртуалізації або скидають параметри PCIe.

Два правила, що тримають вас в глузді

Правило 1: Розглядайте passthrough як ланцюг володіння. Прошивка експонує, ядро перелічує, IOMMU ізолює, VFIO прив’язує, гіпервізор призначає. Злами відбуваються на рівні ланки, а не в абстракції.

Правило 2: Не намагайтеся виправити групування, поки не доведете прив’язку і активацію IOMMU. Інакше ви «виправите» не той шар і нічому не навчитесь.

Цікаві факти та коротка історія, що дійсно допомагає

Трохи передісторії допоможе передбачити, які ручки важливі, а які — плацебо.

  1. Intel «VT-d» і AMD «AMD-Vi» — різні бренди для тієї самої основної ідеї: DMA remapping, щоб пристрої не писали в довільну пам’ять.
  2. IOMMU спочатку не був про зручність віртуалізації; він був про безпеку та коректність при DMA-процесах пристроїв.
  3. Ранній VFIO замінив старі підходи (як-от спадкові шляхи призначення KVM), спираючись на IOMMU для ізоляції та на ядро для медіації.
  4. ACS (Access Control Services) — це функція PCIe, що допомагає забезпечувати межі ізоляції; відсутність ACS — причина «липких» груп на споживчих платформах.
  5. ARI (Alternative Routing-ID Interpretation) впливає на те, як адресуються функції за мостом; зміни в обробці ARI можуть змінювати групування та поведінку multifunction.
  6. MSI/MSI-X ремап переривань важливий: passthrough безпечніший, коли платформа підтримує ремап переривань; деякі ядра жорсткіші, якщо він відсутній.
  7. FLR (Function Level Reset) опціональний у PCIe-пристроїв; багато пристроїв «підтримують скидання» в маркетингових термінах, але поводяться погано при повторних перезапусках ВМ.
  8. GPU passthrough став простішим і складнішим одночасно: кращі можливості VFIO і QEMU, але й складніші GPU, режими енергоспоживання та взаємодія з прошивкою.
  9. Існування ACS override — це результат того, що реальність заплутана, а не найкраща практика; воно змушує ядро вдавати, що ізоляція існує там, де апарат її не гарантує.

Практичні завдання діагностики (команди, вихід, рішення)

Ось завдання, які я виконую в продакшні, коли passthrough ламається після оновлення ядра. Кожне завдання містить: команду, що означає її вихід, і рішення, яке треба прийняти далі. Виконуйте їх у порядку, якщо хочете швидко; або вибирайте цільово, якщо вже знаєте шар, що впав.

Завдання 1: Підтвердіть запущене ядро та контекст останнього завантаження

cr0x@server:~$ uname -r
6.8.0-48-generic

Що це означає: Ви дебагуєте запущене ядро. Якщо ви щойно оновили, але не перезавантажилися, ви можете ганятися за привидами.

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

Завдання 2: Перевірте командний рядок ядра на параметри IOMMU

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/boot/vmlinuz-6.8.0-48-generic root=UUID=2a3d... ro quiet splash intel_iommu=on iommu=pt

Що це означає: Ви запросили Intel IOMMU та режим «passthrough» для хост-пристроїв (iommu=pt), що може зменшити накладні витрати для не призначених пристроїв.

Рішення: Якщо у вас AMD, intel_iommu=on декоративний. Використовуйте amd_iommu=on. Якщо жодного немає, додайте потрібний та перегенеруйте конфіг завантажувача.

Завдання 3: Доведіть, що IOMMU справді ініціалізовано (Intel DMAR / AMD-Vi)

cr0x@server:~$ dmesg -T | egrep -i 'DMAR|IOMMU|AMD-Vi' | head -n 20
[Tue Feb  4 10:18:11 2026] DMAR: IOMMU enabled
[Tue Feb  4 10:18:11 2026] DMAR: Host address width 46
[Tue Feb  4 10:18:11 2026] DMAR: DRHD base: 0x000000fed90000 flags: 0x0
[Tue Feb  4 10:18:11 2026] DMAR: Intel(R) Virtualization Technology for Directed I/O

Що це означає: Ядро каже, що IOMMU увімкнено і знайдено DMAR-блоки.

Рішення: Якщо бачите «IOMMU disabled» або нічого — зупиніться. Ідіть у BIOS/UEFI: увімкніть VT-d/AMD-Vi, і вимикайте «Above 4G decoding» лише якщо у вас специфічна проблемна платформа (рідко; зазвичай його хочуть увімкнути).

Завдання 4: Підтвердьте наявність IOMMU-груп

cr0x@server:~$ ls -1 /sys/kernel/iommu_groups | head
0
1
10
11
12

Що це означає: Групування IOMMU активне. Відсутність груп зазвичай означає, що IOMMU не ввімкнено або ви в режимі, який не створює sysfs-записи груп.

Рішення: Якщо цей шлях порожній або відсутній, поверніться до Завдань 2–3 і налаштувань прошивки. Не витрачайте час на прив’язку VFIO поки це не вирішено.

Завдання 5: Інвентаризація пристроїв і поточна прив’язка драйверів

cr0x@server:~$ lspci -nnk | sed -n '1,120p'
00:00.0 Host bridge [0600]: Intel Corporation Device [8086:3e0f] (rev 0a)
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080] [10de:1e87] (rev a1)
	Subsystem: Device [1462:3771]
	Kernel driver in use: nvidia
	Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia
01:00.1 Audio device [0403]: NVIDIA Corporation TU104 HD Audio Controller [10de:10f8] (rev a1)
	Kernel driver in use: snd_hda_intel
	Kernel modules: snd_hda_intel

Що це означає: GPU зайнятий драйвером хоста NVIDIA, а його аудіо-функція — snd_hda_intel. Passthrough зазнає невдачі або буде нестабільним, якщо хост володіє пристроєм.

Рішення: Якщо ваша мета — передати GPU, прив’яжіть обидві функції (VGA + audio) до vfio-pci. Якщо прив’язати тільки одну, часто виникають помилки або ВМ зависає під час завантаження.

Завдання 6: Визначте членство IOMMU-групи для цільового пристрою

cr0x@server:~$ for g in /sys/kernel/iommu_groups/*; do echo "Group $(basename "$g")"; ls -1 "$g/devices" | sed 's/^/  /'; done | sed -n '1,60p'
Group 1
  0000:00:01.0
Group 2
  0000:01:00.0
  0000:01:00.1
Group 3
  0000:00:14.0
  0000:00:14.2

Що це означає: Функції GPU діляться Group 2 разом (добре), але вам потрібно перевірити, чи немає в цій групі інших пристроїв (погано). Тут це лише дві функції GPU.

Рішення: Якщо ваш GPU ділиться групою з іншими пристроями, які ви не можете передати (наприклад SATA-контролер із кореневим диском), у вас проблема ізоляції. Переходьте до виправлення групування, а не до налаштування VFIO.

Завдання 7: Помітити, що змінилося, порівнявши групи до/після (якщо є логи)

cr0x@server:~$ journalctl -b -1 -k | egrep -i 'DMAR|IOMMU|ACS|vfio' | tail -n 20
Jan 31 09:12:02 server kernel: DMAR: IOMMU enabled
Jan 31 09:12:03 server kernel: vfio-pci 0000:01:00.0: enabling device (0000 -> 0003)

Що це означає: Попереднє завантаження показує, що VFIO-прив’язка відбулася (або принаймні намагалася). Якщо поточний запуск не показує схожих рядків, щось змінилося в initramfs/порядку завантаження модулів або в ID пристроїв.

Рішення: Якщо попередній запуск мав VFIO, а поточний — ні, зосередьтеся на initramfs і конфігурації modprobe, а не на BIOS чи ACS.

Завдання 8: Переконайтеся, що модулі VFIO завантажені

cr0x@server:~$ lsmod | egrep 'vfio|kvm' | head
vfio_pci               163840  0
vfio_pci_core           73728  1 vfio_pci
vfio_iommu_type1        45056  0
vfio                    65536  2 vfio_pci_core,vfio_iommu_type1
kvm_intel              430080  0
kvm                  1335296  1 kvm_intel

Що це означає: Базові частини VFIO присутні. Якщо vfio_iommu_type1 відсутній, VFIO не може безпечно відобразити DMA і призначення пристрою зазнає невдачі.

Рішення: Якщо модулі відсутні — завантажте їх і забезпечте їх постійне завантаження. Для Debian/Ubuntu додайте їх у /etc/modules або переконайтеся, що initramfs включає їх.

Завдання 9: Прив’язати пристрій до vfio-pci (тимчасово, у рантаймі)

cr0x@server:~$ sudo modprobe vfio-pci
cr0x@server:~$ echo 10de 1e87 | sudo tee /sys/bus/pci/drivers/vfio-pci/new_id
10de 1e87
cr0x@server:~$ sudo lspci -nnk -s 01:00.0
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU104 [GeForce RTX 2080] [10de:1e87] (rev a1)
	Subsystem: Device [1462:3771]
	Kernel driver in use: vfio-pci
	Kernel modules: nvidiafb, nouveau, nvidia_drm, nvidia

Що це означає: Пристрій зараз прив’язано до vfio-pci (в рантаймі). Це доводить, що прив’язка працює без перезавантаження.

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

Завдання 10: Зробити прив’язку VFIO постійною (конфіг modprobe + initramfs)

cr0x@server:~$ sudo tee /etc/modprobe.d/vfio.conf >/dev/null <<'EOF'
options vfio-pci ids=10de:1e87,10de:10f8 disable_vga=1
EOF
cr0x@server:~$ sudo tee -a /etc/modules >/dev/null <<'EOF'
vfio
vfio_pci
vfio_iommu_type1
vfio_pci_core
EOF
cr0x@server:~$ sudo update-initramfs -u
update-initramfs: Generating /boot/initrd.img-6.8.0-48-generic

Що це означає: Ви попросили vfio-pci захоплювати конкретні ID пристроїв і забезпечили наявність модулів на ранній стадії. disable_vga=1 може допомогти з арбітрацією primary VGA на деяких платформах.

Рішення: Якщо після перезавантаження хост все ще захоплює GPU, ймовірно, потрібно заблокувати драйвери хоста (nouveau/nvidia/amdgpu) або видалити framebuffer-консолі. Робіть це обдумано; не додавайте у чорний список storage/network драйвери без крайньої потреби, якщо не любите виїзди інженерів.

Завдання 11: Перевірте статус чорного списку для конфліктних GPU-драйверів

cr0x@server:~$ grep -R "blacklist nouveau\|blacklist nvidia\|blacklist amdgpu" /etc/modprobe.d || true
/etc/modprobe.d/blacklist-nouveau.conf:blacklist nouveau
/etc/modprobe.d/blacklist-nouveau.conf:options nouveau modeset=0

Що це означає: Nouveau внесено до чорного списку. Це зменшує одну з поширених гонок, де відкритий драйвер прив’язується першим.

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

Завдання 12: Перевірте, чи доступне ремапування переривань (безпека і стабільність)

cr0x@server:~$ dmesg -T | egrep -i 'interrupt remap|IR:' | head
[Tue Feb  4 10:18:11 2026] DMAR-IR: Enabled IRQ remapping in x2apic mode

Що це означає: Ремап переривань увімкнено. Це важливо для безпечного призначення пристроїв і може впливати на попередження VFIO про «небезпечні переривання».

Рішення: Якщо у вас нема ремапа переривань, passthrough все ще може працювати, але ви в зоні «працює — поки не перестане». Для корпоративних середовищ відсутність IRQ remap — це ризик платформи, а не дрібний параметр.

Завдання 13: Виявити здатність ACS і чи довіряє ядро топології

cr0x@server:~$ sudo lspci -s 00:01.0 -vv | egrep -i 'ACSCap|ACSctl|ARI|SR-IOV' -n
82:	ACSCap: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl+ DirectTrans+
84:	ACSctl: SrcValid+ TransBlk+ ReqRedir+ CmpltRedir+ UpstreamFwd+ EgressCtrl+ DirectTrans+

Що це означає: Висхідний порт рекламує можливості ACS. Це підвищує шанси на чисті групи без перевизначень.

Рішення: Якщо ACS відсутній на ключових мостах, прийміть, що «ідеальні групи» можуть бути неможливі на цій платі. Перемістіть пристрої в інші слоти/root-порти, перш ніж вдаватися до ACS override.

Завдання 14: Перевірте IOMMU-помилки під час запуску ВМ

cr0x@server:~$ dmesg -T | egrep -i 'fault|DMAR:.*fault|AMD-Vi:.*Event|vfio.*error' | tail -n 20
[Tue Feb  4 10:26:44 2026] DMAR: DRHD: handling fault status reg 2
[Tue Feb  4 10:26:44 2026] DMAR: [DMA Read NO_PASID] Request device [01:00.0] fault addr 0x7f3c0000 [fault reason 0x06] PTE Read access is not set

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

Рішення: Якщо помилки з’являються одразу при старті ВМ — підозрюйте скидання/стан прошивки пристрою або неповне passthrough (відсутня компаньйон-функція). Якщо помилки під час навантаження — підозрюйте баги драйвера/прошивки або модулі з поза дерева, що взаємодіють некоректно.

Завдання 15: Переконайтеся, що пристрій підтримує прийнятну поведінку скидання

cr0x@server:~$ sudo lspci -s 01:00.0 -vv | egrep -i 'Capabilities: \[.*\] Express|FLR|PowerCtl|LnkCtl' -n | head -n 30
10:	Capabilities: [60] Express (v2) Endpoint, MSI 00
45:	DevCtl: CorrErr- NonFatalErr+ FatalErr+ UnsupReq+
72:	Capabilities: [100] Advanced Error Reporting

Що це означає: Ви бачите можливості PCIe Express, але явних рядків FLR тут може не бути; підтримка FLR варіюється, і деякі GPU поводяться погано навіть якщо формально підтримують скидання.

Рішення: Якщо проблема в тому, що «перша завантаження ВМ працює, друга — ні», швидше за все це кверки скидання. Виправлення часто: уникати частих перезапусків ВМ, холодна перезавантаження хоста між призначеннями або вибір апаратури з кращою семантикою скидання.

Завдання 16: Підтвердіть, що QEMU/KVM бачать IOMMU і VFIO-пристрої

cr0x@server:~$ sudo virsh nodedev-list | egrep 'pci_0000_01_00_[01]' || true
pci_0000_01_00_0
pci_0000_01_00_1

Що це означає: Libvirt бачить PCI-пристрої як node devices. Це перевірка інвентарю на рівні гіпервізора.

Рішення: Якщо libvirt не бачить їх, ваша udev/libvirt-середа зламана або права доступу неправильні. Не продовжуйте міняти VFIO-ID, якщо шар управління не може перелічити пристрої.

Завдання 17: Підтвердьте права доступу до vfio-нод і групову власність

cr0x@server:~$ ls -l /dev/vfio
total 0
crw-rw---- 1 root kvm  10, 196 Feb  4 10:20 0
crw-rw---- 1 root kvm  10, 196 Feb  4 10:20 2
crw-rw---- 1 root kvm  10, 196 Feb  4 10:20 vfio

Що це означає: VFIO group character devices існують і зазвичай належать root:kvm. Якщо ваш libvirt/QEMU працює без привілеїв, членство в групі має значення.

Рішення: Якщо права неправильні — виправте групи сервісного облікового запису гіпервізора або правила udev. Не робіть chmod 666 і не називайте це «вирішено». Це не інженерія, це капітуляція.

Завдання 18: Перевірте проблеми з Secure Boot/підписуванням модулів (поширено після оновлень)

cr0x@server:~$ dmesg -T | egrep -i 'Lockdown|Secure boot|module verification|taint' | tail -n 10
[Tue Feb  4 10:18:12 2026] Lockdown: Loading of unsigned modules is restricted; see man kernel_lockdown.7

Що це означає: Ядро в режимі, що обмежує завантаження непідписаних модулів. Якщо ваша конфігурація залежить від модулів з поза дерева (поширено для відеодрайверів вендорів), вони можуть не завантажуватися після оновлення.

Рішення: Або зареєструйте ключі/підпишіть модулі належним чином, або уникайте залежності від модулів хоста для passthrough GPU. Якщо хост потребує драйверів вендора — розглядайте Secure Boot як вимогу, а не сюрприз.

Три корпоративні міні-історії (біль, зарозумілість, буденна перемога)

Міні-історія 1: Інцидент через хибне припущення

У них була маленька віртуалізаційна ферма для прискорення збірок: кілька ВМ з passthrough GPU для тестів рендерингу. Це не було «критично для бізнесу», що корпоративною мовою означає — стає критичним о 2-й ночі, коли керівництво хоче демо.

Рутинне оновлення ядра пройшло. Після перезавантаження половина ВМ не стартувала. Оператор на чергуванні побачив, що GPU все ще в списку хоста з завантаженим вендорним драйвером і припустив: «Це нормально; ВМ все одно може прив’язати його». Це припущення перетворило вирішуваний баг на чотиригодинний інцидент.

Насправді все було простіше: рання прив’язка змінилася. Оновлений initramfs перестав включати модулі vfio-pci через дрейф конфігурації в їхньому пайплайні образів. Хост захопив GPU раніше, ніж VFIO отримав шанс. Вони витратили час на зміну налаштувань BIOS і перестановку слотів PCIe, бо «групи виглядали інакше», коли насправді групи були в порядку — прив’язка була неправильною.

Після того як вони знову додали модулі VFIO в initramfs і зафіксували ID для vfio-pci, усе повернулося. Постмортем не був про VFIO. Він був про «перевірити шар, який ви змінюєте». Фікс додали в збірку образу як явну перевірку: провалювати збірку, якщо vfio-модулі відсутні в initramfs для GPU-хостів.

Міні-історія 2: Оптимізація, що відверто відплатилася

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

Після оновлення ядра один SKU апаратури почав кидати періодичні DMA-фаулти під дуже специфічним навантаженням: інтенсивний I/O плюс часте створення/видалення ВМ. Логи показували DMA-запити, які не були відображені так, як очікували. Першою реакцією було звинуватити ядро.

Реальна причина була негарнішою: комбінація «режиму passthrough для хост-пристроїв» та апаратного кверка навколо ATS/PRI створила чутливу до таймінгу поведінку при швидкому приєднанні/відключенні. На старих ядрах кверк це маскував. На новому ядрі кверк змінився і оптимізація оголила проблему коректності.

Вони відкочували прапор продуктивності для того SKU, а потім повторно вводили його тільки після валідації набору функцій PCIe і поведінки пристрою по флоту. Урок: прапори продуктивності — не прикраси. Ставте їх як зміну коду. Гейтуйте тестами, а не інтуїцією.

Міні-історія 3: Нудна, але правильна практика, що врятувала день

Команда зберігання даних вела невелику флотилію гіпервізорів із passthrough HBA до ВМ, що надавали сховищні сервіси. Вони були консервативні до дратівливості: кожне оновлення ядра вимагало пробного перезавантаження на канарі-хості, і вони завжди знімали «знімок здоров’я passthrough» перед будь-якими змінами.

Знімок був нудним: версія ядра, /proc/cmdline, статус IOMMU з dmesg, повний перелік IOMMU-груп і lspci -nnk для HBA. Потім вони зберігали це разом з запитом на зміну. Нікому не подобався цей процес. Він не був гламурним. Він працював.

Одне оновлення змінило групування IOMMU на конкретній ревізії материнської плати. Канарі-перезавантаження миттєво показало, що HBA-група тепер містить root-порт, який спільний з NIC. Це б заблокувало безпечне призначення і примусило б ризикований ACS override. Вони зупинили розгортання, перемістили навантаження і відкоригували розташування слотів для тієї моделі.

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

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

Цей розділ навмисно прямолінійний. Ось найпоширеніші режими відмов після оновлень ядра, зіставлені з виправленнями, які реально закривають проблему.

1) ВМ не стартує: «vfio: failed to setup container» або «No such device»

Симптом: Старт ВМ негайно провалюється; логи згадують VFIO контейнер або помилки відображення IOMMU type1.

Коренева причина: IOMMU не ввімкнено в прошивці/ядрі, або відсутній vfio_iommu_type1.

Виправлення: Увімкніть VT-d/AMD-Vi в BIOS; додайте правильні аргументи ядра; завантажте VFIO-модулі; перебудуйте initramfs.

2) Пристрій виявляється, але драйвер хоста все ще прив’язаний після перезавантаження

Симптом: lspci -nnk показує nvidia/amdgpu/snd_hda_intel як «in use».

Коренева причина: VFIO-прив’язка не відбувається рано; initramfs не містить vfio-pci; конфліктні драйвери завантажуються першими.

Виправлення: Використовуйте options vfio-pci ids=... і забезпечте наявність VFIO-модулів в initramfs; додавайте драйвери в чорний список там, де потрібно; тримайте хост подалі від GPU-консолі.

3) IOMMU-групи погіршилися після оновлення (пристрої злилися)

Симптом: GPU/HBA ділить групу з USB-контролером, SATA-контролером або іншим критичним пристроєм.

Коренева причина: Ядро змінило довіру ACS/кверків; BIOS змінив маршрутизацію PCIe; плата позбавлена ACS на мостах.

Виправлення: Перемістіть пристрій в інший слот/root-порт; увімкніть ACS/ARI в BIOS, якщо доступно; уникайте ACS override, якщо не приймаєте ризик ізоляції.

4) Перша завантаження ВМ працює; друга — ні або пристрій зникає

Симптом: ВМ стартує один раз після перезавантаження хоста; наступні запуски зависають або пристрій не приєднується.

Коренева причина: Кверки скидання пристрою (питання FLR у GPU, поведінка D3cold), або драйвер гостя лишає пристрій у поганому стані.

Виправлення: Віддавайте перевагу апаратурі, відомій чистим скиданням; використовуйте повний перезавантаження хоста між призначеннями; налаштуйте коректне вимкнення гостя; уникайте «швидких циклів перезапуску».

5) Випадкові IOMMU-помилки під навантаженням

Симптом: dmesg показує DMA-фаулти, коли гість завантажений; продуктивність падає або ВМ падає.

Коренева причина: Нестабільна прошивка платформи, баг у прошивці/драйвері пристрою або ситуація з небезпечним ремапом переривань.

Виправлення: Перевірте ремап переривань; оновіть прошивку материнської плати; протестуйте іншим ядром; відмовтесь від прапорів продуктивності, поки стабільність не доведена.

6) «ACS override виправило» і потім стаються дивні речі

Симптом: Ви змусили групи розділитися; ВМ стартує; пізніше з’являються помилки шини, DMA-фаулти або питання безпеки.

Коренева причина: ACS override фальшиво імітує межі ізоляції; пристрої все ще можуть DMA у способи, які апаратно не ізольовані.

Виправлення: Розглядайте ACS override як крайній засіб; у мультиорендних або чутливих середовищах не використовуйте його. Виправте топологію апаратури замість цього.

Короткий жарт №2: ACS override — як заклеїти пластиром автоматичний вимикач — тихо аж до моменту, коли вже не тихо.

Перевірочні списки / покроковий план

Чеклист A: План «потрібно повернути за 30 хвилин»

  1. Захопіть докази: збережіть uname -r, /proc/cmdline, рядки IOMMU з dmesg, lspci -nnk для цільових пристроїв і перелік груп.
  2. Доведіть активність IOMMU: якщо немає DMAR/AMD-Vi — спочатку виправляйте BIOS/параметри ядра.
  3. Доведіть прив’язку: пристрій має бути vfio-pci в lspci -nnk.
  4. Доведіть групи: група цільового пристрою не має включати непрохідні критичні пристрої.
  5. Спробуйте старт ВМ один раз: зберіть помилки. Не запускайте старт у циклі; це ховає проблеми зі скиданням.
  6. Якщо підозрюються кверки скидання: зробіть одне чисте перезавантаження хоста, запустіть ВМ один раз і уникайте частих перезапусків до постійного фіксу.

Чеклист B: План «закріпити виправлення назавжди»

  1. Зафіксуйте аргументи ядра в конфігу завантажувача і задокументуйте їх (Intel vs AMD важить).
  2. Забезпечте постійну прив’язку VFIO через /etc/modprobe.d/vfio.conf і перебудову initramfs.
  3. Чорносписуйте конфліктні драйвери лише коли впевнені, що хост їх не потребує.
  4. Запишіть базові IOMMU-групи і порівнюйте після оновлень на канарі-хості.
  5. Перевірте ремап переривань і вважайте його відсутність як ризик платформи.
  6. Визначте політику ACS override (де дозволено? ніколи на хостах із спільним доступом? тільки в лабі?). Запишіть її.
  7. Протестуйте холодний/теплий перезавантаження для кожного класу пристроїв passthrough (GPU, HBA, NIC). Деякі пристрої брешуть щодо якості скидання.
  8. Автоматизуйте перевірки, щоб наступне оновлення не перетворилося на пошук скарбів.

Чеклист C: Мінімальний «знімок здоров’я passthrough», який потрібно зберігати

  • Версія ядра: uname -r
  • Аргументи завантаження: cat /proc/cmdline
  • Рядки ввімкнення IOMMU: dmesg -T | egrep -i 'DMAR|AMD-Vi|IOMMU' | head
  • Перелік груп: перерахунок /sys/kernel/iommu_groups
  • Прив’язка драйверів: lspci -nnk відфільтровано до призначених пристроїв
  • Погляд гіпервізора: virsh nodedev-list або еквівалент вашої платформи

Ідея надійності, яку варто вкрасти

Парафразована ідея (від Werner Vogels, CTO Amazon): «Ти будуєш — ти і експлуатуєш». Команда, що робить зміну, має відповідати за операційний результат.

Passthrough — це не «проблема апаратури» або «проблема ядра», яку можна послати через паркан. Якщо ви це експлуатуєте — потрібен чеклист регресій і шлях відкату.

Питання та відповіді

1) Мої IOMMU-групи змінилися після оновлення ядра. Це нормально?

Це не рідкість. Групування походить від топології PCIe плюс того, у що ядро вірить щодо ізоляційних функцій (ACS/ARI/кверки). Якщо ядро змінює, як воно довіряє мосту, групи можуть зливатися або розділятися. Розглядайте це як регресію для тріажу, а не як «систему, що переселилась духами».

2) Чи варто використовувати acs_override=downstream,multifunction щоб виправити групування?

Тільки якщо ви розумієте компроміси безпеки та коректності. ACS override змушує ядро прикидатися, що ізоляція існує. У лабораторії може бути норм, у спільних чи чутливих середовищах — уникайте і краще виправляйте топологію (слоти, плату).

3) Який найшвидший спосіб сказати, що passthrough ламається через прив’язку?

lspci -nnk. Якщо «Kernel driver in use» не vfio-pci для пристрою, який ви хочете передати (і для його компаньйон-функцій), у вас ще немає passthrough. Все інше вторинне.

4) Чому треба передавати аудіофункцію GPU також?

Бо це окрема PCI-функція на тому ж пристрої. Залишивши її на хості, ви можете перешкодити правильному скиданню, заплутати гостя або викликати конфлікти власності/груп. Розглядайте GPU + GPU-audio як пару, якщо у вас немає конкретної причини і доказів, що безпечно розділити.

5) Моя ВМ працює тільки після повного перезавантаження хоста. Що відбувається?

Поведінка скидання. Деякі пристрої не скидаються чисто при відключенні від гостя, особливо споживчі GPU. Пристрій опиняється в стані, з якого наступний старт ВМ не може відновитися. Обхідні шляхи: уникати частих перезапусків ВМ, використовувати іншу апаратну платформу або погоджуватись на перезавантаження хоста між запусками.

6) iommu=pt допомагає чи шкодить?

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

7) Як Secure Boot і оновлення ядра впливають на passthrough?

Якщо ви залежать від модулів з поза дерева (часто для драйверів GPU вендорів), Secure Boot може блокувати їх після оновлення, якщо вони не підписані/не зареєстровані. Це змінює прив’язку драйвера і може непрямо зламати вашу конфігурацію. Перевіряйте dmesg на повідомлення про lockdown і перевірку модулів.

8) Я бачу IOMMU-помилки в dmesg. Це завжди фатально?

Не завжди, але це ніколи не „гаразд“. Помилки означають, що пристрій спробував DMA поза дозволеними відображеннями. Якщо це стосується вашого passthrough-пристрою — сприймайте це як серйозний сигнал: неповне passthrough, кверки скидання, баги драйвера або нестабільна платформа.

9) Чи безпечно гаряче підключати пристрої passthrough?

Інколи, але не приймайте це як даність. Гаряче підключення додає складності: стани живлення, семантика скидання і гонки енумерації. Для продукційної надійності надавайте перевагу статичному призначенню з перевіреною апаратурою.

10) Що потрібно знімати перед оновленням ядра на хостах із passthrough?

Версію ядра, аргументи завантаження, рядки ввімкнення IOMMU, інвентар IOMMU-груп і прив’язку драйверів для призначених пристроїв. Якщо не можете порівняти «до» і «після», ви будете гадати, а гадання дорогі.

Висновок: наступні кроки, що працюють

Коли оновлення ядра ламає passthrough, переможний хід — відмовитись від метушні. Підтвердіть активацію IOMMU, потім VFIO-прив’язку, потім групи, потім помилки/кверки скидання. Цей порядок не дозволяє «виправити» три не пов’язані речі й нічому не навчитися.

Зробіть наступне:

  1. Напишіть одну команду «знімок здоров’я passthrough» і зберігайте її вивід до та після оновлень.
  2. Перезавантажуйте канарі-хост для кожного апаратного SKU перед флотовим патчем.
  3. Запишіть вашу політику щодо ACS override і дотримуйтесь її.
  4. Для пристроїв з поганою поведінкою скидання змініть операційний підхід (менше перезапусків, холодні перезавантаження) або міняйте апаратуру. Героїчні дії — не стратегія.

Якщо нічого іншого не робити: наступного разу, коли це зламається, не починайте з конфігурації ВМ. Почніть з dmesg, /proc/cmdline і lspci -nnk. Машина вже каже правду. Ваша задача — слухати в правильному порядку.

← Попередня
Геймпад не працює в Windows: виправлення HID‑драйверів акуратно
Наступна →
Конвертація MBR у GPT без перевстановлення (за допомогою вбудованих інструментів)

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