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

Материал из MediaWiki
Перейти к навигации Перейти к поиску

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

В целом, я оставлю тут все, что я использовал в течение уже нескольких месяцев для своего компа, чтобы те, кто заинтересуются использованием видеокарты в гостевой системе могли разобраться что к чему =)

Для того, чтобы использовать видеокарту внутри xen или kvm нужны следующие вещи:


  1. Видеокарта с поддержкой проброса.


  1. Любая видеокарта для хоста. Конечно можно обойтись и одной, но тогда теряется весь смысл затеи.
  1. Материнская плата с блоком управления памятью ввода/вывода(IOMMU)


  • в случае процессоров/чипсетов от AMD эта технология называется AMD-Vi и важен только чипсет. на данный момент это 890FX, и по идее вся серия 990 чипсетов. процессор может быть любым, но должен иметь аппаратную виртуализацию(AMD-V).


  • В случае процессоров/чипсетов от Intel эта технология называется VT-d и важна поддержка как в чипсете, так и в процессоре.


  • В не зависимости от выбранной платформы в биосе материнской платы должны быть реализованы IVRS/DMAR таблицы. Это основная проблема, перед выбором материнской платы, лучше погуглить насчет успехов использования iommu на данной плате.


Железо, которое было использовано у меня:


  • Материнская плата: Gigabyte GA-990FXA-D3


  • Видеокарта: Msi Twin Razr III R7870


  • Процессор: AMD Phenom II x6 1090T


  • Ядро: 3.4
  • xen 4.1.2
  • kvm 1.0.1

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


Эти действия не зависят от выбранной системы виртуализации, мы подготовим видеокарту к пробросу и применим некоторые костыли для обхода багов.


Сначала нужно перезагрузится в биос и включить там IOMMU. Так же надо установить ту видеокарту, которая будет основной для хоста в качестве основной для хоста +) т.е. чтобы сам POST биоса проходил на той видеокарте, которая НЕ планируется для проброса в гостевую систему.


Прежде чем продолжить, надо проверить что IOMMU вообще работает.

Можно проверить так:

dmesg | grep -iE "(iommu|vt-d)" -a1

А если вы уже загрузились в Xen, это можно сделать примерно так:

 # xm dmesg | grep -i iommu -a2
(XEN) Detected 3547.487 MHz processor.
(XEN) Initing memory sharing.
(XEN) AMD-Vi: IOMMU 0 Enabled.
(XEN) I/O virtualisation enabled
(XEN)  - Dom0 mode: Relaxed

Для платформы Intel там будут сообщения о VT-d, вместо AMD-Vi.

Затем, для уменьшения потенциального количества глюков добавить модуль ядра radeon и/или fglrx в blacklist, для того, чтобы не загружать драйвер для видеокарты на хосте, т.к. мы все равно ее будем отправлять в гостевую систему, а динамическое отключение драйвера может добавить несколько неприятностей. Нужно прописать в файле /etc/modprobe.d/blacklist.conf :

  blacklist fglrx
  blacklist radeon
  • есть небольшая проблема, если вторая видеокарта в вашей системе - тоже AMD, то при таком раскладе драйвер для нее не загрузится. Тут в принципе три варианта: либо не прописывать radeon/fglrx в blacklist, либо загружать эти модули уже после подключения нужной видеокарты к pci-stub, либо написать правило для udev. Так что, в случае если у вас обе видеокарты AMD, то добавляйте модули в blacklist если возникнут проблемы.

Теперь нужно подготовить видеокарту к пробросу, отключив ее от драйвера на хосте и подключив к специальному ничего-не-делающему драйверу pci-stub. Если присутствуют hdmi/displayport видеовыходы, то на видеокарте есть встроенная звуковая карта, ее так же нужно подключить к pci-stub. Проверить можно через lspci:

  01:00.0 VGA compatible controller: ATI Technologies Inc PITCAIRN [Radeon HD 7800]
  01:00.1 Audio device: ATI Technologies Inc Device aab0

Как мы видим, 01:00.0 - видеочип, а 01:00.1 - звуковой чип. Затем, нам нужны vendor id и device id. посмотреть можно запустив lspci с ключем -n

  01:00.0 0300: 1002:6818
  01:00.1 0403: 1002:aab0

Теперь подключаем железки к pci-stub

  #говорим pci-stub, что он может работать с нашей видеокартой.
  echo "1002 6818" > /sys/bus/pci/drivers/pci-stub/new_id 
#следующие строчки отключат видеокарту от текущего драйвера и подключат ее к pci-stub. #Если вы уже прописали в blacklist модули radeon/fglrx, то соответственно не нужно отключать/подключать устройство, #поэтому в них нет необходимости. Ядро само увидит, что pci-stub может работать с 1002 6818 и подключит его.
echo "0000:01:00.0" > /sys/bus/pci/devices/0000\:01\:00.0/driver/unbind echo "0000:01:00.0" > /sys/bus/pci/drivers/pci-stub/bind
  #звуковая карта
  echo "1002 aab0" > /sys/bus/pci/drivers/pci-stub/new_id 
  echo "0000:01:00.1" > /sys/bus/pci/devices/0000\:01\:00.1/driver/unbind 
  echo "0000:01:00.1" > /sys/bus/pci/drivers/pci-stub/bind

Разумеется лучше это сохранить в виде скрипта, подставив нужные значения.

Можно проверить что все правильно, посмотрев вывод lspci -s 01:00.0 -k

01:00.0 VGA compatible controller: Advanced Micro Devices [AMD] nee ATI PITCAIRN [Radeon HD 7800]
       Subsystem: Micro-Star International Co., Ltd. Device 2740
       Kernel driver in use: pci-stub
       Kernel modules: radeon

В данном случае мы видим, что в данный момент используется драйвер pci-stub, значит все нормально. Разумеется стоит проверить, что он используется и для звуковой карты.



KVM.

Для начала нужно просто установить kvm и по желанию libvirt c virt-manager, для удобного управления через графический интерфейс. Это можно сделать используя пакетный менеджер вашего дистрибутива.

Поскольку AMD IOMMU(или драйвер в ядре) пока не поддерживает Interrupt Remapping, то нужно передать модулю kvm опцию allow_unsafe_assigned_interrupts=1. Можно или вручную загрузить модуль с помощью modprobe, или создать файл в /etc/modprobe.d/kvm.conf с содержанием и перезагрузить моудль.

  options kvm allow_unsafe_assigned_interrupts=1


Теперь запускаем virt-manager и устанавливаем операционную систему в виртуальную машину как обычно. Если это Windows, то разумеется неплохо бы скачать virtio драйвера и установить их. После того как ОС установленна, можно выключить виртуальную машину и в virt-manager'e добавить нужные PCI устройства, в моем случае это 0000:01:00.0 и 0000:01:00.1. Теперь запускаем гостя снова. Для Windows нужно скачать драйвера с сайта AMD и установить их. При установке драйверов Windows может легко уйти в BSOD, так что если не получилось с первого раза, стоит попробовать запустить гостя вновь и попробовать еще. После установки, разумеется нужно будет перезапустить виртуальную машину.

  • На данный момент, kvm при повторном запуске гостя с проброшенной видеокартой вешает всю систему, поэтому, если вы выключили виртуалку, то придется так же перезагружать весь компьютер.

Теперь, после старта консоль виртуальной машины отключится после загрузки драйвера видеокарты, в случае Windows 7 там остается картинка "Starting Windows", но само изображение должно уже выводится на проброшенную видеокарту. Хотя на коносль и не будет выводится изображение, тем не менее она будет передавать данные от устройств ввода и можно будет управлять гостем с клавиатуры и мыши как обычную виртуалку.



XEN

Сначала, разумеется, нужно поставить ксен из репозитория дистрибутива.

В отличие от kvm, здесь не нужно никаких дополнительных костылей.

Пример конфигурационного файла, который использовался у меня:

kernel = "hvmloader"
builder='hvm'
memory = 3096
name = "win7_x64"
vcpus=3
pae=1
acpi=1
apic=1
vif = [ 'bridge=xenbr0' ]
disk = [ 
'phy:/dev/md0,hda,w',
'file:/var/lib/libvirt/images/win7_x64_n_u.iso,hdb:cdrom,r'
]
xen_platform_pci=1
viridian=1
on_poweroff = 'destroy'
on_reboot   = 'restart'
on_crash    = 'destroy'
device_model = 'qemu-dm'
boot='c'
sdl=0
vnc=1
vncconsole=0
stdvga=1
serial='pty'
pci = ['01:00.0', '01:00.1']
gfx_passthru=0
usbdevice="tablet"      

В данном случае, в качестве диска для виртуальной машины использовался mdraid массив /dev/md0, если вы хотите использовать образ в виде файла, то в параметре disk, вместо phy:/dev/md0 нужно написать tap:aio:/path/to/file или просто file:/path/to/file

параметр boot говорит xen'у с чего грузиться, "c" - грузиться с диска, "d" - с cdrom'а, так что вначале вам придется поставить там d, чтобы установить ОС.

После того, как поставите нужные параметры, конфиг надо куда нибудь сохранить.

Собственно старт виртуальной машины:

xm create /path/to/vmconfig

А для ее управления можно использовать vncviewer, запущенный от обычного пользователя

vncviewer :0

Как и в случае с kvm, если вы ставите Windows, то нужно скачать паравиртуальные драйвера для Xen (GPLPV) и драйвер Catalyst для проброшенной видеокарты.

  • так же как и с kvm, установка драйверов запросто может отправить Windows в BSOD, судя по моему опыту, драйвера устанавливаются полностью только раза с третьего.

После того как все установленно, нужно, разумеется перезагрузить гостя. Поведение будет такое же как и в случае с kvm, т.е. на vnc консоли замрет изображение, но события от устройств ввода она будет передавать гостю. Изображение с виртуальной машины должно передаваться на проброшенную видеокарту.

Ох, это было чертовски интересно ! TODO: Проблема со звуком, Устройства ввода, FLR, Отжать устройство обратно из виртуалки, Ну по фиксы по мелочи.