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