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

Бывает такой момент, что без Windows никак не обойтись, и даже wine не помогает, и тут к нам на помощь приходят виртуальный машины. Под Linux их хватает, VirtualBox, VMWare, XEN(гипервизор, но все же), qemu с kvm. Иногда нам необходима полноценная 3D графика, на виртуалке, и тут нам поможет проброс(passthrough) видеокарты в виртуалку.


В интернете полно статей, что да как делать, но интернет у нас большой и от еще одной статейки он не лопнет.
Для начала нам необходимо, что бы в компьютере было 2 видеокарты, например встроенная и дискретная. У меня основная видеокарта Geforce GXT 550ti, а прокидывал я GTX 650ti и Ati HD4850 и все успешно работало.
Существует 2 вида проброса, использовать OVMF, данный проект позволяет использовать UEFI в виртуалке, но и видеокарта должна быть не простая, а аж с двумя биосами, это можно выяснить следующим образом [ http://vfio.blogspot.ru/2014/08/does-my-graphics-card-rom-support-efi.html ].
Скачиваем, компилируем
git clone https://github.com/awilliam/rom-parser
cd rom-parser
make
Получаем BIOS видекарты
cd /sys/bus/pci/devices/0000:01:00.0/
echo 1 > rom
cat rom > image.rom
echo 0 > rom
0000:01:00.0 — надо изменить на код вашего девайса.

Проверяем BIOS ./rom-parser image.rom
Если вы видите подобное PCIR: type 3(EFI ROM), то ваша видеокарта поддерживает OVMF.
Valid ROM signature found @0h, PCIR offset 190h
 PCIR: type 0, vendor: 10de, device: 1280, class: 030000
 PCIR: revision 0, vendor revision: 1
Valid ROM signature found @f400h, PCIR offset 1ch
 PCIR: type 3, vendor: 10de, device: 1280, class: 030000
 PCIR: revision 3, vendor revision: 0
  EFI: Signature Valid
 Last image
Ваш конфиг виртуалки будет немножко отличаться.

Я поэкспериментировал с ядрами, ни к чему интересному и хорошему это не привело, писали [https://bbs.archlinux.org/viewtopic.php?id=203240] что в ядре 4.2.2-1 поломали проброс, но как оказалось все прекрасно работает.
Но если же у вас все же есть желание, то устанавливайте из AUR'a:
1. [ https://aur.archlinux.org/packages/linux-vfio/ ] — на данный момент типа багнутое ядро, где сломан проброс, но используются полезные патчи для видюх интел и еще что-то там
2. [ https://aur.archlinux.org/packages/linux-vfio-lts/ ] — рабочее ядро, с теми же патчами, что и выше.
Как пользоваться makepkg, разберетесь сами.

1. Устанавливаем необходимый софт pacman -S qemu libvirt synergy
2. Нужно подкорректировать загрузку ядра, что бы не подцеплялась, наша видеокарта которую мы будем прокидывать. Нужно узнать id вендора и кода нашей видеокарты. Для этого выводим lspci
02:00.0 VGA compatible controller: NVIDIA Corporation GK106 [GeForce GTX 650 Ti] (rev a1)
02:00.1 Audio device: NVIDIA Corporation GK106 HDMI Audio Controller (rev a1)
Находим там код видеокарты, запоминаем его, и вводим уже lspci -n
02:00.0 0300: 10de:11c6 (rev a1)
02:00.1 0403: 10de:0e0b (rev a1)
Теперь правим параметры загрузки grub, для этого открываем /etc/default/grub
и добавляем параметр в GRUB_CMDLINE_LINUX_DEFAULT vfio-pci.ids=10de:11c6,10de:0e0b
У меня следующего вида
GRUB_CMDLINE_LINUX_DEFAULT="noresume iommu=noaperture vfio-pci.ids=10de:11c6,10de:0e0b"
Применяем параметры grub-mkconfig -o /boot/grub/grub.cfg, после перезагрузки, должно быть нечто подобное dmesg | grep vfio_pci:
[    0.881226] vfio_pci: add [10de:11c6[ffff:ffff]] class 0x000000/00000000
[    0.881257] vfio-pci 0000:02:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=io+mem:owns=none
[    0.893270] vfio_pci: add [10de:0e0b[ffff:ffff]] class 0x000000/00000000
[    2.496137] vfio-pci 0000:02:00.0: vgaarb: changed VGA decodes: olddecodes=io+mem,decodes=io+mem:owns=none
Подкорректируем /etc/mkinitcpio.conf:
...
MODULES="vfio vfio_iommu_type1 vfio_pci vfio_virqfd"
...
Применим mkinitcpio -p linux(linux изменить на имя вашего ядра)

3. Настраиваем и создаем виртуалку.
Подправим конфиг qemu
/etc/libvirt/qemu.conf:
...
user = "root"
group = "root"
clear_emulator_capabilities = 0
...
cgroup_device_acl = [
    "/dev/null", "/dev/full", "/dev/zero",
    "/dev/random", "/dev/urandom",
    "/dev/ptmx", "/dev/kvm", "/dev/kqemu",
    "/dev/rtc","/dev/hpet", "/dev/vfio/vfio",
    "/dev/vfio/1"
]
...
В принципе действия для того что бы использовать ovmf те же, так вот если вам повезло и у вас видеокарта поддерживает EFI, то следующий конфиг для вас:
pacman -S ovmf
qemu-system-x86_64 -enable-kvm -m 1024 -cpu host,kvm=off  \
-smp 4,sockets=1,cores=4,threads=1 \
-device virtio-scsi-pci,id=scsi \
-drive file=/Win/windows.img,id=disk,format=raw,if=none -device scsi-hd,drive=disk \
-drive file=/Win/virtio-win.iso.1,id=virtiocd,if=none -device ide-cd,bus=ide.1,drive=virtiocd \
-drive file=/Win/ru_windows_7_3in1_x64_by_AG_09.2015.iso,id=isocd,if=none -device scsi-cd,drive=isocd \
-drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/ovmf_x64.bin \
-vga std \
#-device vfio-pci,host=02:00.0,x-vga=on -device vfio-pci,host=02:00.1 \
Если же нет, используем Seabios
qemu-system-x86_64 -enable-kvm -m 1024 -cpu host,kvm=off \
-smp 4,sockets=1,cores=4,threads=1 \
-device virtio-scsi-pci,id=scsi \
-drive file=/Win/windows.img,id=disk,format=raw,if=none -device scsi-hd,drive=disk \
-drive file=/Win/virtio-win.iso.1,id=virtiocd,if=none -device ide-cd,bus=ide.1,drive=virtiocd \
-drive file=/Win/windows.iso,id=isocd,if=none -device scsi-cd,drive=isocd \
-vga std \
#-device vfio-pci,host=02:00.0,x-vga=on -device vfio-pci,host=02:00.1 \
windows.img — образ жесткого диска, создается командой dd if=/dev/zero of=windows.img bs=1M seek=60000 count=0seek=60000 размер диска в мегабайтах.
virtio-win.iso — образ с драйверами, берется последующей ссылки [ https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/latest-virtio/virtio-win.iso ]
windows.iso — образ диска с Windows, сами разберетесь где его брать, если используете ovmf убедитесь, что образ поддерживает загрузку UEFI. и при загрузке системы скорее всего надо будет ввести команду следующего вида: PS0:/EFI/BOOT/bootx64.efi
Данные конфиги для начальной установки Windows и все должно пройти на отлично.

3. После окончания установки, настало время прокинуть видеокарту.
Раскоментируем строку в конфиге
-device vfio-pci,host=02:00.0,x-vga=on -device vfio-pci,host=02:00.1 \
и запустим виртуалку.

Если все прошло хорошо, должно определиться новое устройство, скачиваем и устанавливаем драйвера для видеокарты, я не ставил никакого лишнего софта, только драйвера, пишут что Catalyst control center да и nvidia experience загоняет в синий экран, не проверял.

Нужно не забыть установить synergy, без этой программы управление(мышкой и клавиатурой) виртуалкой будет невозможно.
Найдете ее на торрентах или прочих сайтах, там в настройках надо указать client: 10.0.2.2(дефолтный ip хоста) и имя экрана, допустим Windows. Теперь настроим synergy на хосте(компьютер с Linux), создадим конфиг следующего содержания:
synergy.conf
# Example config
section: screens
    Windows:
	halfDuplexCapsLock = false
	halfDuplexNumLock = false
	halfDuplexScrollLock = false
	xtestIsXineramaUnaware = false
	switchCorners = none 
	switchCornerSize = 0
    Linux:
	halfDuplexCapsLock = false
	halfDuplexNumLock = false
	halfDuplexScrollLock = false
	xtestIsXineramaUnaware = false
	switchCorners = none 
	switchCornerSize = 0
end

section: aliases
    Windows:
	10.0.2.15 # default for vm
    Linux:
	10.0.2.2  # default for host
end

section: links
    Windows:
	right = Linux
    Linux:
	left = Windows
end

section: options
    relativeMouseMoves = true
    screenSaverSync = true
    win32KeepForeground = false
    switchCorners = none 
    switchCornerSize = 0
    keystroke(f12) = lockCursorToScreen(toggle)
end
Windows и Linux это имена экранов, измените на ваши
Запустим synergy synergys --config synergy.conf --debug INFO, и при передвижение мышки за левую часть экрана, она должна переходить на виртуалку.
Если все получилось, выключаем виртуальную машину, в конфиге меняем строку -vga std на -vga none, подключаем к выходу проброшенной видеокарты кабель к монитору, запускаем виртуалку и у нас на экране должна появится картинка с процессом загрузки. Проверяем функциональность synergy, кнопка F12 блокирует курсор на текущем экране.

4. Прокидываем звук, если вы используете pulseaudio просто укажите перед запуском quemu QEMU_AUDIO_DRV=pa если же ALSA, то предлагаю вам использовать утилиту apulse, она есть в AUR [ https://aur.archlinux.org/packages/apulse/ ] и запуск виртуалки будет следующим QEMU_AUDIO_DRV=pa apulse qemu-system-x86_64.....5. У меня 2 монитора, и при запуске виртуалки на главный монитор(центральный) через vga идет картинка с Windows. а правый становится главным Linux'овым монитором.
К основной видеокарте правый монитор подключен через DVI, центральный монитор подключен к «виртуальной» видюхе через VGA, а к основной через HDMI.
Команда xrandr --output DVI-I-1 --auto && xrandr --output HDMI-0 --offВаши подключенные мониторы и возможные режимы работы можно посмотреть командой xrandr

Выклаываю полный скрипт запуска виртуалки
xrandr --output DVI-I-1 --auto && xrandr --output HDMI-0 --off 
synergys --config synergy.conf -d INFO > synergy.log
apulse qemu-system-x86_64 -enable-kvm -m 3048 -cpu host,kvm=off  \
-smp 6,cores=6,threads=1,sockets=1 \
-device virtio-scsi-pci,id=scsi \
-drive file=/Win/windows.img,id=disk,format=raw,if=none -device scsi-hd,drive=disk \
-drive file=/Win/virtio-win.iso.1,id=virtiocd,if=none -device ide-cd,bus=ide.1,drive=virtiocd \
-rtc base=localtime \
-soundhw hda \
-vga none \
-device vfio-pci,host=02:00.0,multifunction=on,x-vga=on
xrandr --output HDMI-0 --auto && xrandr --output DVI-I-1 --off
-soundhw hda \
-audiodev pa,id=pa,server=/run/user/1000/pulse/native
kill -9 `pgrep synergys`
Так же рекомендую отключить запрос на восстановление системы при загрузке после сбоев
bcdedit /set {current} bootstatuspolicy ignoreallfailures
bcdedit /set {current} recoveryenabled no
В данную тему я нырнул лишь ради интереса и возможности поиграть в ММО Black Desert, отлично кстати работает.


UPD 11.10.2016
Сегодня вновь столкнулся с пробросом видеокарты, но теперь мне нужен был еще и звук по hdmi, немного погуглив нашел решение http://vfio.blogspot.ru/2014/09/vfio-interrupts-and-how-to-coax-windows.html?m=1
Что бы нормально работал звук через HDMI проброшенный видюхи нужно включить Message Signaled Interrupts(MSI).
Для этого в реестре Windows необходимо внести правки, а именно в разделе HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\ найти вашу видеокарту, там будет два устройства видео и звук, далее в Device Parameters\Interrupt Management создать(если его нет) раздел MessageSignaledInterruptProperties и в нем DWORD параметр MSISupported со значением 1, он включит MSI. После перезагрузки звук должен прекрасно заработать.

UPD 01.06.2019
Обновил компьютер до Ryzen и столкнулся с проблемой
vfio_bar_restore: 0000:0a:00.1 reset recovery - restoring bars
vfio-pci 0000:0a:00.0: enabling device (0000 -> 0003)
qemu-system-x86_64: vfio: Unable to power on device, stuck in D3
Подробности здесь AMD Ryzen и проблемы с пробросом видеокарты в QEMU KVM

UPD 15.09.2019
После очередного обновления начались неприятности, qemu падал в core-dump при попытке издать малейший звук, решилась эта проблема добавлением строки
-audiodev pa,id=pa,server=/run/user/1000/pulse/native
1000 — id вашего юзера, все переменные QEMU_AUDIO можно убрать.

Если будет писать что нет доступа
pulseaudio: Wrong context state
pulseaudio: Reason: Access denied
pulseaudio: Failed to initialize PA contextaudio: Could not init `pa' audio driver
audio: warning: Using timer based audio emulation

Можно скопировать пользовательские cookie в root
cp ~/.config/pulse/cookie /root/.config/pulse/cookie
На 15.09 проблема с Ryzen еще присутствует, приходится патчить ядро...

Комментарии ()

  1. Snowkai 31 мая 2017, 19:58 # 0
    А есть инфа, по тому же самому, но прокидыванию видихи из Винды в гостевой Линукс?
    1. cloudsv 01 июня 2017, 11:16(Комментарий был изменён) # 0
      Про прокидывание видеокарты в виндах не слышал и гугл видимо тоже
    2. Demige 18 января 2018, 22:47 # 0
      Никак не могу прокинуть видеокарту Nvidia 1050ti. bios — UEFI. Всё делаю как в статье, в винте после установки дров пишет что «это устройство было остановлено, поскольку оно сообщило о возникновении неполадок».

      Пробовал делать по этой статье: habrahabr.ru/post/211909/, пишет что устройство не может выделить ресурсы, сначала отключите что-то ещё.

      1. cloudsv 18 января 2018, 22:49(Комментарий был изменён) # 0
        После установки дров, отключи qemu видеокарту -vga none и жди вывод на монитор, у самого сейчас gtx 1050, отлично прокидывается :-)
        1. Demige 18 января 2018, 23:07 # 0
          Не хотит :(. Открывается консоль. На мониторе ничего. На system_powerdown машина не реагирует.
          1. cloudsv 18 января 2018, 23:09 # 0
            Пиши в телеграм t.me/cloudsv
      2. Евгений 10 мая 2019, 05:35 # 0
        Здравствуйте. Подскажите какую VMware установить на Win10 чтобы виртуальная машина определила NVIDIA Quadro из www.digitalvision.tv/w/index.php?title=Support:Drivers#Supported_Drivers_and_Software_Versions

        железо:
        Тип ЦП QuadCore Intel Core i7-3770, 3700 MHz (37 x 100)
        Системная плата Asus P8H77-V LE (3 PCI, 2 PCI-E x1, 2 PCI-E x16, 4 DDR3 DIMM, Audio, Video, Gigabit LAN)
        Чипсет системной платы Intel Panther Point H77, Intel Ivy Bridge
        Системная память 24518 МБ (DDR3-1600)
        Дисковый накопитель R3SL120G (111 ГБ)
        Дисковый накопитель ST2000DM001-1CH164 (2 ТБ, 7200 RPM, SATA-III)
        Дисковый накопитель ST2000DM006-2DM164 (2 ТБ, 7200 RPM, SATA-III)
        Видеоадаптер GeForce RTX 2060 (6 ГБ)
        1. cloudsv 02 июня 2019, 12:22 # 0
          Пропустил видимо уведомление о комментарии, но к сожалению c пробросом видеокарт в Windows я совершенно не знаком.

          ПолагаюVMware vSphere умеет пробрасывать устройства в VM.
        2. Kenzi 13 июля 2020, 20:03 # 0
          Подскажите пожалуйста, а можно пробросить единственную видеокарту, а хост оставить на графике intel?
          1. cloudsv 14 июля 2020, 01:40 # 0
            Что значит единственную? Единственную дискретную? Конечно можно, интел для хоста, а плата для виртуалки

          Авторизация

          GitHubGoogleVkontakteYandex
          Есть вопрос или предложение пиши в Telegram @cloudsv

          MTProto прokси для Telegram

          Прямой эфир

          Diego mont 25 мая 2023, 07:04
          Полезные боты в Telegram 2
          cloudsv 24 апреля 2023, 17:56
          Обновление Scala Rider G4 52
          cloudsv 12 ноября 2022, 19:16
          Установка и настройка minidlna 3
          cloudsv 03 ноября 2022, 03:42
          Настройка прокси mtproto для Telegram 52
          cloudsv 03 января 2022, 10:50
          Let's Encrypt это легко и просто 4
          cloudsv 10 сентября 2020, 13:17
          MySQL Workbench падает при подключении 2
          cloudsv 05 августа 2020, 11:57
          Мне вчера стукнуло 34 4
          cloudsv 07 августа 2023, 22:56
          Linux Asus ROG x13 flow 2022 GV301RE и Linux 0
          cloudsv 15 апреля 2023, 16:23
          Linux Уведомление о смены workspace в X11 Linux 0
          cloudsv 17 октября 2020, 09:55
          Linux Отключить DHCP IPv6 в systemd 0
          cloudsv 30 июля 2020, 21:54
          О жизни Мне вчера стукнуло 34 4
          cloudsv 15 апреля 2020, 15:45
          Linux Основные hotkeys редактора Vim 0
          cloudsv 01 октября 2019, 08:00
          Linux Локальный редирект порта в Linux 0
          cloudsv 25 августа 2019, 16:14
          О жизни Социальная сеть от Яндекса Aura 0
          cloudsv 30 июля 2019, 21:34
          О жизни 33 year old 0
          cloudsv 25 июня 2019, 18:29
          Telegram Полезные боты в Telegram 2