virtio-win / kvm-guest-drivers-windows

Windows paravirtualized drivers for QEMU\KVM
https://www.linux-kvm.org/page/WindowsGuestDrivers
BSD 3-Clause "New" or "Revised" License
1.92k stars 377 forks source link

virtio-gpu: Possible to support "Duplicate these displays" ? #993

Open jonesmz opened 8 months ago

jonesmz commented 8 months ago

Is your feature request related to a problem? Please describe. I have a libvirt/virtual-machine-manager Windows 10 virtual machine with a VFIO passed-through physical GPU.

For remote access purposes, I also have a Spice display configured.

When viewing the remote machine via virtual-machine-manager/Spice, when the viogpudod driver isn't installed, Windows configures the "Microsoft Basic Display Driver" for the virtio video device.

With the "Microsoft Basic Display Driver", the resolution is able to be configured as 1920x1080, but has an "Active Signal Resolution" of 1280x800. So the displayed graphics are squished on the virtual-machine-manager screen.

However, Importantly I can set the physical GPU and virtio device as "Duplicate these displays", which shows allows the remote machine to see the same data that's on the physical screen.

If i install the viogpudod driver the resolution can be set to 1920x1080 properly (though the "Active Signal Resolution" is shown as -1x-1, which doesn't seem right), However, i can't set "Duplicate these displays", meaning that I can't see what's on the physical screen from the remote virtual-machine-manager screen.

Is it possible to add support for duplicating the display? It's not clear that this is possible for display-only-drivers to support the "Duplicate these displays" feature, but the "Microsoft Basic Display Driver' seemingly supporting this makes me think it's possible.

vrozenfe commented 8 months ago

@jonesmz

Can you please post the qemu command line for viogpudod config?

Thanks, Vadim.

jonesmz commented 8 months ago

This is the xml for libvirt

<domain type="kvm">
  <name>Huginn</name>
  <uuid>d878035b-a9d6-4b57-98d6-d6495a842367</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">33554432</memory>
  <currentMemory unit="KiB">33554432</currentMemory>
  <memoryBacking>
    <source type="memfd"/>
    <access mode="shared"/>
  </memoryBacking>
  <vcpu placement="static">8</vcpu>
  <cputune>
    <vcpupin vcpu="0" cpuset="8"/>
    <vcpupin vcpu="1" cpuset="9"/>
    <vcpupin vcpu="2" cpuset="10"/>
    <vcpupin vcpu="3" cpuset="11"/>
    <vcpupin vcpu="4" cpuset="24"/>
    <vcpupin vcpu="5" cpuset="25"/>
    <vcpupin vcpu="6" cpuset="26"/>
    <vcpupin vcpu="7" cpuset="27"/>
  </cputune>
  <os firmware="efi">
    <type arch="x86_64" machine="pc-q35-8.0">hvm</type>
    <firmware>
      <feature enabled="no" name="enrolled-keys"/>
      <feature enabled="yes" name="secure-boot"/>
    </firmware>
    <loader readonly="yes" secure="yes" type="pflash">/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd</loader>
    <nvram template="/usr/share/edk2-ovmf/OVMF_VARS.fd">/var/lib/libvirt/qemu/nvram/Huginn_VARS.fd</nvram>
    <bootmenu enable="yes"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <viridian/>
    <hyperv mode="passthrough">
    </hyperv>
    <kvm>
      <hint-dedicated state="on"/>
    </kvm>
    <pvspinlock state="on"/>
    <vmport state="off"/>
    <smm state="on"/>
  </features>
  <cpu mode="host-passthrough" check="none" migratable="off">
    <topology sockets="1" dies="1" cores="4" threads="2"/>
    <feature policy="require" name="topoext"/>
  </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="cdrom">
      <driver name="qemu" type="raw"/>
      <target dev="sda" bus="sata"/>
      <readonly/>
      <shareable/>
      <boot order="1"/>
      <address type="drive" controller="0" bus="0" target="0" unit="0"/>
    </disk>
    <disk type="file" device="cdrom">
      <driver name="qemu" type="raw"/>
      <source file="/home/jonesmz/Downloads/virtio-win-0.1.229.iso"/>
      <target dev="sdb" bus="sata"/>
      <readonly/>
      <shareable/>
      <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="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-root-port">
      <model name="pcie-root-port"/>
      <target chassis="10" port="0x19"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x1"/>
    </controller>
    <controller type="pci" index="11" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="11" port="0x1a"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x2"/>
    </controller>
    <controller type="pci" index="12" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="12" port="0x1b"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x3"/>
    </controller>
    <controller type="pci" index="13" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="13" port="0x1c"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x4"/>
    </controller>
    <controller type="pci" index="14" model="pcie-root-port">
      <model name="pcie-root-port"/>
      <target chassis="14" port="0x1d"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x5"/>
    </controller>
    <controller type="sata" index="0">
      <address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
    </controller>
    <filesystem type="mount" accessmode="passthrough">
      <driver type="virtiofs"/>
      <source dir="/home/jonesmz/Downloads/"/>
      <target dir="host_downloads"/>
      <address type="pci" domain="0x0000" bus="0x08" slot="0x00" function="0x0"/>
    </filesystem>
    <interface type="direct">
      <mac address="52:54:00:0d:60:49"/>
      <source dev="eno1" mode="bridge"/>
      <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"/>
    <graphics type="spice" port="-1" autoport="no">
      <listen type="address"/>
      <gl enable="no"/>
    </graphics>
    <audio id="1" type="none"/>
    <video>
      <model type="virtio" heads="1" primary="yes"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0"/>
    </video>
    <hostdev mode="subsystem" type="usb" managed="yes">
      <source>
        <vendor id="0x046d"/>
        <product id="0xc52b"/>
        <address bus="3" device="3"/>
      </source>
      <address type="usb" bus="0" port="1"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
      </source>
      <boot order="2"/>
      <address type="pci" domain="0x0000" bus="0x07" slot="0x00" function="0x0"/>
    </hostdev>
    <hostdev mode="subsystem" type="usb" managed="yes">
      <source>
        <vendor id="0x045e"/>
        <product id="0x02fe"/>
      </source>
      <address type="usb" bus="0" port="2"/>
    </hostdev>
    <hostdev mode="subsystem" type="pci" managed="yes">
      <source>
        <address domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
      </source>
      <address type="pci" domain="0x0000" bus="0x03" 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="0x04" slot="0x00" function="0x0"/>
    </hostdev>
    <watchdog model="itco" action="reset"/>
    <memballoon model="virtio">
      <address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
    </memballoon>
    <rng model="virtio">
      <backend model="random">/dev/urandom</backend>
      <address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
    </rng>
    <panic model="hyperv"/>
  </devices>
</domain>

This is the qemu cmdline

/usr/bin/qemu-system-x86_64 -name guest=Huginn,debug-threads=on -S -object {"qom-type":"secret","id":"masterKey0","format":"raw","file":"/var/lib/libvirt/qemu/domain-19-Huginn/master-key.aes"} -blockdev {"driver":"file","filename":"/usr/share/edk2-ovmf/OVMF_CODE.secboot.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"} -blockdev {"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/Huginn_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"} -machine pc-q35-8.0,usb=off,vmport=off,smm=on,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format,hpet=off,acpi=on -accel kvm -cpu host,migratable=off,topoext=on,hv-time=on,kvm-pv-unhalt=on,hv-passthrough=on,hv-crash,kvm-hint-dedicated=on -global driver=cfi.pflash01,property=secure,value=on -m 32768 -object {"qom-type":"memory-backend-memfd","id":"pc.ram","share":true,"x-use-canonical-path-for-ramblock-id":false,"size":34359738368} -overcommit mem-lock=off -smp 8,sockets=1,dies=1,cores=4,threads=2 -uuid d878035b-a9d6-4b57-98d6-d6495a842367 -no-user-config -nodefaults -chardev socket,id=charmonitor,fd=37,server=on,wait=off -mon chardev=charmonitor,id=monitor,mode=control -rtc base=localtime,driftfix=slew -global kvm-pit.lost_tick_policy=delay -no-shutdown -global ICH9-LPC.disable_s3=1 -global ICH9-LPC.disable_s4=1 -boot menu=on,strict=on -device {"driver":"pcie-root-port","port":16,"chassis":1,"id":"pci.1","bus":"pcie.0","multifunction":true,"addr":"0x2"} -device {"driver":"pcie-root-port","port":17,"chassis":2,"id":"pci.2","bus":"pcie.0","addr":"0x2.0x1"} -device {"driver":"pcie-root-port","port":18,"chassis":3,"id":"pci.3","bus":"pcie.0","addr":"0x2.0x2"} -device {"driver":"pcie-root-port","port":19,"chassis":4,"id":"pci.4","bus":"pcie.0","addr":"0x2.0x3"} -device {"driver":"pcie-root-port","port":20,"chassis":5,"id":"pci.5","bus":"pcie.0","addr":"0x2.0x4"} -device {"driver":"pcie-root-port","port":21,"chassis":6,"id":"pci.6","bus":"pcie.0","addr":"0x2.0x5"} -device {"driver":"pcie-root-port","port":22,"chassis":7,"id":"pci.7","bus":"pcie.0","addr":"0x2.0x6"} -device {"driver":"pcie-root-port","port":23,"chassis":8,"id":"pci.8","bus":"pcie.0","addr":"0x2.0x7"} -device {"driver":"pcie-root-port","port":24,"chassis":9,"id":"pci.9","bus":"pcie.0","multifunction":true,"addr":"0x3"} -device {"driver":"pcie-root-port","port":25,"chassis":10,"id":"pci.10","bus":"pcie.0","addr":"0x3.0x1"} -device {"driver":"pcie-root-port","port":26,"chassis":11,"id":"pci.11","bus":"pcie.0","addr":"0x3.0x2"} -device {"driver":"pcie-root-port","port":27,"chassis":12,"id":"pci.12","bus":"pcie.0","addr":"0x3.0x3"} -device {"driver":"pcie-root-port","port":28,"chassis":13,"id":"pci.13","bus":"pcie.0","addr":"0x3.0x4"} -device {"driver":"pcie-root-port","port":29,"chassis":14,"id":"pci.14","bus":"pcie.0","addr":"0x3.0x5"} -device {"driver":"qemu-xhci","p2":15,"p3":15,"id":"usb","bus":"pci.2","addr":"0x0"} -device {"driver":"ide-cd","bus":"ide.0","share-rw":true,"id":"sata0-0-0","bootindex":1} -blockdev {"driver":"file","filename":"/home/jonesmz/Downloads/virtio-win-0.1.229.iso","node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"} -blockdev {"node-name":"libvirt-1-format","read-only":true,"driver":"raw","file":"libvirt-1-storage"} -device {"driver":"ide-cd","bus":"ide.1","share-rw":true,"drive":"libvirt-1-format","id":"sata0-0-1"} -chardev socket,id=chr-vu-fs0,path=/var/lib/libvirt/qemu/domain-19-Huginn/fs0-fs.sock -device {"driver":"vhost-user-fs-pci","id":"fs0","chardev":"chr-vu-fs0","tag":"host_downloads","bus":"pci.8","addr":"0x0"} -netdev {"type":"tap","fd":"38","vhost":true,"vhostfd":"41","id":"hostnet0"} -device {"driver":"virtio-net-pci","netdev":"hostnet0","id":"net0","mac":"52:54:00:0d:60:49","bus":"pci.1","addr":"0x0"} -audiodev {"id":"audio1","driver":"none"} -spice port=5900,addr=127.0.0.1,disable-ticketing=on,seamless-migration=on -device {"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pcie.0","addr":"0x1"} -global ICH9-LPC.noreboot=off -watchdog-action reset -device {"driver":"usb-host","hostdevice":"/dev/bus/usb/003/003","id":"hostdev0","bus":"usb.0","port":"1"} -device {"driver":"vfio-pci","host":"0000:02:00.0","id":"hostdev1","bootindex":2,"bus":"pci.7","addr":"0x0"} -device {"driver":"usb-host","hostdevice":"/dev/bus/usb/001/005","id":"hostdev2","bus":"usb.0","port":"2"} -device {"driver":"vfio-pci","host":"0000:01:00.0","id":"hostdev3","bus":"pci.3","addr":"0x0"} -device {"driver":"vfio-pci","host":"0000:01:00.1","id":"hostdev4","bus":"pci.4","addr":"0x0"} -device {"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.5","addr":"0x0"} -object {"qom-type":"rng-random","id":"objrng0","filename":"/dev/urandom"} -device {"driver":"virtio-rng-pci","rng":"objrng0","id":"rng0","bus":"pci.6","addr":"0x0"} -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny -msg timestamp=on

Seems libvirt is using virtio-vga ?

-device {"driver":"virtio-vga","id":"video0","max_outputs":1,"bus":"pcie.0","addr":"0x1"}
vrozenfe commented 8 months ago

@jonesmz

Yes, virtio-vga can be a problem. I would suggest to try "-device virtio-gpu-pci" instead.

Best, Vadim.

jonesmz commented 8 months ago

Seems that might be a limitation of libvirt

    <video>
      <model type="virtio" heads="1" primary="yes"/>
      <address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0"/>
    </video>

as far as i know doesn't provide a way to specify virtio-gpu-pci over virtio-vga

vrozenfe commented 8 months ago

I have very limited knowledge in libvirt but it looks as libvirt knows about virtio-gpu-pci capability https://github.com/libvirt/libvirt/blob/master/src/qemu/qemu_capabilities.c#L1285 Maybe it is not a of libvirt but just XML parser limitation.

daiaji commented 5 months ago

To be honest, this gave me trouble with some settings after reinstalling the system.

vrozenfe commented 5 months ago

Don't have working gpu passthrough system at the moment, but tried to check "-device VGA/cirrus/virtio-vga" + "-device virtio-gpu-pci" configurations. In all cases mirroring is not available in the "Multiply Displays" options list. I will try to investigate this issue and keep it as the feature requests for the next major release.

Vadim.

jonesmz commented 2 months ago

It's been a while, but i was messing with my virtual machine today and remembered this issue.

After searching a bit about what virtio-gpu-pci is, i think this is intended to pass through the host machine's GPU for the guest to use? This is not my objective.

I have the host machine's GPUs passed through by passing the entire IMMOU group into the VM as exclusive access with VFIO.

What I'm trying to do here is support the ability for a remote virt-manager instance to see the desktop in situations where i need to tweak settings. E.g. today my windows 11 vm has decided not to display anything on the screen via the passed through GPU, and i can't access it via spice (virt-manager), but i can RDP into it.

nfam commented 4 days ago

Just FYI, I have just got "Duplicate these displays" working. I mostly use Moonlight + Sunshine to remotely control the headless PC from MacBook, but I did plug in a monitor to the PC and saw monitor, Moonlight, and VNC all them same.

Spec:

Qemu runs inside 2 layers of container, aka. Quemu -> docker -> LXC -> Debian host. But I don't think it matters. Here is my Qemu options.

qemu-system-x86_64 \
    -machine q35 \
    -cpu host \
    -enable-kvm \
    -smp sockets=1,cores=4,threads=1 \
    -m 8G \
    -name win10-vfio \
    -uuid 4cda0e80-1b50-4323-ab83-020000000006 \
    -monitor unix:/win10-vfio/win10-vfio.sock,server,nowait \
    -rtc base=localtime \
    -device virtio-vga,bus=pcie.0,addr=0x1 \
    -device virtio-keyboard-pci,bus=pcie.0,addr=0x2 \
    -device virtio-mouse-pci,bus=pcie.0,addr=0x3 \
    -device virtio-tablet-pci,bus=pcie.0,addr=0x4 \
    -netdev bridge,id=net0,br=br0 \
    -device virtio-net-pci,netdev=net0,mac=02:00:00:00:00:06,bus=pcie.0,addr=0x5 \
    -drive id=disk0,file=/win10-vfio/win10-vfio.qcow2,index=0,media=disk,if=none,discard=unmap,detect-zeroes=unmap \
    -device virtio-blk-pci,drive=disk0,bus=pcie.0,addr=0x6 \
    -device qemu-xhci,id=xhci,bus=pcie.0,addr=0x7 \
    -audiodev none,id=snd0 \
    -device intel-hda,bus=pcie.0,addr=0x8 \
    -device hda-output,audiodev=snd0 \
    -device vfio-pci,host=00:02.0,rombar=1,x-vga=off,x-igd-gms=1,x-igd-opregion=on,bus=pcie.0,addr=0x9 \
    -display vnc=192.168.21.3:6 \
    -boot c