On Sun, 19 May 2019 at 09:30, James Courtier-Dutton <james.dut...@gmail.com>
wrote:

> Hi,
>
> I have a PC with two identical GPUs.
> One I wish to hand over to vfio and do passthru with, the other I wish the
> host to use.
> I know about commands like:
> echo 1002 687f  >/sys/bus/pci/drivers/vfio-pci/new_id
>
> But those will cause both GPUs to be claimed by vfio.
> I would prefer to do it by slot, e.g. echo 09:00.0
> >/sys/bus/pci/drivers/vfio-pci/new_id
> But, I cannot see how to do it by slot instead of PCI-ID.
>
>
How about something like the attached:
It lets you future filter down what vfio-pci will claim by entering them as
module options.
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 3fa20e95a6bb..c85567c5ef94 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -40,6 +40,10 @@ static char ids[1024] __initdata;
 module_param_string(ids, ids, sizeof(ids), 0);
 MODULE_PARM_DESC(ids, "Initial PCI IDs to add to the vfio driver, format is \"vendor:device[:subvendor[:subdevice[:class[:class_mask]]]]\" and multiple comma separated entries can be specified");
 
+static char slots[1024];
+module_param_string(slots, slots, sizeof(slots), 0);
+MODULE_PARM_DESC(slots, "After selecting the PCI devices by PCI IDs, further filter down and only select these PCI SLOTS to add to the vfio driver, format is \"bus:slot.function\" and multiple comma separated entries can be specified");
+
 static bool nointxmask;
 module_param_named(nointxmask, nointxmask, bool, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(nointxmask,
@@ -1286,12 +1290,57 @@ static const struct vfio_device_ops vfio_pci_ops = {
 static int vfio_pci_reflck_attach(struct vfio_pci_device *vdev);
 static void vfio_pci_reflck_put(struct vfio_pci_reflck *reflck);
 
+static int vfio_pci_filter_slots(int bus, int slot, int func) {
+	char *p, *id;
+	/* no slots passed actually */
+	if (slots[0] == '\0') {
+		return 0;
+	}
+
+	/* add ids specified in the module parameter */
+	p = slots;
+	while ((id = strsep(&p, ","))) {
+		int bus1, slot1, func1;
+		int fields;
+
+		if (!strlen(id))
+			continue;
+
+		fields = sscanf(id, "%x:%x.%x",
+				&bus1, &slot1, &func1);
+
+		if (fields < 3) {
+			pr_warn("invalid id string \"%s\"\n", id);
+			continue;
+		}
+		if ((bus == bus1) && (slot == slot1) && (func == func1)) {
+			return 0;
+		}
+	}
+	return -ENODEV;
+}
+
 static int vfio_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	struct vfio_pci_device *vdev;
 	struct iommu_group *group;
 	int ret;
+	int bus = 0;
+	int slot = 0;
+	int func = 0;
+
+	if (pdev->bus) {
+		//pr_info("pdev->bus->number = %d\n", pdev->bus->number);
+		bus = pdev->bus->number;
+	}
+	slot = PCI_SLOT(pdev->devfn);
+	func = PCI_FUNC(pdev->devfn);
 
+	ret = vfio_pci_filter_slots(bus, slot, func);
+	if (ret)  {
+		pr_info("Skipping slot %02x:%02x.%x\n", bus, slot, func);
+		return ret;
+	}
 	if (pdev->hdr_type != PCI_HEADER_TYPE_NORMAL)
 		return -EINVAL;
 
_______________________________________________
vfio-users mailing list
vfio-users@redhat.com
https://www.redhat.com/mailman/listinfo/vfio-users

Reply via email to