[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