Рубрики
Виртуализация

Виртуализация QEMU — прямой доступ к устройствам

Активно применяя идеи Виртуализации на рабочем месте, я непременно столкнусь с тем, что не все операционные системы (а скорее их приложения) одинаково хорошо работают со всеми устройствами. Классическая пример домашнего пользователя — переключился бы на Linux, если бы не игры. Каким образом обеспечить доступ из виртуальной машины непосредственно к устройству?

TODO:BIOS/Стенд

Включение виртуализации в BIOS. Описать конфигурацию системы, тестовый стенд (сослаться на соответствующую статью). Сослаться на DC1-09 в дата-центре BatCave.

TODO: Обновление BIOS до F12 (до настроек, иначе оно собъёт)

Tweaker -> Advanced CPU Settings -> SVM Mode -> Enabled

Settings -> Miscellaneous -> IOMMU -> Enabled (TODO:или Auto)

В качестве тестовой платформы беру Дистрибутив Linux, заглядывающий в будущее. Максимально свежие драйвера, QEMU и т.п.

TODO: Ссылка на QEMU.

[root@fedora ~]# uname -a
Linux fedora 5.12.0-0.rc3.20210319git8b12a62a4e3e.172.fc35.x86_64 #1 SMP Fri Mar 19 17:12:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

Доступ, соответственно, будет обеспечиваться из виртуальной машины Windows напрямую к GPU (видео-адаптеру).

TODO:GRUB

TODO:Для эксперимента все изменения я буду стараться вносить в GRUB, а именно в GRUB_CMDLINE_LINUX_DEFAULT в файле /etc/default/grub, чтобы легко было откатиться. Скажем внести изменения непосредственно в загрузчике (кнопка «e»).

Мне часто придётся добавлять те или иные опции к ядру Linux через редактирование загрузчика GRUB. Поэтому рассмотрю отдельно операции, связанные с ним. А включать они будут, в основном, управление параметрами в ключе GRUB_CMDLINE_LINUX_DEFAULT в файле /etc/default/grub, который отвечает за передачу дополнительных параметров ядру Linux и выглядит как GRUB_CMDLINE_LINUX_DEFAULT=»param1 param2 …».

В отличие от GRUB_CMDLINE_LINUX он не работает в «rescue mode», поэтому любую ошибку легко будет нивелировать просто загрузившись в rescure-режиме.

Чтобы применить внесенные изменения требуется сгенерировать конфигурационный файл и перезагрузить компьютер.

[root@fedora ~]# grub2-mkconfig > /etc/grub2-efi.cfg
[root@fedora ~]# reboot

TODO:IOMMU

TODO: Was ist das (Input–output memory management unit)

[root@fedora ~]# dmesg | grep AMD-Vi
[    1.859881] pci 0000:00:00.2: AMD-Vi: IOMMU performance counters supported
[    1.869155] pci 0000:00:00.2: AMD-Vi: Found IOMMU cap 0x40
[    1.869172] pci 0000:00:00.2: AMD-Vi: Extended features (0x58f77ef22294ade):
[    1.869205] AMD-Vi: Interrupt remapping enabled
[    1.869215] AMD-Vi: Virtual APIC enabled
[    1.869223] AMD-Vi: X2APIC enabled
[    1.869397] AMD-Vi: Lazy IO/TLB flushing enabled

Для увеличения производительности стоит в GRUB поставить IOMMU в режим pass-through добавив параметр iommu=pt. Также для платформы Intel можно принудительно указать intel_iommu=on. Я часто видел совет добавить amd_iommu=on для платформы AMD, но такого значения вообще нет в документации и оно никогда не поддерживалось кодом ядра Linux (функция parse_amd_iommu_options из /linux/drivers/iommu/amd/init.c).

[root@fedora ~]# dmesg | grep -i iommu
[    0.000000] Command line: BOOT_IMAGE=(hd1,gpt2)/vmlinuz-5.12.0-0.rc3.20210319git8b12a62a4e3e.172.fc35.x86_64 root=UUID=94bddd96-e674-4adc-a019-1d0c80e5fada ro rootflags=subvol=root amd_iommu=on
[    0.000000] Kernel command line: BOOT_IMAGE=(hd1,gpt2)/vmlinuz-5.12.0-0.rc3.20210319git8b12a62a4e3e.172.fc35.x86_64 root=UUID=94bddd96-e674-4adc-a019-1d0c80e5fada ro rootflags=subvol=root amd_iommu=on
[    0.306280] **  IOMMU DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL  **
[    0.306319] ** IOMMU data structures, which may compromise security on **
[    0.584430] iommu: Default domain type: Translated
[    0.881935] pci 0000:00:00.2: AMD-Vi: IOMMU performance counters supported
[    0.882136] pci 0000:00:01.0: Adding to iommu group 0
[    0.882184] pci 0000:00:01.1: Adding to iommu group 1
[    0.882231] pci 0000:00:01.2: Adding to iommu group 2
[    0.882289] pci 0000:00:02.0: Adding to iommu group 3
[    0.882348] pci 0000:00:03.0: Adding to iommu group 4
[    0.882392] pci 0000:00:03.1: Adding to iommu group 5
[    0.882450] pci 0000:00:04.0: Adding to iommu group 6
[    0.882511] pci 0000:00:05.0: Adding to iommu group 7
[    0.882573] pci 0000:00:07.0: Adding to iommu group 8
[    0.882617] pci 0000:00:07.1: Adding to iommu group 9
[    0.882676] pci 0000:00:08.0: Adding to iommu group 10
[    0.882720] pci 0000:00:08.1: Adding to iommu group 11
[    0.882794] pci 0000:00:14.0: Adding to iommu group 12

TODO: Использование iommu=pt изменило dmesg: «[ 0.584430] iommu: Default domain type: Translated» на «[ 0.581899] iommu: Default domain type: Passthrough (set via kernel command line)». Надо будет внимательно исследовать эту опцию, SR-IOV.

TODO: Включение ничего не поменяло в «dmesg | grep AMD-Vi» и «dmesg | grep -i iommu» (за исключением того, что туда попали опции ядра).

TODO:Ищем устройства и смотрим группу IOMMU

[root@fedora ~]# lspci -vnn | grep NVIDIA -A2
08:00.0 VGA compatible controller [0300]: NVIDIA Corporation GA104 [GeForce RTX 3070] [10de:2484] (rev a1) (prog-if 00 [VGA controller])
        Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:3903]
        Flags: bus master, fast devsel, latency 0, IRQ 4, IOMMU group 16
--
08:00.1 Audio device [0403]: NVIDIA Corporation GA104 High Definition Audio Controller [10de:228b] (rev a1)
        Subsystem: Micro-Star International Co., Ltd. [MSI] Device [1462:3903]
        Flags: bus master, fast devsel, latency 0, IRQ 11, IOMMU group 16

TODO: Уточняем на всякий случай, что на этой группе (16) не висит множества других устройств.

[root@fedora ~]# find /sys/kernel/iommu_groups/16/devices/
/sys/kernel/iommu_groups/16/devices/
/sys/kernel/iommu_groups/16/devices/0000:08:00.0
/sys/kernel/iommu_groups/16/devices/0000:08:00.1

TODO:VFIO

TODO: Was ist das (Virtual function I/O)

TODO: https://wiki.qemu.org/Features/MultiProcessQEMU (vfio over socket)

Первым делом надо «отобрать» устройство у реальной машины, чтобы отдать виртуальному VFIO и тот уже могу передавать его той или иной виртуальной машине.

TODO: В этом может быть определённая идея SRP/ISP? Отцепить как можно больше специфичных устройств от гипервизора, которыми он не собирается управлять.

[root@fedora ~]# lspci -s 08:00 -v | grep -i kernel
        Kernel driver in use: nouveau
        Kernel modules: nouveau
        Kernel driver in use: snd_hda_intel
        Kernel modules: snd_hda_intel

TODO: После добавления в GRUB параметра module_blacklist=nouveau,snd_hda_intel отцепляются «Kernel driver in use». (TODO: Есть ещё альтернативные варианты — modprobe.blacklist для modprobe и rd.driver.blacklist для Dracut).

TODO: Картинка на физическом экране продолжает выводиться. После отключения видео (video=efifb:off,vesafb:off) она исчезла даже при загрузке, но светодиод наличия сигнала с карты не пропадал. TODO:Там, конечно, много frame-buffer драйверов и наверно достаточно одного работающего варианта.

TODO: Теперь надо передать эти устройства под управление VFIO, добавив в GRUD параметр «modules_load=vfio_pci vfio-pci.ids=10de:2484,10de:228b».

[root@fedora ~]# lsmod | grep -i vfio
vfio_pci               73728  0
vfio_virqfd            16384  1 vfio_pci
vfio_iommu_type1       40960  0
vfio                   40960  2 vfio_iommu_type1,vfio_pci
irqbypass              16384  2 vfio_pci,kvm
[root@fedora ~]# lspci -s 08:00 -v | grep -i kernel
        Kernel driver in use: vfio-pci
        Kernel modules: nouveau
        Kernel driver in use: vfio-pci
        Kernel modules: snd_hda_intel

TODO:QEMU

[root@fedora ~]# qemu-system-x86_64 -device vfio-pci,host=08:00.0 -device vfio-pci,host=08:00.1 -nographic -cdrom win10.iso

[root@fedora ~]# qemu-img create -f qcow2 -o extended_l2=on,compression_type=zstd hda.qcow2 256G

[root@fedora ~]# wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

TODO: Интересно, что после запуска монитор теряет сигнал от карты.

TODO: Экспериментальный вариант

  • Добавляю spice, чтобы подключать к нему virt-viewer (spice://192.168.1.231:5900)
  • Подключаю OMVF UEFI BIOS (dnf install @virtualization)
  • Создаю основной диск qemu-img create -f qcow2 -o extended_l2=on,compression_type=zstd hda.qcow2 256G
  • Подключаю диск с драйверами VirtiIO «wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso»
  • Поставить Windows, подсунув VirtiIO-драйвера
  • Поставить драйвера Nvidia
  • Попробовать майнеры, разгон и т.п.
  • TODO: Драйвера мыши, клавиатуры
  • TODO: Попробовать vga=qxl
  • TODO: Воткнуть какую-нибудь игру
  • TODO:Заменить сетевую карту на e1000? Или что там было.

TODO:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *