Проброс видеокарты в виртуальную машину
Проброс видеокарты в виртуальную машину.
В целом, я оставлю тут все, что я использовал в течение уже нескольких месяцев для своего компа, чтобы те, кто заинтересуются использованием видеокарты в гостевой системе могли разобраться что к чему =)
Для того, чтобы использовать видеокарту внутри xen или kvm нужны следующие вещи:
- Видеокарта с поддержкой проброса.
- Любая видеокарта для хоста. Конечно можно обойтись и одной, но тогда теряется весь смысл затеи.
- Материнская плата с блоком управления памятью ввода/вывода(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, Отжать устройство обратно из виртуалки, Ну по фиксы по мелочи.