WWW.LUSHNIKOV.NET

Intel GVT-G и libvirt. Как быстро настроить и попробовать.

GVT-G – это технология, позволяющая виртуализировать встроенную в процессоры Intel Core видеокарту. Можно создать несколько таких виртуальных видеокарт и раздать виртуальным машинам. Каждая виртуальная машина будет иметь доступ к настоящему аппаратному 3d-ускорителю. Пока работает только под KVM и XEN. Есть возможность выводить картинку с этой виртуальной видеокарты на реальную. Но у нас же сервер. Нам не для игр. Поэтому ограничимся доступом по Remote Desktop.

1. Берем комп с процессором Intel Core поколения 5 или новее. В BIOS выставляем максимально возможный размер видеопамяти.

2. Ставим ubuntu 18.04. Мой любимый debian не подойдет, поскольку у него в ядре выключен CONFIG_DRM_I915_GVT_KVMGT. Можно пересобрать ядро самостоятельно, но нам же надо быстро.

3. Обновляем

# apt update
# apt dist-upgrade -y

4. Ставим libvirt

# apt install libvirt-daemon-system

5. Добавляем в /etc/default/grub:

GRUB_CMDLINE_LINUX="i915.enable_gvt=1 kvm.ignore_msrs=1 intel_iommu=on i915.enable_guc=0"

Не забываем обновить конфиг:

# update-grub

Перезагружаемся и после перезагрузки убеждаемся, что у нас получилось:

# ls /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
i915-GVTg_V5_2  i915-GVTg_V5_4  i915-GVTg_V5_8

В каждом из этих каталогов есть файл available_instances, в котором указано, сколько виртуальных видоекарт можно создать одновременно. В файле description написано, какие параметры будут у этих видеокарт.

6. Придумываем UUID и создаем виртуальную видеокарту.

# echo "df7aee77-abed-4c3c-b6b0-3e38db57f13d" > "/sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_4/create"

Эту процедуру придется повторять руками после каждой загрузки или прибить гвоздями куда-нибудь в /etc/rc.local.

7. Создаем виртуалку примерно такого вида:

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
  <name>win1</name>
  <uuid>d68571d2-3dd1-4aa2-a780-36160afff657</uuid>
  <memory unit='KiB'>3145728</memory>
  <currentMemory unit='KiB'>3145728</currentMemory>
  <vcpu placement='static'>2</vcpu>
  <os>
    <type arch='x86_64' machine='pc-q35-2.11'>hvm</type>
    <bootmenu enable='yes' timeout='3000'/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state='on'/>
      <vapic state='on'/>
      <spinlocks state='on' retries='8191'/>
      <vpindex state='on'/>
      <synic state='on'/>
      <stimer state='on'/>
    </hyperv>
    <vmport state='off'/>
    <ioapic driver='kvm'/>
  </features>
  <cpu mode='host-passthrough' check='partial'>
    <topology sockets='1' cores='2' threads='1'/>
    <cache mode='passthrough'/>
  </cpu>
  <clock offset='localtime'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
    <timer name='hypervclock' present='yes'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>restart</on_crash>
  <devices>
    <emulator>/usr/bin/kvm</emulator>
    <disk type='block' device='disk'>
      <driver name='qemu' type='raw' discard='unmap'/>
      <source dev='/virt/raw/win1/raw'/>
      <target dev='sda' bus='scsi'/>
      <boot order='1'/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/virt/iso/win10-64.iso'/>
      <target dev='sdb' bus='sata'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='1'/>
    </disk>
    <controller type='scsi' index='0' model='lsisas1068'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </controller>
    <controller type='usb' index='0' model='qemu-xhci'>
      <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
    </controller>
    <controller type='sata' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pcie-root'/>
    <controller type='pci' index='1' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='1' port='0x8'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/>
    </controller>
    <controller type='pci' index='2' model='pcie-root-port'>
      <model name='pcie-root-port'/>
      <target chassis='2' port='0x9'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
      <mac address='54:52:00:e7:2f:2a'/>
      <source bridge='br-int'/>
      <model type='e1000'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='tablet' bus='usb'>
      <address type='usb' bus='0' port='1'/>
    </input>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='-1' autoport='yes'>
      <listen type='address'/>
    </graphics>
    <memballoon model='none'/>
  </devices>
</domain>

Ключевое тут – чипсет pc-q35-2.11.

8. Запускаем виртуалку, подключаемся по VNC и ставим Windows 10. Настраиваем сеть, разрешаем Remote Desktop. Подключаемся по Remote Desktop, скачиваем драйвера для видеокарты. Выключаем виртуалку.

9. Добавляем новое устройство vfio-pci c uuid нашей виртуальной видеокарты.

    ...
    </graphics>
    <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci'>
      <source>
        <address uuid='df7aee77-abed-4c3c-b6b0-3e38db57f13d'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/>
    </hostdev>
    <memballoon model='none'/>
    ...

10. Загружаем виртуалку, подключаемся по Remote Desktop и устанавливаем драйвер для видеокарты. На этом пункте уже можно остановиться, 3D на виртуальной машине уже есть. Но…

11. …поскольку примерно с п.9 подключаться по VNC бессмысленно (всегда будет только черный экран), можно убрать из xml вот этот блок:

  <graphics type='vnc' port='-1' autoport='yes'>
    <listen type='address'/>
  </graphics>

и добавить дополнительный аргумент в командную строку qemu:

    ...
    </devices>
  <qemu:commandline>
    <qemu:arg value='-nographic'/>
  </qemu:commandline>
</domain>

Вот теперь точно всё.

Leave a Reply