From b71351a7ed19c1e1c5f6d05807c473b364196cb5 Mon Sep 17 00:00:00 2001 From: Dominik Csapak Date: Fri, 16 Nov 2018 16:17:51 +0100 Subject: [PATCH] QemuServer: remove PCI sysfs helpers and use them from PVE::SysFSTools, where they got moved to Signed-off-by: Dominik Csapak --- PVE/QemuServer.pm | 158 +++--------------------------------------- PVE/QemuServer/PCI.pm | 2 + 2 files changed, 10 insertions(+), 150 deletions(-) diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 035d8b7..b69cffa 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -34,6 +34,7 @@ use PVE::QemuServer::PCI qw(print_pci_addr print_pcie_addr); use PVE::QemuServer::Memory; use PVE::QemuServer::USB qw(parse_usb_device); use PVE::QemuServer::Cloudinit; +use PVE::SysFSTools; use PVE::Systemd; use Time::HiRes qw(gettimeofday); use File::Copy qw(copy); @@ -2106,7 +2107,7 @@ sub parse_hostpci { if (defined($2)) { push @{$res->{pciid}}, { id => $1, function => $2 }; } else { - my $pcidevices = lspci($1); + my $pcidevices = PVE::SysFSTools::lspci($1); $res->{pciid} = $pcidevices->{$1}; } } else { @@ -2455,15 +2456,6 @@ sub check_type { } } -sub check_iommu_support{ - #fixme : need to check IOMMU support - #http://www.linux-kvm.org/page/How_to_assign_devices_with_VT-d_in_KVM - - my $iommu=1; - return $iommu; - -} - sub touch_config { my ($vmid) = @_; @@ -5149,11 +5141,13 @@ sub vm_start { foreach my $pcidevice (@$pcidevices) { my $pciid = $pcidevice->{id}.".".$pcidevice->{function}; - my $info = pci_device_info("0000:$pciid"); - die "IOMMU not present\n" if !check_iommu_support(); + my $info = PVE::SysFSTools::pci_device_info("0000:$pciid"); + die "IOMMU not present\n" if !PVE::SysFSTools::check_iommu_support(); die "no pci device info for device '$pciid'\n" if !$info; - die "can't unbind/bind pci group to vfio '$pciid'\n" if !pci_dev_group_bind_to_vfio($pciid); - die "can't reset pci device '$pciid'\n" if $info->{has_fl_reset} and !pci_dev_reset($info); + die "can't unbind/bind pci group to vfio '$pciid'\n" + if !PVE::SysFSTools::pci_dev_group_bind_to_vfio($pciid); + die "can't reset pci device '$pciid'\n" + if $info->{has_fl_reset} and !PVE::SysFSTools::pci_dev_reset($info); } } @@ -5558,123 +5552,6 @@ sub vm_destroy { }); } -# pci helpers - -sub file_write { - my ($filename, $buf) = @_; - - my $fh = IO::File->new($filename, "w"); - return undef if !$fh; - - my $res = print $fh $buf; - - $fh->close(); - - return $res; -} - -sub pci_device_info { - my ($name) = @_; - - my $res; - - return undef if $name !~ m/^([a-f0-9]{4}):([a-f0-9]{2}):([a-f0-9]{2})\.([a-f0-9])$/; - my ($domain, $bus, $slot, $func) = ($1, $2, $3, $4); - - my $irq = file_read_firstline("$pcisysfs/devices/$name/irq"); - return undef if !defined($irq) || $irq !~ m/^\d+$/; - - my $vendor = file_read_firstline("$pcisysfs/devices/$name/vendor"); - return undef if !defined($vendor) || $vendor !~ s/^0x//; - - my $product = file_read_firstline("$pcisysfs/devices/$name/device"); - return undef if !defined($product) || $product !~ s/^0x//; - - $res = { - name => $name, - vendor => $vendor, - product => $product, - domain => $domain, - bus => $bus, - slot => $slot, - func => $func, - irq => $irq, - has_fl_reset => -f "$pcisysfs/devices/$name/reset" || 0, - }; - - return $res; -} - -sub pci_dev_reset { - my ($dev) = @_; - - my $name = $dev->{name}; - - my $fn = "$pcisysfs/devices/$name/reset"; - - return file_write($fn, "1"); -} - -sub pci_dev_bind_to_vfio { - my ($dev) = @_; - - my $name = $dev->{name}; - - my $vfio_basedir = "$pcisysfs/drivers/vfio-pci"; - - if (!-d $vfio_basedir) { - system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null"); - } - die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir; - - my $testdir = "$vfio_basedir/$name"; - return 1 if -d $testdir; - - my $data = "$dev->{vendor} $dev->{product}"; - return undef if !file_write("$vfio_basedir/new_id", $data); - - my $fn = "$pcisysfs/devices/$name/driver/unbind"; - if (!file_write($fn, $name)) { - return undef if -f $fn; - } - - $fn = "$vfio_basedir/bind"; - if (! -d $testdir) { - return undef if !file_write($fn, $name); - } - - return -d $testdir; -} - -sub pci_dev_group_bind_to_vfio { - my ($pciid) = @_; - - my $vfio_basedir = "$pcisysfs/drivers/vfio-pci"; - - if (!-d $vfio_basedir) { - system("/sbin/modprobe vfio-pci >/dev/null 2>/dev/null"); - } - die "Cannot find vfio-pci module!\n" if !-d $vfio_basedir; - - # get IOMMU group devices - opendir(my $D, "$pcisysfs/devices/0000:$pciid/iommu_group/devices/") || die "Cannot open iommu_group: $!\n"; - my @devs = grep /^0000:/, readdir($D); - closedir($D); - - foreach my $pciid (@devs) { - $pciid =~ m/^([:\.\da-f]+)$/ or die "PCI ID $pciid not valid!\n"; - - # pci bridges, switches or root ports are not supported - # they have a pci_bus subdirectory so skip them - next if (-e "$pcisysfs/devices/$pciid/pci_bus"); - - my $info = pci_device_info($1); - pci_dev_bind_to_vfio($info) || die "Cannot bind $pciid to vfio\n"; - } - - return 1; -} - # vzdump restore implementaion sub tar_archive_read_firstfile { @@ -6878,25 +6755,6 @@ sub create_efidisk($$$$$) { return ($volid, $vars_size); } -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; - }); - - # Entries should be sorted by functions. - foreach my $id (keys %$devices) { - my $dev = $devices->{$id}; - $devices->{$id} = [ sort { $a->{function} <=> $b->{function} } @$dev ]; - } - - return $devices; -} - sub vm_iothreads_list { my ($vmid) = @_; diff --git a/PVE/QemuServer/PCI.pm b/PVE/QemuServer/PCI.pm index 1641c28..29b8943 100644 --- a/PVE/QemuServer/PCI.pm +++ b/PVE/QemuServer/PCI.pm @@ -155,3 +155,5 @@ sub print_pcie_addr { return $res; } + +1; -- 2.39.2