From: Dominik Csapak Date: Tue, 20 Nov 2018 16:13:39 +0000 (+0100) Subject: add mediated devices support X-Git-Url: https://git.proxmox.com/?p=qemu-server.git;a=commitdiff_plain;h=6ab45bd7ff8418abe00861df74ff85dfe244a108 add mediated devices support with this, we are able to create and use mediated devices, which include Intel GVT-g (aka KVMGT) and Nvidia vGPUs, and probably more types of devices in the future Signed-off-by: Dominik Csapak --- diff --git a/PVE/QemuServer.pm b/PVE/QemuServer.pm index 8023150..38f3a05 100644 --- a/PVE/QemuServer.pm +++ b/PVE/QemuServer.pm @@ -1244,6 +1244,17 @@ EODESCR optional => 1, default => 0, }, + 'mdev' => { + type => 'string', + format_description => 'string', + pattern => '[^/\.:]+', + optional => 1, + description => <{pciid}; my $multifunction = 1 if @$pcidevices > 1; + my $sysfspath; + if ($d->{mdev} && scalar(@$pcidevices) == 1) { + my $id = $pcidevices->[0]->{id}; + my $function = $pcidevices->[0]->{function}; + my $uuid = PVE::SysFSTools::generate_mdev_uuid($vmid, $i); + $sysfspath = "/sys/bus/pci/devices/0000:$id.$function/$uuid"; + } elsif ($d->{mdev}) { + warn "ignoring mediated device with multifunction device\n"; + } my $j=0; foreach my $pcidevice (@$pcidevices) { @@ -3547,7 +3567,13 @@ sub config_to_command { $id .= ".$j" if $multifunction; my $addr = $pciaddr; $addr .= ".$j" if $multifunction; - my $devicestr = "vfio-pci,host=$pcidevice->{id}.$pcidevice->{function},id=$id$addr"; + my $devicestr = "vfio-pci"; + if ($sysfspath) { + $devicestr .= ",sysfsdev=$sysfspath"; + } else { + $devicestr .= ",host=$pcidevice->{id}.$pcidevice->{function}"; + } + $devicestr .= ",id=$id$addr"; if($j == 0){ $devicestr .= "$rombar$xvga"; @@ -5142,10 +5168,16 @@ sub vm_start { 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 !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); + + if ($d->{mdev}) { + my $uuid = PVE::SysFSTools::generate_mdev_uuid($vmid, $i); + PVE::SysFSTools::pci_create_mdev_device($pciid, $uuid, $d->{mdev}); + } else { + 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); + } } } @@ -5385,6 +5417,18 @@ sub vm_stop_cleanup { unlink "/var/run/qemu-server/${vmid}.$ext"; } + foreach my $key (keys %$conf) { + next if $key !~ m/^hostpci(\d+)$/; + my $hostpciindex = $1; + my $d = parse_hostpci($conf->{$key}); + my $uuid = PVE::SysFSTools::generate_mdev_uuid($vmid, $hostpciindex); + + foreach my $pci (@{$d->{pciid}}) { + my $pciid = $pci->{id} . "." . $pci->{function}; + PVE::SysFSTools::pci_cleanup_mdev_device($pciid, $uuid); + } + } + vmconfig_apply_pending($vmid, $conf, $storecfg) if $apply_pending_changes; }; warn $@ if $@; # avoid errors - just warn