On Sun, 19 May 2019 at 09:30, James Courtier-Dutton <[email protected]>
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
[email protected]
https://www.redhat.com/mailman/listinfo/vfio-users