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 0E1FE1FF0DF for ; Thu, 15 Oct 2026 09:55:04 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id DE5F721656; Thu, 15 Oct 2026 09:54:34 +0200 (CEST) From: Dominik Csapak To: pve-devel@lists.proxmox.com Subject: [PATCH qemu-server 3/5] net: use version guard for the machine version checks of NICs Date: Thu, 15 Oct 2026 09:52:17 +0200 Message-ID: <20261015075428.572882-4-d.csapak@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261015075428.572882-1-d.csapak@proxmox.com> References: <20261015075428.572882-1-d.csapak@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.369 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust 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: C3TSWDVG2ZPHBCIFR5VH2O2W2MKLEOJH X-Message-ID-Hash: C3TSWDVG2ZPHBCIFR5VH2O2W2MKLEOJH X-MailFrom: d.csapak@proxmox.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: Since commit 41734ab8 ("fix #7627: net: virtio: disable host_tunnel feature again with 11.0+pve1"), VirtIO NICs get 'host_tunnel=off' with machine version 11.0+pve1 and newer. The check uses min_version, which does not record the required PVE machine revision. So a guest started with an unversioned machine type on QEMU 11.0 got 'host_tunnel=off', but its machine type was recorded as '+pve0'. Migration, snapshots and hibernation then use that recorded machine type, for which the NIC is generated without 'host_tunnel=off'. The checks in print_netdevice_full could not use the version guard, since the function is also called for hotplug, where there is none. The 'host_mtu' differentiation for 10.0+pve1 works around that with a separate guard call in config_to_command. Instead, pass the version guard to print_netdevice_full and use it for all of its machine version checks, so the required revision gets recorded where the feature is decided. For hotplug, pass a stub around min_version, as the machine is already running there. The separate guard call for 'host_mtu' is kept, as it also records '+pve1' for NICs that skip the 'host_mtu' check, for example when it is omitted for migration compatibility. Signed-off-by: Dominik Csapak --- src/PVE/QemuServer.pm | 23 ++++++++++++-------- src/test/cfg2cmd/simple-11.0-binary.conf.cmd | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/PVE/QemuServer.pm b/src/PVE/QemuServer.pm index 097c88b6..39096199 100644 --- a/src/PVE/QemuServer.pm +++ b/src/PVE/QemuServer.pm @@ -1327,7 +1327,7 @@ sub print_netdevice_full { $netid, $use_old_bios_files, $arch, - $machine_version, + $version_guard, # checks the machine version and records the required +pveX revision $host_mtu_migration, # force this value for host_mtu, 0 means force absence of param ) = @_; @@ -1343,12 +1343,12 @@ sub print_netdevice_full { # and out of each queue plus one config interrupt and control vector queue my $vectors = $net->{queues} * 2 + 2; $tmpstr .= ",vectors=$vectors,mq=on"; - if (min_version($machine_version, 7, 1)) { + if ($version_guard->(7, 1)) { $tmpstr .= ",packed=on"; } } - if (min_version($machine_version, 7, 1) && $net->{model} eq 'virtio') { + if ($version_guard->(7, 1) && $net->{model} eq 'virtio') { $tmpstr .= ",rx_queue_size=1024,tx_queue_size=256"; } @@ -1378,7 +1378,7 @@ sub print_netdevice_full { . " that the bridge is configured as desired.\n"; } - if (min_version($machine_version, 10, 0, 1) || $host_mtu_migration) { + if ($version_guard->(10, 0, 1) || $host_mtu_migration) { # Always add host_mtu for migration compatibility, because the presence of host_mtu # means that the virtual hardware is generated differently (at least for i440fx) $tmpstr .= ",host_mtu=$mtu"; @@ -1390,7 +1390,7 @@ sub print_netdevice_full { if ($migration_skip_host_mtu) { # When the machine version is less than 10.0+pve1 and the MTU is 1500, not having the # host_mtu parameter is fully expected. Only log when not expected to avoid confusion. - if (min_version($machine_version, 10, 0, 1) || $mtu != 1500) { + if ($version_guard->(10, 0, 1) || $mtu != 1500) { log_warn( "$msg_prefix, not used on the source side according to migration parameters"); } @@ -1423,10 +1423,10 @@ sub print_netdevice_full { # include the fix "virtio_net: do not allow tunnel csum offload for non GSO packets" with a # prominent notice in the upgrade guide. if ($net->{model} eq 'virtio') { - if (min_version($machine_version, 11, 0, 1)) { + if ($version_guard->(11, 0, 1)) { # Turn off if not explicitly enabled starting with 11.0+pve1 $tmpstr .= ",host_tunnel=off" if !$net->{'host-tunnel'}; - } elsif (min_version($machine_version, 10, 2)) { + } elsif ($version_guard->(10, 2)) { # The feature was introduced in QEMU 10.2. Turn off if explicitly disabled. $tmpstr .= ",host_tunnel=off" if defined($net->{'host-tunnel'}) && !$net->{'host-tunnel'}; @@ -3705,7 +3705,7 @@ sub config_to_command { $netname, $use_old_bios_files, $arch, - $machine_version, + $version_guard, $nets_host_mtu->{$netname}, ); @@ -3949,8 +3949,13 @@ sub vm_deviceplug { my $use_old_bios_files = undef; ($use_old_bios_files, $machine_type) = qemu_use_old_bios_files($machine_type); + # the machine is already running, so there is no required version to record + my $version_guard = sub { + my ($major, $minor, $pve) = @_; + return min_version($machine_version, $major, $minor, $pve); + }; my $netdevicefull = print_netdevice_full( - $vmid, $conf, $device, $deviceid, $use_old_bios_files, $arch, $machine_version, + $vmid, $conf, $device, $deviceid, $use_old_bios_files, $arch, $version_guard, ); qemu_deviceadd($vmid, $netdevicefull); eval { diff --git a/src/test/cfg2cmd/simple-11.0-binary.conf.cmd b/src/test/cfg2cmd/simple-11.0-binary.conf.cmd index 924d8041..5d01263e 100644 --- a/src/test/cfg2cmd/simple-11.0-binary.conf.cmd +++ b/src/test/cfg2cmd/simple-11.0-binary.conf.cmd @@ -32,4 +32,4 @@ -device 'scsi-hd,bus=scsihw0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0,id=scsi0,device_id=drive-scsi0,bootindex=100,write-cache=on' \ -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:77:08:A0,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' + -machine 'hpet=off,type=pc+pve1' -- 2.47.3