With this, we can now tell qemu-server to choose the first avaiable devices, which makes using vGPUs and SR-IOV capable devices much easier to use, since the user does not have to hardcode the device, but can give a list of identical ones, and qemu-server chooses dynamically.
note that we require the devices all to be the same vendor/device, because we don't want to group unrelated devices, but we only check the iommugroup for the first device, but there is a high chance that this also changes when somethings off since e.g. SRIOV devices are most often created at the same time, so when the any has a different group, the first one will too Signed-off-by: Dominik Csapak <d.csa...@proxmox.com> --- src/PVE/HardwareMap.pm | 71 ++++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 30 deletions(-) diff --git a/src/PVE/HardwareMap.pm b/src/PVE/HardwareMap.pm index 31841b4..52c45e1 100644 --- a/src/PVE/HardwareMap.pm +++ b/src/PVE/HardwareMap.pm @@ -84,9 +84,11 @@ my $format = { }, path => { description => "The path to the device. If the function is omitted, the whole device is" - ." mapped. In that case use the attributes of the first device.", + ." mapped. In that case use the attributes of the first device. You can give" + ." multiple paths as a semicolon seperated list, the first available will then" + ." be chosen on guest start.", type => 'string', - pattern => "${PCI_RE}", + pattern => "(?:${PCI_RE};)*${PCI_RE}", }, mdev => { description => "The Device supports mediated devices.", @@ -213,39 +215,48 @@ sub write_hardware_map { my $pci_valid = sub { my ($cfg) = @_; - my $multifunction = 0; - if ($path !~ m/\.[a-f0-9]/i) { - # whole device, add .0 (must exist) - $path = "$path.0"; - $multifunction = 1; - } + my @paths = split(';', $cfg->{path} // ''); - my $info = PVE::SysFSTools::pci_device_info($path, 1); - die "pci device '$path' not found\n" if !defined($info); + my $idx = 0; + for my $path (@paths) { - my $correct_props = { - vendor => $info->{vendor}, - device => $info->{device}, - 'subsystem-vendor' => $info->{'subsystem_vendor'}, - 'subsystem-device' => $info->{'subsystem_device'}, - mdev => $multifunction ? undef : $info->{mdev}, # don't allow mdev for multifunction - iommugroup => $info->{iommugroup}, - }; + my $multifunction = 0; + if ($path !~ m/\.[a-f0-9]/i) { + # whole device, add .0 (must exist) + $path = "$path.0"; + $multifunction = 1; + } + + my $info = PVE::SysFSTools::pci_device_info($path, 1); + die "pci device '$path' not found\n" if !defined($info); - for my $prop (sort keys %$correct_props) { - next if !defined($correct_props->{$prop}) && !defined($cfg->{$prop}); - die "no '$prop' for device '$path'\n" - if defined($correct_props->{$prop}) && !defined($cfg->{$prop}); - die "'$prop' configured but should not be\n" - if !defined($correct_props->{$prop}) && defined($cfg->{$prop}); + my $correct_props = { + vendor => $info->{vendor}, + device => $info->{device}, + 'subsystem-vendor' => $info->{'subsystem_vendor'}, + 'subsystem-device' => $info->{'subsystem_device'}, + mdev => $multifunction ? undef : $info->{mdev}, # don't allow mdev for multifunction + iommugroup => $info->{iommugroup}, + }; + + for my $prop (sort keys %$correct_props) { + next if $prop eq 'iommugroup' && $idx > 0; # check iommu only on the first device - my $correct_prop = $correct_props->{$prop}; - $correct_prop =~ s/^0x//; - my $configured_prop = $cfg->{$prop}; - $configured_prop =~ s/^0x//; + next if !defined($correct_props->{$prop}) && !defined($cfg->{$prop}); + die "no '$prop' for device '$path'\n" + if defined($correct_props->{$prop}) && !defined($cfg->{$prop}); + die "'$prop' configured but should not be\n" + if !defined($correct_props->{$prop}) && defined($cfg->{$prop}); - die "'$prop' does not match for '$cfg->{name}' ($correct_prop != $configured_prop)\n" - if $correct_prop ne $configured_prop; + my $correct_prop = $correct_props->{$prop}; + $correct_prop =~ s/^0x//; + my $configured_prop = $cfg->{$prop}; + $configured_prop =~ s/^0x//; + + die "'$prop' does not match for '$cfg->{name}' ($correct_prop != $configured_prop)\n" + if $correct_prop ne $configured_prop; + } + $idx++; } return 1; -- 2.30.2 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel