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 | 68 +++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/PVE/HardwareMap.pm b/src/PVE/HardwareMap.pm index 7a90220..4a322ff 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.", @@ -212,37 +214,47 @@ sub write_hardware_map { my $pci_valid = sub { my ($cfg) = @_; - if ($path !~ m/\.[a-f0-9]/i) { - # whole device, add .0 (must exist) - $path = "$path.0"; - } + 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 $correct_props = { - vendor => $info->{vendor}, - device => $info->{device}, - 'subsystem-vendor' => $info->{'subsystem_vendor'}, - 'subsystem-device' => $info->{'subsystem_device'}, - mdev => $info->{mdev}, - iommugroup => $info->{iommugroup}, - }; + my $idx = 0; + for my $path (@paths) { - 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}); + if ($path !~ m/\.[a-f0-9]/i) { + # whole device, add .0 (must exist) + $path = "$path.0"; + } - my $correct_prop = $correct_props->{$prop}; - $correct_prop =~ s/^0x//; - my $configured_prop = $cfg->{$prop}; - $configured_prop =~ s/^0x//; + my $info = PVE::SysFSTools::pci_device_info($path, 1); + die "pci device '$path' not found\n" if !defined($info); + + my $correct_props = { + vendor => $info->{vendor}, + device => $info->{device}, + 'subsystem-vendor' => $info->{'subsystem_vendor'}, + 'subsystem-device' => $info->{'subsystem_device'}, + mdev => $info->{mdev}, + iommugroup => $info->{iommugroup}, + }; - die "'$prop' does not match for '$cfg->{name}' ($correct_prop != $configured_prop)\n" - if $correct_prop ne $configured_prop; + for my $prop (sort keys %$correct_props) { + next if $prop eq 'iommugroup' && $idx > 0; # check iommu only on the first device + + 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_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