+sub pci_create_mdev_device {
+ my ($pciid, $uuid, $type) = @_;
+
+ my $basedir = "$pcisysfs/devices/0000:$pciid";
+ my $mdev_dir = "$basedir/mdev_supported_types";
+
+ die "pci device '$pciid' does not support mediated devices \n"
+ if !-d $mdev_dir;
+
+ die "pci device '$pciid' has no type '$type'\n"
+ if !-d "$mdev_dir/$type";
+
+ if (-d "$basedir/$uuid") {
+ # it already exists, checking type
+ my $typelink = readlink("$basedir/$uuid/mdev_type");
+ my ($existingtype) = $typelink =~ m|/([^/]+)$|;
+ die "mdev instance '$uuid' already exits, but type is not '$type'\n"
+ if $type ne $existingtype;
+
+ # instance exists, so use it but warn the user
+ warn "mdev instance '$uuid' already existed, using it.\n";
+ return undef;
+ }
+
+ my $instances = file_read_firstline("$mdev_dir/$type/available_instances");
+ my ($avail) = $instances =~ m/^(\d+)$/;
+ die "pci device '$pciid' has no available instances of '$type'\n"
+ if $avail < 1;
+
+ die "could not create 'type' for pci devices '$pciid'\n"
+ if !file_write("$mdev_dir/$type/create", $uuid);
+
+ return undef;
+}
+
+sub pci_cleanup_mdev_device {
+ my ($pciid, $uuid) = @_;
+
+ my $basedir = "$pcisysfs/devices/0000:$pciid/$uuid";
+
+ if (! -e $basedir) {
+ return 1; # no cleanup necessary if it does not exist
+ }
+
+ return file_write("$basedir/remove", "1");
+}
+
+# encode the hostpci index and vmid into the uuid
+sub generate_mdev_uuid {
+ my ($vmid, $index) = @_;
+
+ my $string = sprintf("%08d-0000-0000-0000-%012d", $index, $vmid);
+
+ return $string;
+}
+