Attention
Это копипаста, записки и эксперименты, неструктурированные. Не голое howto.
В качестве железа использовалось:
- Intel® Core™ i5-4430 CPU @ 3.00GHz
- NVIDIA Corporation GM206 [GeForce GTX 960] (rev a1)
- Intel® Z87 Chipset
Основной монитор подключён через HDMI на материнской плате и использует встроенную видеокарту (Intel® HD Graphics 4600). Телевизор подключён через HDMI к видеокарте.
Из сильных огорчений: после часового гугления оказалось что видяхи, даже дорогущие, не умеют HDMI-CEC чтобы можно было отправить сигнал для включения телевизора, хотя копеечная Raspberry PI умеет :/
TLDR;
Играбельно, за исключением со временем (часы) нарастающего количества описанных ниже звуковых артефактов.
- The Witcher 2 играбельно на максимальных настройках 1920x1080 как в Windows 10, так и в SteamOS
- Ori and the Blind Forest: Definitive Edition пройдена полностью в Windows 10 виртуалке, ибо linux не поддерживает
- [Doom 4|] полностью пройден на почти максимальных настройках (после какой-то из настроек FPS резко упали до 10, но, думаю, тут уже проблема в железе).
IOMMU
http://awilliam.github.io/presentations/KVM-Forum-2016/
http://vfio.blogspot.ru/2016/09/intel-iommu-enabled-it-doesnt-mean-what.html
https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/vt-directed-io-spec.pdf
IOMMU (англ. input/output memory management unit) — блок управления памятью (MMU) для операций ввода-вывода. Так же как традиционный, процессорный блок управления памятью, который переводит виртуальные адреса, видимые процессором в физические, этот блок занимается трансляцией виртуальных адресов, видимых аппаратным устройством, в физические адреса. Wikipedia
https://www.kernel.org/doc/Documentation/Intel-IOMMU.txt
DMAR - DMA remapping
Проверить состояние IOMMU и DMAR:
dmesg|grep -e DMAR -e IOMMU
AMD
AMD systems only require that the IOMMU is enabled in the BIOS. The system is ready for PCI passthrough once the IOMMU is enabled.
Настройка модулей ядра
Xenial Fresh
Ставим свежее ядро
sudo apt-get install linux-generic-hwe-16.04-edge
Теоретически (в процессе проверки), с ядром 4.10 (на текущий момент hwe edge) можно обойтись без vfio_iommu_type1.allow_unsafe_interrupts=1
Через параметр ядра в конфигурации grub
Добавить всё что нужно в значение переменной GRUB_CMDLINE_LINUX_DEFAULT
в файле /etc/default/grub
, к дефолту добавилось следующее:
intel_iommu=on vm.nr_hugepages=5120 nvidia.blacklist=1
После этого нужно выполнить команду update-grub
для обновления конфигурации в /boot
:
$ sudo update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.10.0-26-generic
Found initrd image: /boot/initrd.img-4.10.0-26-generic
Found linux image: /boot/vmlinuz-4.4.0-83-generic
Found initrd image: /boot/initrd.img-4.4.0-83-generic
Found linux image: /boot/vmlinuz-3.19.0-37-generic
Found initrd image: /boot/initrd.img-3.19.0-37-generic
Found memtest86+ image: /memtest86+.elf
Found memtest86+ image: /memtest86+.bin
done
TODO: телега про GRUB_HIDDEN_TIMEOUT (Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.
)
Через modprobe.d
Либо воспользоваться каталогом /etc/modprobe.d/
:
echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" | sudo tee /etc/modprobe.d/vfio_iommu_type1.conf
$ sudo modprobe vfio_iommu_type1
Посмотреть текущие параметры модуля ядра, в данном случае - vfio_iommu_type1:
$ grep -H '' /sys/module/vfio_iommu_type1/parameters/*
Проверяем IOMMU
После перезагрузки проверяем что iommu работает (внимание на “IOMMU group <номер>” ):
$ for iommu_group in $(find /sys/kernel/iommu_groups/ -maxdepth 1 -mindepth 1 -type d); do echo "IOMMU group $(basename "$iommu_group")"; for device in $(ls -1 "$iommu_group"/devices/); do echo -n $'\t'; lspci -nns "$device"; done; done
IOMMU group 0
00:00.0 Host bridge [0600]: Intel Corporation 4th Gen Core Processor DRAM Controller [8086:0c00] (rev 06)
IOMMU group 1
00:01.0 PCI bridge [0604]: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor PCI Express x16 Controller [8086:0c01] (rev 06)
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation GM206 [GeForce GTX 960] [10de:1401] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:0fba] (rev a1)
IOMMU group 2
00:02.0 VGA compatible controller [0300]: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor Integrated Graphics Controller [8086:0412] (rev 06)
IOMMU group 3
00:03.0 Audio device [0403]: Intel Corporation Xeon E3-1200 v3/4th Gen Core Processor HD Audio Controller [8086:0c0c] (rev 06)
IOMMU group 4
00:14.0 USB controller [0c03]: Intel Corporation 8 Series/C220 Series Chipset Family USB xHCI [8086:8c31] (rev 05)
IOMMU group 5
00:16.0 Communication controller [0780]: Intel Corporation 8 Series/C220 Series Chipset Family MEI Controller #1 [8086:8c3a] (rev 04)
IOMMU group 6
00:1a.0 USB controller [0c03]: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #2 [8086:8c2d] (rev 05)
IOMMU group 7
00:1b.0 Audio device [0403]: Intel Corporation 8 Series/C220 Series Chipset High Definition Audio Controller [8086:8c20] (rev 05)
IOMMU group 8
00:1c.0 PCI bridge [0604]: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express Root Port #1 [8086:8c10] (rev d5)
IOMMU group 9
00:1c.2 PCI bridge [0604]: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express Root Port #3 [8086:8c14] (rev d5)
IOMMU group 10
00:1c.3 PCI bridge [0604]: Intel Corporation 82801 PCI Bridge [8086:244e] (rev d5)
04:00.0 PCI bridge [0604]: ASMedia Technology Inc. ASM1083/1085 PCIe to PCI Bridge [1b21:1080] (rev 03)
IOMMU group 11
00:1d.0 USB controller [0c03]: Intel Corporation 8 Series/C220 Series Chipset Family USB EHCI #1 [8086:8c26] (rev 05)
IOMMU group 12
00:1f.0 ISA bridge [0601]: Intel Corporation Z87 Express LPC Controller [8086:8c44] (rev 05)
00:1f.2 SATA controller [0106]: Intel Corporation 8 Series/C220 Series Chipset Family 6-port SATA Controller 1 [AHCI mode] [8086:8c02] (rev 05)
00:1f.3 SMBus [0c05]: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller [8086:8c22] (rev 05)
IOMMU group 13
03:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd. RTL8111/8168/8411 PCI Express Gigabit Ethernet Controller [10ec:8168] (rev 11)
Using vfio-pci
https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#Using_vfio-pci
Starting with Linux 4.1, the kernel includes vfio-pci, which is functionally similar to pci-stub with a few added bonuses, such as switching devices into their D3 state when they are not in use. If your system supports it, which you can try by running the following command, you should use it. If it returns en error, you will have to rely on pci-stub instead.
Сам PCIe-контроллер пробрасывать не нужно, только видеокарту. Звуковое устройство от видяхи тоже не нужно - у меня постоянно возникали звуковые артефакты (щелчки и искажения, звучит как переполнение буфера при попытке добиться малой задержки), а иной раз звук вообще вырубало. Не исключено что проблема в win10 Insider Preview который я использовал для тестов. Есть подозрение что это проблема всех windows 10, на уровне всей системы были уменьшены буферы для достижения низкой задержки в угоду звуковым программам - https://msdn.microsoft.com/ru-ru/library/windows/hardware/mt298187(v=vs.85).aspx). Update: кажется, дело в каких-то таймингах, в SteamOS тоже проблема со звуком. С изображением всё хорошо.
Проверил работу звука виртуализировав SteamOS.
http://kvm-exp.blogspot.ru/2015/07/SteamOSruninaKVMwithphysicalGPUpassthrough.html
Со звуком проблемы остались.
$ sudo apt-get remove nvidia* -y
$ lspci -nnk| grep NVIDIA | egrep -oe "(\w{4}:\w{4})"
10de:1401
10de:0fba
$ echo "options vfio-pci ids=10de:1401,10de:0fba" | sudo tee /etc/modprobe.d/vfio.conf
options vfio-pci ids=10de:1401,10de:0fba
$ grep vfio /etc/initramfs-tools/modules
vfio
vfio_iommu_type1
vfio_pci
vfio_virqfd
$ sudo update-initramfs -u
KSM
Внимание на параметр /sys/kernel/mm/ksm/merge_across_nodes
.
TODO: Проверить :)
Huge pages
Problem:
(qemu) qemu-system-x86_64: unable to map backing store for hugepages: Cannot allocate memory
echo 5120 | sudo tee /proc/sys/vm/nr_hugepages
Создаём образ диска VM
$ qemu-img create -f raw -o preallocation=falloc win10.raw 100G
VirtIO в гостевой машине REWRITE
Чтобы Windows смогла увидеть блочное устройство нужны драйверы VirtIO - без них система не увидит дисков. Win10 умеет устанавливать драйвера перед началом установки с ISO-образа. ISO-образы (а также для НГМД) можно найти тут: https://fedoraproject.org/wiki/Windows_Virtio_Drivers#Direct_download
OVMF
http://blog.system76.com/post/139138591598/howto-qemu-w-ubuntu-xenial-host-uefi-guest
https://git.mel.vin/melvin/scripts/tree/master/qemu
https://git.mel.vin/melvin/scripts/blob/master/qemu/windows_usbpass.sh
http://www.tianocore.org/ovmf/
http://www.linux-kvm.org/page/OVMF
$ sudo apt-get install ovmf
cp /usr/share/OVMF/OVMF_VARS.fd win10_ovmf.fd
XBOX 360 usb gamepad and others usb devices
Пробросить сразу все подключённые к компьютеру контроллеры xbox 360 не получилось. Для проброса первого добавляем следующий аргумент к qemu-system-x86_64
:
-usbdevice host:045e:028e
Then you can use following command in qemu monitor to add other controllers:
usb_add <host:vendor_id:product_id>
or
usb_add <host:bus.addr>
This command show you usb hierarchy: lsusb --tree
or shorterlsusb -t
Refs:
- http://download.qemu.org/qemu-doc.html#index-usb_005fadd
- http://download.qemu.org/qemu-doc.html#usb_005fdevices
When win10 guest sleep
system_wakeup
в qemu-monitor
Запуск виртуалки через QEMU-KVM
- disable kvm detection:
https://www.redhat.com/archives/libvir-list/2014-August/msg00512.html - Other optimisations for windows VMs:
http://blog.wikichoon.com/2014/07/enabling-hyper-v-enlightenments-with-kvm.html - Huge doc with a lot of manual steps on fedora 20:
http://www.firewing1.com/howtos/fedora-20/create-gaming-virtual-machine-using-vfio-pci-passthrough-kvm
qemu-system-x86_64 \
-serial none \
-parallel none \
-nodefaults \
-nodefconfig \
-no-user-config \
-enable-kvm \
-name Windows \
-cpu host,kvm=off,hv_vapic,hv_time,hv_relaxed,hv_spinlocks=0x1fff,hv_vendor_id=sugoidesu \
-smp sockets=1,cores=4,threads=1 \
-m 8192 \
-mem-path /dev/hugepages \
-mem-prealloc \
-device ich9-usb-uhci3,id=uhci \
-device usb-ehci,id=ehci \
-device nec-usb-xhci,id=xhci \
-machine pc,accel=kvm,kernel_irqchip=on,mem-merge=off \
-drive if=pflash,format=raw,readonly,file=/usr/share/OVMF/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=./win10_ovmf.fd \
-rtc base=localtime,clock=host,driftfix=none \
-boot order=d \
-net nic,macaddr=52:54:00:00:00:01,model=virtio,name=net0 \
-net tap,ifname=tap0,script=no,downscript=no,vhost=on \
-usbdevice tablet \
-drive if=virtio,id=drive0,file=./win10.raw,format=raw,cache=none,aio=native \
-drive file=/media/keeper/homer/isos/Windows10_InsiderPreview_Client_x64_ru-ru_14332.iso,if=ide,id=cd0,media=cdrom,readonly \
-drive file=./virtio-win.iso,if=ide,id=cd1,media=cdrom,readonly \
-device vfio-pci,host=01:00.0,addr=09.0,multifunction=on \
-device vfio-pci,host=01:00.1,addr=09.1 \
-device usb-host,hostbus=3,hostaddr=6 \
-usbdevice host:045e:028e
http://www.linux-kvm.org/images/b/b3/01x09b-VFIOandYou-small.pdf
https://wiki.archlinux.org/index.php/QEMU
http://blog.system76.com/tagged/ovmf
LAST STARTS WIN10
Имя интерфейса tap0 - прямо в коде, копипаста опасна и аргументы могут быть неюзабельными, много лишнего. Звук через через PulseAudio.
win10_start.sh
#!/bin/bash
export QEMU_AUDIO_DRV="pa"
modprobe vfio_iommu_type1
qemu-system-x86_64 \
-serial none \
-parallel none \
-nodefaults \
-nodefconfig \
-no-user-config \
-enable-kvm \
-name Windows \
-cpu host,kvm=off,hv_vapic,hv_time,hv_relaxed,hv_spinlocks=0x1fff,hv_vendor_id=sugoidesu \
-smp sockets=1,cores=4,threads=1 \
-m 8192 \
-mem-path /dev/hugepages \
-mem-prealloc \
-device ich9-usb-uhci3,id=uhci \
-device usb-ehci,id=ehci \
-device nec-usb-xhci,id=xhci \
-machine pc,accel=kvm,kernel_irqchip=on,mem-merge=off \
-drive if=pflash,format=raw,readonly,file=/usr/share/OVMF/OVMF_CODE.fd \
-drive if=pflash,format=raw,file=./win10_ovmf.fd \
-rtc base=localtime,driftfix=slew \
-boot order=d \
-net nic,macaddr=52:54:00:00:00:01,model=virtio,name=net0 \
-net tap,ifname=tap0,script=no,downscript=no,vhost=on \
-usbdevice tablet \
-drive if=virtio,id=drive0,file=./win10.raw,format=raw,cache=none,aio=native \
-drive file=/media/keeper/homer/isos/Windows10_InsiderPreview_Client_x64_ru-ru_14332.iso,if=ide,id=cd0,media=cdrom,readonly \
-drive file=./virtio-win.iso,if=ide,id=cd1,media=cdrom,readonly \
-device vfio-pci,host=01:00.0,addr=09.0,multifunction=on \
-device vfio-pci,host=01:00.1,addr=09.1,multifunction=on \
-soundhw hda \
-usbdevice host:045e:028e \
-device usb-host,hostbus=3,hostaddr=4 \
-monitor stdio
win10_net.sh (запускаем после старта машины, по идее, можно сделать хук, но лучше всё обернуть в libvirt):
#!/bin/bash
brctl addif virbr0 tap0
ip l set tap0 up
LAST STARTS STEAMOS
Имя интерфейса tap0 - прямо в коде, копипаста опасна и аргументы могут быть неюзабельными, много лишнего. Звук через через hdmi видео-карты (в теории :D).
steam_os_start.sh:
#!/bin/bash
modprobe vfio_iommu_type1
qemu-system-x86_64 \
-serial none \
-parallel none \
-nodefaults \
-nodefconfig \
-no-user-config \
-enable-kvm \
-name Windows \
-cpu host,kvm=off,hv_vapic,hv_time,hv_relaxed,hv_spinlocks=0x1fff,hv_vendor_id=sugoidesu \
-smp sockets=1,cores=4,threads=1 \
-m 8192 \
-mem-path /dev/hugepages \
-mem-prealloc \
-device ich9-usb-uhci3,id=uhci \
-device usb-ehci,id=ehci \
-device nec-usb-xhci,id=xhci \
-machine pc,accel=kvm,kernel_irqchip=on,mem-merge=off \
-drive if=pflash,format=raw,readonly,file=/usr/share/OVMF/OVMF_CODE.fd \
-rtc base=localtime,clock=host,driftfix=none \
-net nic,macaddr=52:54:00:00:00:01,model=virtio,name=net0 \
-net tap,ifname=tap0,script=no,downscript=no,vhost=on \
-usbdevice tablet \
-boot order=c \
-drive file=./steamos.raw,if=none,id=drive-virtio-disk0,format=raw,cache=none,aio=native \
-device virtio-blk-pci,scsi=off,addr=0x7,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1 \
-device vfio-pci,host=01:00.0,addr=09.0,multifunction=on \
-device vfio-pci,host=01:00.1,addr=09.1,multifunction=on \
-usbdevice host:045e:028e \
-device usb-host,hostbus=3,hostaddr=6 \
-monitor stdio
# -drive if=pflash,format=raw,file=./steamos_ovmf.fd \
# -drive if=pflash,format=raw,readonly,file=/usr/share/OVMF/OVMF_CODE.fd \
# -drive if=virtio,id=drive0,file=./steamos.raw,format=raw,cache=none,aio=native \
# -boot order=d \
# -drive file=/media/keeper/homer/isos/steamos.iso,if=none,id=drive-ide0-0-0,readonly=on,format=raw \
# -device ide-cd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
steamos_net.sh (запускаем после старта машины, по идее, можно сделать хук, но лучше всё обернуть в libvirt):
$ cat net_start.sh
#!/bin/bash
brctl addif virbr0 tap0
ip l set tap0 up
Комментариев нет:
Отправить комментарий