Здрасти,
Я тут немного извращаюсь, пытаюсь найти решение, но возможно вы ускорите всё это, либо идею какую-то подадите.
Есть ПК, Intel i7-8700k, Nvidia RTX 2070. Собирал в основном для игр, поэтому стоит дуалбут с офтопиком. Для меня работать/отдыхать на линуксе намного удобнее, поэтому основная система линь. Немного надоело перезагружаться чтобы поиграть/перестать играть, поэтому захотелось попробовать держать винду на виртуалке и просто пробросить ей видеокарту.
И так, желание примерно следующее. Компьютер включается с линуксом, который использует nvidia (так как это бывает нужно, что-нибудь порендерить/поиграть нативное и т.п.). Когда мне хочется поиграть, я просто запускаю виртуалку и nvidia передаётся виртуалке, а потом останавливаю виртуалку и возвращаюсь к линуксу. При этом, у меня два монитора, на одном я всегда хочу видеть линукс, а второй монитор будет переключаться между линуксом и виртуалкой. При этом хочу иметь возможность юзать обе системы/монитора. То бишь, просто провести мышку на первый монитор и там «полинуксить», а потом переключить опять на второй и продолжить играть.
Что имеется:
-
Две видеокарты - intel и nvidia и два монитора. На UEFI врубил режим multi-gpu - один монитор подключен к материнке, второй к видеокарте. Линукс стартует на первом мониторе с интелом, а потом прогружается nvidia и оба монитора/видеокарты работают.
-
Видеокарту я пробросил через qemu/kvm и всё работает. Для совместной работы в двух системах тестово использовал barrier, работает. Не тестил производительность, но если что, можно будет что-нибудь придумать (квм свитч или как-нибудь приделать проброс клавиатуры).
Но есть проблема. Чтобы загружалась виртуалка, нужно убирать из ядра nvidia. Но сделать это не получается, так как она используется иксами. Можно конечно убивать иксы, отключать нвидиа и опять стартовать, но тогда сессия вылетает. Но у меня и интел используется, который также рисует на одном из мониторов, можно ли как-то не убивая иксы убрать из ядра нвидиа и стартануть виртуалку?
Решения по типу «вайн» не принимаются, так как не всё гладко.
Чуть позже напишу полный гайд, а пока вкратце.
По железу: MB - Asus Prime z370-a
CPU - Intel i7-8700k (6 core 12 threads)
RAM - Corsair Vengeance RGB (2x16GB)
GPU - NVIDIA RTX 2070 (ASUS)
iGPU - Intel UHD Graphics 630
SSD - Intel 660p (1Tb)
HDD - Seagate (1Tb)
Monitor 1 - Dell 24" 1080p
Monitor 2 - LG 32" 1440p
SoundCard - NoName usb sound card
В UEFI врублен vt-d (для проброса видеокарты виртуалке) и iGPU Multi-Monitor (чтобы можно было использовать интегрированную карту). От материнки идут 2 видеовыхода на каждый из мониторов; от видеокарты идёт 1 видеовыход на LG монитор.
По софту:
OS - Arch
DM - SDDM
WM - i3-gaps
bumblebee, mesa, libvirt, virt-manager, qemu-kvm, barrier
Для видеокарты нужно установить bumblebee. Куча гайдов про то, как настроить vfio и т.п., но на деле это ничего не нужно (кроме intel_iommu=on) , если установлен bumblee. Как я понимаю, он при включении не даёт видеокарте загрузиться и в целом держит её подальше от ядра, благодаря чему видеокарту можно свободно использовать как в виртуалке, так и в свободное время просто запустив приложение через optirun.
Для ядра в граб добавляется -
GRUB_CMDLINE_LINUX="intel_iommu=on isolcpus=4-7 nohz_full=4-7 rcu_nocbs=4-7"
В virt-manager куча нюансов относительно процессора, как для обмана видеокарты (для установки драйвера, иначе ругается), так и для оптимизации производительности, звука.
<domain xmlns:qemu="http://libvirt.org/schemas/domain/qemu/1.0" type="kvm">
<name>win10</name>
<uuid>23795b4a-69db-428e-88eb-0532383d6f0c</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://microsoft.com/win/10"/>
</libosinfo:libosinfo>
</metadata>
<memory unit="KiB">16777216</memory>
<currentMemory unit="KiB">16777216</currentMemory>
<vcpu placement="static">8</vcpu>
<iothreads>1</iothreads>
<cputune>
<vcpupin vcpu="0" cpuset="2"/>
<vcpupin vcpu="1" cpuset="8"/>
<vcpupin vcpu="2" cpuset="3"/>
<vcpupin vcpu="3" cpuset="9"/>
<vcpupin vcpu="4" cpuset="4"/>
<vcpupin vcpu="5" cpuset="10"/>
<vcpupin vcpu="6" cpuset="5"/>
<vcpupin vcpu="7" cpuset="11"/>
<emulatorpin cpuset="0,6"/>
<iothreadpin iothread="1" cpuset="0,6"/>
</cputune>
<os>
<type arch="x86_64" machine="pc-q35-4.2">hvm</type>
<loader readonly="yes" type="pflash">/usr/share/ovmf/x64/OVMF_CODE.fd</loader>
<nvram>/usr/share/ovmf/x64/OVMF_VARS.fd</nvram>
<boot dev="hd"/>
</os>
<features>
<acpi/>
<apic/>
<hyperv>
<relaxed state="on"/>
<vapic state="on"/>
<spinlocks state="on" retries="8191"/>
<vendor_id state="on" value="1234567890ab"/>
</hyperv>
<kvm>
<hidden state="on"/>
</kvm>
<vmport state="off"/>
<ioapic driver="kvm"/>
</features>
<cpu mode="host-passthrough" check="partial">
<topology sockets="1" cores="4" threads="2"/>
</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>destroy</on_crash>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type="file" device="disk">
<driver name="qemu" type="qcow2"/>
<source file="/home/doctor/vms/win10.qcow2"/>
<target dev="sda" bus="sata"/>
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
</disk>
<disk type="block" device="disk">
<driver name="qemu" type="raw" cache="none" io="native"/>
<source dev="/dev/nvme0n1p3"/>
<target dev="sdb" bus="sata"/>
<address type="drive" controller="0" bus="0" target="0" unit="1"/>
</disk>
<controller type="usb" index="0" model="qemu-xhci" ports="15">
<address type="pci" domain="0x0000" bus="0x02" 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="0x10"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="2" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="2" port="0x11"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x1"/>
</controller>
<controller type="pci" index="3" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="3" port="0x12"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x2"/>
</controller>
<controller type="pci" index="4" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="4" port="0x13"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x3"/>
</controller>
<controller type="pci" index="5" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="5" port="0x14"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x4"/>
</controller>
<controller type="pci" index="6" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="6" port="0x15"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x5"/>
</controller>
<controller type="pci" index="7" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="7" port="0x16"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x6"/>
</controller>
<controller type="pci" index="8" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="8" port="0x17"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x7"/>
</controller>
<controller type="pci" index="9" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="9" port="0x18"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="10" model="pcie-to-pci-bridge">
<model name="pcie-pci-bridge"/>
<address type="pci" domain="0x0000" bus="0x09" slot="0x00" function="0x0"/>
</controller>
<controller type="pci" index="11" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="11" port="0x19"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x1"/>
</controller>
<controller type="pci" index="12" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="12" port="0x1a"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x2"/>
</controller>
<controller type="virtio-serial" index="0">
<address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
</controller>
<controller type="scsi" index="0" model="virtio-scsi">
<address type="pci" domain="0x0000" bus="0x0b" slot="0x00" function="0x0"/>
</controller>
<interface type="bridge">
<mac address="52:54:00:1b:af:60"/>
<source bridge="virbr0"/>
<model type="virtio"/>
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</interface>
<input type="mouse" bus="ps2"/>
<input type="keyboard" bus="ps2"/>
<sound model="ich9">
<codec type="micro"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
</sound>
<hostdev mode="subsystem" type="pci" managed="yes">
<source>
<address domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</source>
<address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
</hostdev>
<hostdev mode="subsystem" type="pci" managed="yes">
<source>
<address domain="0x0000" bus="0x01" slot="0x00" function="0x1"/>
</source>
<address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
</hostdev>
<hostdev mode="subsystem" type="pci" managed="yes">
<source>
<address domain="0x0000" bus="0x01" slot="0x00" function="0x2"/>
</source>
<address type="pci" domain="0x0000" bus="0x07" slot="0x00" function="0x0"/>
</hostdev>
<hostdev mode="subsystem" type="pci" managed="yes">
<source>
<address domain="0x0000" bus="0x01" slot="0x00" function="0x3"/>
</source>
<address type="pci" domain="0x0000" bus="0x08" slot="0x00" function="0x0"/>
</hostdev>
<memballoon model="virtio">
<address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
</memballoon>
</devices>
<qemu:commandline>
<qemu:arg value="-audiodev"/>
<qemu:arg value="pa,id=pa1,server=/run/user/1000/pulse/native,in.latency=20000,out.latency=20000"/>
</qemu:commandline>
</domain>
В i3 также два хоткея - Win PgUP, Win PgDwn
bindsym $mod+Prior exec sudo /home/doctor/bin/win10-on ### LAUNCH VM
bindsym $mod+Next exec sudo /home/doctor/bin/win10-off ### POWEROFF VM
а в самих скриптах пока что простенько, win10-on
#!/bin/sh
# Turn to 1 screen
bash /home/doctor/.screenlayout/singlescreen.sh
# Run cpu governer
for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor;
do echo "performance" > $file
done
# Run vm
virsh start win10
и win10-off
#!/bin/sh
# Shutdown vm
virsh shutdown win10
# Stop gpu governer
for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
do echo "powersave" > $file
done
# Turn to 2 screens
bash /home/doctor/.screenlayout/dualscreen.sh
Чтобы можно было свободно двигать мышкой/клавиатурой между виртуалкой и хостом и иметь общий буфер стоит barrier.