[pve-devel] [PATCH 2/3] add pci multifunction support

Alexandre Derumier aderumier at odiso.com
Mon Jun 23 17:41:54 CEST 2014


multifunction device should be define without the .function

hostpci0: 00:00

example
-------
if 00:00.0
   00:00.1
   00:00.2

exists,

then we generate the multifunction devices

-device (pci-assign|vfio-pci),host=00:00.0,id=hostpci0.0,bus=...,addr=0x0.0,multifunction=on
-device (pci-assign|vfio-pci),host=00:00.1,id=hostpci0.1,bus=...,addr=0x0.1
-device (pci-assign|vfio-pci),host=00:00.2,id=hostpci0.2,bus=...,addr=0x0.2

Signed-off-by: Alexandre Derumier <aderumier at odiso.com>
---
 PVE/QemuServer.pm |   44 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm
index 597d013..3041dd5 100644
--- a/PVE/QemuServer.pm
+++ b/PVE/QemuServer.pm
@@ -22,7 +22,7 @@ use PVE::SafeSyslog;
 use Storable qw(dclone);
 use PVE::Exception qw(raise raise_param_exc);
 use PVE::Storage;
-use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline);
+use PVE::Tools qw(run_command lock_file lock_file_full file_read_firstline dir_glob_foreach);
 use PVE::JSONSchema qw(get_standard_option);
 use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
 use PVE::INotify;
@@ -1267,9 +1267,15 @@ sub parse_hostpci {
     my $res = {};
     foreach my $kv (@list) {
 
-	if ($kv =~ m/^(host=)?([a-f0-9]{2}:[a-f0-9]{2}\.[a-f0-9])$/) {
+	if ($kv =~ m/^(host=)?([a-f0-9]{2}:[a-f0-9]{2})(\.([a-f0-9]))?$/) {
 	    $found = 1;
-	    $res->{pciid} = $2;
+	    if(defined($4)){
+		push @{$res->{pciid}}, { id => $2 , function => $4};
+
+	    }else{
+		my $pcidevices = lspci($2);
+	        $res->{pciid} = $pcidevices->{$2};
+	    }
 	} elsif ($kv =~ m/^driver=(kvm|vfio)$/) {
 	    $res->{driver} = $1;
 	} elsif ($kv =~ m/^rombar=(on|off)$/) {
@@ -2430,9 +2436,26 @@ sub config_to_command {
 	my $driver = $d->{driver} && $d->{driver} eq 'vfio' ? "vfio-pci" : "pci-assign";
 	my $xvga = $d->{'x-vga'} && $d->{'x-vga'} eq 'on' ? ",x-vga=on" : "";
 	$driver = "vfio-pci" if $xvga ne '';
+	my $pcidevices = $d->{pciid};
+	my $multifunction = 1 if @$pcidevices > 1;
 
-	push @$devices, '-device', "$driver,host=$d->{pciid},id=hostpci$i$pciaddr$rombar$xvga";
+	my $j=0;
+        foreach my $pcidevice (@$pcidevices) {
 
+	    my $id = "hostpci$i";
+	    $id .= ".$j" if $multifunction;
+	    my $addr = $pciaddr;
+	    $addr .= ".$j" if $multifunction;
+	    my $devicestr = "$driver,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr";
+
+	    if($j == 0){
+		$devicestr .= "$rombar$xvga";
+		$devicestr .= ",multifunction=on" if $multifunction;
+	    }
+
+	    push @$devices, '-device', $devicestr;
+	    $j++;
+	}
     }
 
     # usb devices
@@ -5167,4 +5190,17 @@ sub get_current_qemu_machine {
     return $current || $default || 'pc';
 }
 
+sub lspci {
+
+    my $devices = {};
+
+    dir_glob_foreach("$pcisysfs/devices", '[a-f0-9]{4}:([a-f0-9]{2}:[a-f0-9]{2})\.([0-9])', sub {
+            my (undef, $id, $function) = @_;
+	    my $res = { id => $id, function => $function};
+	    push @{$devices->{$id}}, $res;
+    });
+
+    return $devices;
+}
+
 1;
-- 
1.7.10.4




More information about the pve-devel mailing list