Проброс карт 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
Необходимо отключить драйвер 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
Выполняем
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
Создание ВМ
- Переходим в кокпит по адресу https://ip_address:9090
- Переходим в Virtual Machines
- Нажимаем кнопку Create VM
В окне:
- Именуем машину
- В строке "Installation type" выбираем "Local install media", а в "Installation source" указываем нужную директорию, где находится установочный диск с ОС
- В строке "Storage" выбираем "Storage pools" и выбираем пул, в котором должны создаваться диски машин
- В "Size" выбираем емкость диска
- В "Memory" количество ОЗУ
- Снимаем галочку с "Immediately start VM"
- Нажимаем кнопку "Create"
Выбираем созданную машину
- Напротив Firmware выбираем BIOS и в окне меняем на UEFI
- По желанию меняем количество CPU, ОЗУ и тд.
- Нажимаем кнопку "Install" и машина будет создана
- Устанавливаем ОС
- После установки выключаем машину
Добавление карты в виртуальную машину
Сначала нам нужно узнать адрес 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.
В выводе видно, что компонентов каждой карты - четыре:
- Сама карта (06:00.0)
- Аудио (06:00.1)
- USB 3.1 (06:00.2)
- 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.