From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 6E9CD1FF0AD for ; Sun, 04 Oct 2026 15:30:10 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id 3C5E621589; Sun, 04 Oct 2026 15:30:09 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=dualfroz.com; s=dkim; t=1791120601; h=from:subject:date:message-id:to:mime-version: content-transfer-encoding; bh=qQnEFeYMKVl615C5TdtvCnyWDsCLgg7vllP5lwpxcvw=; b=ndJwxV1dL/Lrn/GQ6tv6sUWjEYeNXTUgQ7ZUvJIynHat6mxs7kwnjAfzDR8leAh6xB+bGr B85jdrCzl22+RntPSRsuAHU8a6sKDEpyLHBqo24P0d+baf9S2SC9a7k7ZBkFXckcWZKX07 8rpFbWumdfYnKVRN0sllYjNJWiw8/RIGqEtuTlwxYxczYaNMTFAG79ZquGFD5lHY2zyy5s M2GzUHVwPI9txqAwJj3MKQyS1zp07F+Zz+67gP5+yGit+x+vjV8CK0Jw9fdtIcT0Sp0XwB /G4mZAeP+kqbFL4k5x42PN/4/Pw38wGPqNacn5whQDNYQKqeaWSvmffdMaXD8g== From: Michal Fox To: pve-devel@lists.proxmox.com Subject: [PATCH qemu-server] fix #7525: vga: allow setting the number of outputs for VirtIO GPU Date: Sun, 4 Oct 2026 13:29:59 +0000 Message-ID: <20261004132959.7-1-me@dualfroz.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Last-TLS-Session-Version: TLSv1.3 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.200 Adjusted score from AWL reputation of From: address DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 3NLZ6ZXTMXEOOVLZIXLUMCDB4EMAARQL X-Message-ID-Hash: 3NLZ6ZXTMXEOOVLZIXLUMCDB4EMAARQL X-MailFrom: me@dualfroz.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: With SPICE and QXL, Linux guests get 'max_outputs=4' on the display device, so they can use up to four displays with a single device. For the VirtIO GPU, there is no way to change QEMU's default of a single output, so using multiple displays requires passing the whole device via custom arguments. Add a 'max-outputs' option to the 'vga' property, which sets the 'max_outputs' property of the VirtIO GPU, for both 'virtio' and 'virtio-gl'. QEMU supports up to 16 outputs. Other display types reject the option, as QXL handles multiple displays on its own. Signed-off-by: Michal Fox --- Tested with new config to command tests for 'virtio,max-outputs=2' and for the rejection with 'qxl'. Without the change to print_vga_device(), the first one fails, as 'max_outputs' is missing. The whole qemu-server test suite passes. QEMU 11.0 starts with '-device virtio-vga,max_outputs=2' and 16, and rejects 17 with "invalid max_outputs > 16". The option is not exposed in the GUI yet; saving the display settings there would drop it, which could be done as a follow-up in pve-manager. src/PVE/QemuServer.pm | 15 ++++++++ src/test/cfg2cmd/vga-max-outputs-qxl.conf | 11 ++++++ src/test/cfg2cmd/vga-virtio-max-outputs.conf | 10 ++++++ .../cfg2cmd/vga-virtio-max-outputs.conf.cmd | 35 +++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 src/test/cfg2cmd/vga-max-outputs-qxl.conf create mode 100644 src/test/cfg2cmd/vga-virtio-max-outputs.conf create mode 100644 src/test/cfg2cmd/vga-virtio-max-outputs.conf.cmd diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index f199371d..37dda998 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -187,6 +187,15 @@ my $vga_fmt = { enum => ['vnc'], optional => 1, }, + 'max-outputs' => { + description => "Sets the maximum number of displays the guest can use. Only supported" + . " with 'virtio' and 'virtio-gl'.", + type => 'integer', + optional => 1, + minimum => 1, + maximum => 16, + default => 1, + }, }; my $ivshmem_fmt = { @@ -1513,6 +1522,12 @@ sub print_vga_device { } } + if (my $outputs = $vga->{'max-outputs'}) { + die "'max-outputs' is only supported with VGA type 'virtio' or 'virtio-gl'\n" + if $vga->{type} !~ m/^virtio/; + $max_outputs = ",max_outputs=$outputs"; + } + die "no device-type for $vga->{type}\n" if !$type; my $memory = ""; diff --git a/src/test/cfg2cmd/vga-max-outputs-qxl.conf b/src/test/cfg2cmd/vga-max-outputs-qxl.conf new file mode 100644 index 00000000..d85155e3 --- /dev/null +++ b/src/test/cfg2cmd/vga-max-outputs-qxl.conf @@ -0,0 +1,11 @@ +# TEST: Test that max-outputs is rejected for non-VirtIO GPUs +# EXPECT_ERROR: 'max-outputs' is only supported with VGA type 'virtio' or 'virtio-gl' +cores: 2 +memory: 2048 +name: qxldisplays +net0: virtio=A2:C0:43:67:08:A1,bridge=vmbr0 +ostype: l26 +scsihw: virtio-scsi-pci +smbios1: uuid=7b10d7af-b932-4c66-b2c3-3996152ec465 +vmgenid: c773c261-d800-4348-9f5d-167fadd53cf8 +vga: qxl,max-outputs=2 diff --git a/src/test/cfg2cmd/vga-virtio-max-outputs.conf b/src/test/cfg2cmd/vga-virtio-max-outputs.conf new file mode 100644 index 00000000..1146b353 --- /dev/null +++ b/src/test/cfg2cmd/vga-virtio-max-outputs.conf @@ -0,0 +1,10 @@ +# TEST: Test for VirtIO GPU with multiple outputs +cores: 2 +memory: 2048 +name: virtiodisplays +net0: virtio=A2:C0:43:67:08:A1,bridge=vmbr0 +ostype: l26 +scsihw: virtio-scsi-pci +smbios1: uuid=7b10d7af-b932-4c66-b2c3-3996152ec465 +vmgenid: c773c261-d800-4348-9f5d-167fadd53cf8 +vga: virtio,max-outputs=2 diff --git a/src/test/cfg2cmd/vga-virtio-max-outputs.conf.cmd b/src/test/cfg2cmd/vga-virtio-max-outputs.conf.cmd new file mode 100644 index 00000000..613f0411 --- /dev/null +++ b/src/test/cfg2cmd/vga-virtio-max-outputs.conf.cmd @@ -0,0 +1,35 @@ +/usr/bin/kvm \ + -id 8006 \ + -name virtiodisplays \ + -no-shutdown \ + -chardev 'socket,id=qmp,path=/var/run/qemu-server/8006.qmp,server=on,wait=off' \ + -object 'monitor-qmp,chardev=qmp,id=monitor-qmp' \ + -chardev 'socket,id=qmp-event,path=/var/run/qmeventd.sock,reconnect-ms=5000' \ + -object 'monitor-qmp,chardev=qmp-event,id=monitor-qmp-event' \ + -pidfile /var/run/qemu-server/8006.pid \ + -daemonize \ + -smbios 'type=1,uuid=7b10d7af-b932-4c66-b2c3-3996152ec465' \ + -smp '2,sockets=1,cores=2,maxcpus=2' \ + -nodefaults \ + -boot 'menu=on,strict=on,reboot-timeout=1000,splash=/usr/share/qemu-server/bootsplash.jpg' \ + -vnc 'unix:/var/run/qemu-server/8006.vnc,password=on' \ + -cpu kvm64,enforce,+kvm_pv_eoi,+kvm_pv_unhalt,+lahf_lm,+sep \ + -m 2048 \ + -global 'PIIX4_PM.disable_s3=1' \ + -global 'PIIX4_PM.disable_s4=1' \ + -device 'pci-bridge,id=pci.1,chassis_nr=1,bus=pci.0,addr=0x1e' \ + -device 'pci-bridge,id=pci.2,chassis_nr=2,bus=pci.0,addr=0x1f' \ + -device 'pci-bridge,id=pci.4,chassis_nr=4,bus=pci.1,addr=0x1c' \ + -device 'vmgenid,guid=c773c261-d800-4348-9f5d-167fadd53cf8' \ + -device 'piix3-usb-uhci,id=uhci,bus=pci.0,addr=0x1.0x2' \ + -device 'usb-tablet,id=tablet,bus=uhci.0,port=1' \ + -device 'virtio-vga,id=vga,max_outputs=2,bus=pci.0,addr=0x2' \ + -device 'virtio-serial,id=spice,bus=pci.0,addr=0x9' \ + -chardev 'spicevmc,id=vdagent,name=vdagent' \ + -device 'virtserialport,chardev=vdagent,name=com.redhat.spice.0' \ + -spice 'tls-port=61000,addr=127.0.0.1,tls-ciphers=HIGH,seamless-migration=on' \ + -device 'virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3,free-page-reporting=on' \ + -iscsi 'initiator-name=iqn.1993-08.org.debian:01:aabbccddeeff' \ + -netdev 'type=tap,id=net0,ifname=tap8006i0,script=/usr/libexec/qemu-server/pve-bridge,downscript=/usr/libexec/qemu-server/pve-bridgedown,vhost=on' \ + -device 'virtio-net-pci,mac=A2:C0:43:67:08:A1,netdev=net0,bus=pci.0,addr=0x12,id=net0,rx_queue_size=1024,tx_queue_size=256,bootindex=300,host_mtu=1500,host_tunnel=off' \ + -machine 'hpet=off,type=pc+pve0' -- 2.43.0