Проброс карт GeForce на KVM CentOS 8 в Windows 10

Если у вас что-то не получается пишите в комментариях. Отвечаю в течение дня.



Всем привет.

При пробросе карт GeForce в Windows 10 столкнулись с общеизвестной ошибкой Error 43.

В этой статье расскажу как на CentOS 8 с помощью KVM пробросить несколько видеокарт GeForce в гостевую ОС. На своём опыте развернул более десятка машин с GeForce GTX 1080Ti, RTX 2080Ti, RTX 3090. поэтому процесс полностью отлажен.

В рамках этой статьи будут проброшены четыре видеокарты RTX 2080Ti на четыре виртуальные машины.



Подготовка


Установка KVM:

dnf module install virt && dnf install virt-install virt-viewer


Для удобства работы с KVM я использую Cockpit (https://cockpit-project.org/). Поэтому установим и его:

dnf config-manager --add-repo https://copr.fedorainfracloud.org/coprs/g/cockpit/cockpit-preview/repo/epel-8/group_cockpit-cockpit-preview-epel-8.repo && dnf -y install cockpit*


Чтобы получить доступ в веб-панель Cockpit добавьте правила в FirewallD

firewall-cmd --add-service=https --permanent && firewall-cmd --reload



Далее включим поддержку IOMMU. Для этого в /etc/default/grub добавим строку

GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/cl-swap rd.lvm.lv=cl/root rd.lvm.lv=cl/swap rhgb quiet intel_iommu=on"


Сохраняем, выполняем

grub2-mkconfig -o /boot/grub2/grub.cfg
Обратите внимание, что в BIOS обязательно нужно включить поддержку IOMMU!


Необходимо отключить драйвер nouveau, иначе могут быть проблемы с привязкой vfio-pci к видеокартам. В любом случае не забивайте голову этими терминами, а просто выполните следующие команды и перезагрузите сервер

grubby --update-kernel=ALL --args="rd.driver.blacklist=nouveau nouveau.modeset=0"
mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
dracut /boot/initramfs-$(uname -r).img $(uname -r)
echo 'blacklist nouveau' > /etc/modprobe.d/nouveau-blacklist.conf

Перезагружать сервер пока не нужно.


Подготовка видеокарт к пробросу

Выведите список карт командой lspci -nn | grep -i nvidia. В моём случае два карты RTX 2080 Ti

lspci -nn | grep -i nvidia
06:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1)
06:00.1 Audio device [0403]: NVIDIA Corporation TU102 High Definition Audio Controller [10de:10f7] (rev a1)
06:00.2 USB controller [0c03]: NVIDIA Corporation TU102 USB 3.1 Host Controller [10de:1ad6] (rev a1)
06:00.3 Serial bus controller [0c80]: NVIDIA Corporation TU102 USB Type-C UCSI Controller [10de:1ad7] (rev a1)
82:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1)
82:00.1 Audio device [0403]: NVIDIA Corporation TU102 High Definition Audio Controller [10de:10f7] (rev a1)
82:00.2 USB controller [0c03]: NVIDIA Corporation TU102 USB 3.1 Host Controller [10de:1ad6] (rev a1)
82:00.3 Serial bus controller [0c80]: NVIDIA Corporation TU102 USB Type-C UCSI Controller [10de:1ad7] (rev a1)


Создаём файл vi /etc/modprobe.d/vfio.conf и добавляем в него

options vfio-pci ids=10de:1e07, 10de:10f7, 10de:1ad6, 10de:1ad7
vid:pid карт обязательно прописывать в одной строке vfio-pci ids= иначе есть вероятность, что часть карт не подхватят vfio-pci.

Выполняем

echo 'vfio-pci' > /etc/modules-load.d/vfio-pci.conf


Теперь перезагрузите сервер.


Проверка, что карты встали в режим vfio

[root@localhost ~]# lspci -vs 81:00.0
81:00.0 VGA compatible controller: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] (rev a1) (prog-if 00 [VGA
controller])
Subsystem: ZOTAC International (MCO) Ltd. Device 1503
Physical Slot: 6
Flags: bus master, fast devsel, latency 0, IRQ 24, NUMA node 1
Memory at fa000000 (32-bit, non-prefetchable) 
Memory at e0000000 (64-bit, prefetchable) 
Memory at f0000000 (64-bit, prefetchable) 
I/O ports at f000 
Expansion ROM at fb000000 [virtual] [disabled] 
Capabilities: [60] Power Management version 3
Capabilities: [68] MSI: Enable- Count=1/1 Maskable- 64bit+
Capabilities: [78] Express Legacy Endpoint, MSI 00
Capabilities: [100] Virtual Channel
Capabilities: [258] L1 PM Substates
Capabilities: [128] Power Budgeting <?>
Capabilities: [420] Advanced Error Reporting
Capabilities: [600] Vendor Specific Information: ID=0001 Rev=1 Len=024 <?>
Capabilities: [900] Secondary PCI Express
Capabilities: [bb0] Resizable BAR <?>
Kernel driver in use: vfio-pci
Kernel modules: nouveau

Жирным и красным выделено, как должно выглядеть. Если карта не использует vfio-pci, то будет

Kernel driver in use: nouveau
Kernel modules: nouveau

Создание ВМ

  1. Переходим в кокпит по адресу https://ip_address:9090
  2. Переходим в Virtual Machines
  3. Нажимаем кнопку Create VM



В окне:

  1. Именуем машину
  2. В строке "Installation type" выбираем "Local install media", а в "Installation source" указываем нужную директорию, где находится установочный диск с ОС
  3. В строке "Storage" выбираем "Storage pools" и выбираем пул, в котором должны создаваться диски машин
  4. В "Size" выбираем емкость диска
  5. В "Memory" количество ОЗУ
  6. Снимаем галочку с "Immediately start VM"
  7. Нажимаем кнопку "Create"


Выбираем созданную машину

  1. Напротив Firmware выбираем BIOS и в окне меняем на UEFI
  2. По желанию меняем количество CPU, ОЗУ и тд.
  3.  Нажимаем кнопку "Install" и машина будет создана
  4.  Устанавливаем ОС
  5.  После установки выключаем машину


Добавление карты в виртуальную машину


Сначала нам нужно узнать адрес GPU карты, которую мы хотим добавить в виртуальную машину.

В консоли выполняем

[root@kvm-node-gpu5 yum.repos.d]# lspci -nn | grep -i nvidia
06:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1)
06:00.1 Audio device [0403]: NVIDIA Corporation TU102 High Definition Audio Controller [10de:10f7] (rev a1)
06:00.2 USB controller [0c03]: NVIDIA Corporation TU102 USB 3.1 Host Controller [10de:1ad6] (rev a1)
06:00.3 Serial bus controller [0c80]: NVIDIA Corporation TU102 USB Type-C UCSI Controller [10de:1ad7] (rev a1)
82:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1)
82:00.1 Audio device [0403]: NVIDIA Corporation TU102 High Definition Audio Controller [10de:10f7] (rev a1)
82:00.2 USB controller [0c03]: NVIDIA Corporation TU102 USB 3.1 Host Controller [10de:1ad6] (rev a1)
82:00.3 Serial bus controller [0c80]: NVIDIA Corporation TU102 USB Type-C UCSI Controller [10de:1ad7] (rev a1)


Как видим у меня две карты с адресами 06 и 82. Добавлять мы будем карту с адресом 06.
В выводе видно, что компонентов каждой карты - четыре:

  1. Сама карта (06:00.0)
  2. Аудио (06:00.1)
  3. USB 3.1 (06:00.2)
  4. USB Type-C (06:00.3)

Где:
06 - номер шины
00 - номер слота
0  - номер функции

Чтобы присвоить карту виртуальной машине, необходимо всегда использовать этот шаблон для карт и вместо цветных цифр добавлять свои. Этот шаблон добавляется в XML машины. Как это сделать будет написано ниже.

<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x0'/>
</source>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x1'/>
</source>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x2'/>
</source>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x3'/>
</source>
</hostdev>



Редактирование XML машины

1. В консоли хоста выполняем virsh edit --domain имя_машины
2. Внутри тегов <hyperv></hyperv> добавляем: <vendor_id state='on' value='111111111'/>
3. Внутри тегов <features></features> добавляем:

<kvm>
<hidden state='on'/>
</kvm>


Пролистываем в самый низ и перед

  </devices>
</domain>

вставляем

<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x0'/>
</source>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x1'/>
</source>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x2'/>
</source>
</hostdev>
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0' bus='0x06' slot='0x0' function='0x3'/>
</source>
</hostdev>


Сохраняем XML, запускаем машину и устанавливаем драйвера NVidia.

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