struct pci_dev *pdev = to_pci_dev(data);
        struct dmar_pci_notify_info *info;
 
-       /* Only care about add/remove events for physical functions */
+       /* Only care about add/remove events for physical functions.
+        * For VFs we actually do the lookup based on the corresponding
+        * PF in device_to_iommu() anyway. */
        if (pdev->is_virtfn)
                return NOTIFY_DONE;
        if (action != BUS_NOTIFY_ADD_DEVICE &&
 
                return NULL;
 
        if (dev_is_pci(dev)) {
+               struct pci_dev *pf_pdev;
+
                pdev = to_pci_dev(dev);
+               /* VFs aren't listed in scope tables; we need to look up
+                * the PF instead to find the IOMMU. */
+               pf_pdev = pci_physfn(pdev);
+               dev = &pf_pdev->dev;
                segment = pci_domain_nr(pdev->bus);
        } else if (has_acpi_companion(dev))
                dev = &ACPI_COMPANION(dev)->dev;
                for_each_active_dev_scope(drhd->devices,
                                          drhd->devices_cnt, i, tmp) {
                        if (tmp == dev) {
+                               /* For a VF use its original BDF# not that of the PF
+                                * which we used for the IOMMU lookup. Strictly speaking
+                                * we could do this for all PCI devices; we only need to
+                                * get the BDF# from the scope table for ACPI matches. */
+                               if (pdev->is_virtfn)
+                                       goto got_pdev;
+
                                *bus = drhd->devices[i].bus;
                                *devfn = drhd->devices[i].devfn;
                                goto out;