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

e3a1f3f31ad5b107be1330ba48b7e8c6

1. Вступление

Две разные системы (win + linux) на одной аппаратной базе — реальность. В этом нет ничего нового или инновационного (на данный момент времени), но если требуется максимальная производительность гостевой системы, то не обойтись без проброса реальных устройств в виртуальную машину. Проброс сетевых карт, usb-контроллеров (etc) экстраординарных особенностей не несёт, а вот попытка «шаринга» ресурсов видеокарты и процессора вполне может принести некоторое количество проблем.

Итак, а для чего, собственного говоря, городить системы с полнофункциональным использованием ресурсов GPU и CPU? Самый простой и очевидный ответ — игры (широко известный факт — если не большинство, то очень многие, написаны под ОС Windows). Другой вариант — полноценное рабочее место с возможностью запуска требовательных приложений (например, CAD-софта), быстрым бэкапом (скопировать файл ВМ куда проще, чем создавать полную копию HDD/SSD) и опцией полного контроля сетевого трафика гостевой системы.

2. Аппаратная часть

Процессор: Intel® Core i5–9400F CPU @ 2.90GHz

Материнская плата: ASRock Z390 Phantom Gaming 4S

Видеокарта 0 (для проброса в ВМ): Lexa PRO [Radeon 540/540X/550/550X / RX 540X/550/550X]

Видеокарта 1 (для хост-системы): Park [Mobility Radeon HD 5430]

USB-контроллер (для проброса в ВМ и последующего подключения периферийных устройств, например, клавиатуры): VIA Technologies, Inc. VL805 USB 3.0 Host Controller

3. Настройки ОС

В качестве хост-системы выбрана ОС AlmaLinux 8 (вариант установки«Server with GUI»). Долгое время пользовался CentOS 7/8, поэтому, думаю, выбор тут очевиден.

Первое, что необходимо сделать, — это ограничить использование видеокарты, предназначенной для использования в ВМ, хост-системой. Для этого применяем ряд команд и настроек:
1) с помощью команды »lspci -nn | grep RX» получаем уникальные идентификаторы видеокарты. Т. к. видеокарта RX-серии, то, соответственно, ищем в выводе lspci(утилита устанавливается посредством команды »dnf install pciutils») по этим двум символам. Вывод получим примерно такой (выделенные подстроки — это и есть искомые идентификаторы устройств) —

«02:00.0 VGA compatible controller [0300]: Advanced Micro Devices, Inc. [AMD/ATI] Lexa PRO [Radeon 540/540X/550/550X / RX 540X/550/550X] [1002:699f] (rev c7)

02:00.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] Baffin HDMI/DP Audio [Radeon RX 550 640SP / RX 560/560X] [1002:aae0]», где 1002:699f — идентификатор VGA-контроллера, а 1002: aae0 — встроенной аудиокарты. Также запоминаем идентификаторы »02:00.0» и »02:00.1»;

2) добавив к команде »lspci -nn» ключ »k» (»lspci -nnk») находим в выводе устройство »1002:699f» и запоминаем значение «Kernel driver in use». В моём случае — это »amdgpu»;

3) в файле »/etc/default/grub» находим строку, начинающуюся с »GRUB_CMDLINE_LINUX», и добавляем после »quiet» значения »intel_iommu=on iommu=on rd.driver.pre=pci-stub pci-stub.ids=1002:67ff, 1002: aae0», где »intel_iommu / iommu» — параметры, отвечающие за поддержку технологии IOMMU (технология взаимодействия виртуальных машин с реальным оборудованием),»rd.driver.pre=pci-stub» — указание на принудительную первоочередную загрузку фиктивного драйвера pci-sub,»pci-stub.ids» — перечисление устройств, для которых при загрузке ядра необходимо использовать фиктивный драйвер (т.е. происходит изоляция устройств для дальнейшего использования в виртуальных машинах). Если на хост-машине используется CPU от AMD, то «intel_iommu» меняем на »amd_iommu»;

4) в файл »/etc/modprobe.d/local.conf» добавляем строки »blacklist amdgpu» и »options pci-stub ids=1002:67ff,1002:aae0», где »blacklist amdgpu» — явное указание на запрет использования драйвера AMD для графических устройств, а »options pci-stub ids=1002:67ff,1002:aae0» — явное указание на использование фиктивного драйвера для соответствующих идентификаторов устройств;

5) выполняем команду »grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg» (т.е. пересоздаём конфигурационный файл загрузчика GRUB). Если речь не про EFI-загрузку, то команда выглядит так — »grub2-mkconfig -o /boot/grub2/grub.cfg»;

6) выполняем команду »dracut --regenerate-all --force» для пересоздания образа initramfs (initial RAM disk image, загружаемый в оперативную память файл с образом файловой системы), используемого при загрузке Linux в качестве первоначальной корневой файловой системы;

7) перезагружаем хост виртуализации.

Смысл этих настроек в том, чтобы ограничить использование определённых устройств при загрузке. Например, до прописания параметров в выводе команды «lspci -v» для VGA-контроллера будет присутствовать подстрока »Kernel driver in use: amdgpu», а после перезагрузки — »Kernel driver in use: pci-stub». При старте же ВМ с Windows (и после проброса устройств) — »Kernel driver in use: vfio-pci» (в чём можно убедиться после запуска созданной ВМ). Важный момент — используемая для хост-системы видеокарта должна использовать драйвера, отличные от используемых для пробрасываемой видеокарты, например, в моём случае используется «Radeon HD 5430», драйвер для которой — это «radeon» (в выводе »lspci -v» — »Kernel driver in use: radeon»).

4. Установка софта для виртуализации

1) »dnf install epel-release».

2) »dnf install qemu-kvm qemu-img libvirt virt-install libvirt-client virt-viewer virt-manager seabios numactl perf cockpit cockpit-machines xauth virt-top libguestfs-tools».

3) »dnf install @virt».

4) Optional.»dnf install perl» (Perl — one love).

5. Настройки ВМ QEMU-KVM via virt-manager

Предварительно скачиваем iso-образ Windows 10 и драйвера Virtio от RedHat (тоже в виде iso-образа).

При первоначальной установке всегда ставим галочку »Customize configuration before install».

1) Указываем iso-образ устанавливаемой операционной системы (например, Windows 10). Также добавляем дополнительное устройство вида «CD-ROM» и монтируем в доп. устройство iso-образ с драйверами Virtio.

2) Для виртуального HDD (куда планируется установка ОС) выставляем:»Bus type = Virtio». Тип виртуального диска — qcow2 или raw.

3) Для более эффективной работы размещаем основной виртуальный диск для ВМ на SSD.

4) Модель сетевой карты — virtio.

5) Overview: chipset = »Q35», firmware = »UEFI x86_64: /usr/share/OVMF/OVMF_CODE.secboot.fd».

6) OS Information: Operation System = «Microsoft Windows 10».

7) CPU (соответствующие блоки в XML должны выглядеть именно так, если речь про аналогичную аппаратную конфигурацию):

Развернуть

8) Удаляем из конфигурации ВМ: «Tablet», «Display VNC», «Channel qemu-ga», «Video VGA».

9) Добавляем (через »Add Hardware → PCI Host Device») нужные устройства (VGA-контроллер, встроенный в видеокарту аудиконтроллер и отдельный USB-контроллер), ориентируясь на выделенный идентификатор »02:00.0 VGA compatible controller: Advanced Micro Devices, Inc. [AMD/ATI] Lexa PRO [Radeon 540/540X/550/550X / RX 540X/550/550X] (rev c7)» (пример вывода «lspci»).

10) Подключаем монитор к проброшенной видеокарте, а «мышь» с клавиатурой — к проброшенному USB-контроллеру.

11) Запускаем процесс установки (»Begin installation»). В процессе установки указываем инсталлятору на образ Virtio в качестве драйвер-источника для HDD.

12) После установки заходим в диспетчер задач и для неизвестных устройств указываем в качестве драйвер-источника диск с Virtio. Также инсталлируем драйвера видеокарты.

Если всё сделано правильно, то в диспетчере задач Windows вы увидите реальную видеокарту и 4 ядра CPU с расшаренными ресурсами процессора (Кэш L1 + L2 + L3).

© Habrahabr.ru