Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
jonesmz opened this issue Oct 26, 2023 · 9 comments
Open

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

jonesmz opened this issue Oct 26, 2023 · 9 comments

Comments

@jonesmz
Copy link

jonesmz commented Oct 26, 2023

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
Copy link
Collaborator

@jonesmz

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

Thanks,
Vadim.

@jonesmz
Copy link
Author

jonesmz commented Oct 26, 2023

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
Copy link
Collaborator

@jonesmz

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

Best,
Vadim.

@jonesmz
Copy link
Author

jonesmz commented Oct 31, 2023

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
Copy link
Collaborator

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
Copy link

daiaji commented Jan 22, 2024

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

@vrozenfe
Copy link
Collaborator

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
Copy link
Author

jonesmz commented Apr 9, 2024

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
Copy link

nfam commented Jul 3, 2024

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:

  • HW: Intel N100
  • OS: Debian Bookworm
  • Qemu 9.0.1 (docker image tianon/qemu:native)
  • Quest: Windows 10 2021 LTSC
  • GPU driver on Guest: gfx_win_101.5593 (latest)

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants