Skip to content

Commit ff82872

Browse files
committed
iommu/vt-d: Cure VF irqdomain hickup
The recent changes to store the MSI irqdomain pointer in struct device missed that Intel DMAR does not register virtual function devices. Due to that a VF device gets the plain PCI-MSI domain assigned and then issues compat MSI messages which get caught by the interrupt remapping unit. Cure that by inheriting the irq domain from the physical function device. Ideally the irqdomain would be associated to the bus, but DMAR can have multiple units and therefore irqdomains on a single bus. The VF 'bus' could of course inherit the domain from the PF, but that'd be yet another x86 oddity. Fixes: 85a8dfc ("iommm/vt-d: Store irq domain in struct device") Reported-by: Jason Gunthorpe <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Lu Baolu <[email protected]> Cc: Joerg Roedel <[email protected]> Cc: Bjorn Helgaas <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: David Woodhouse <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 77c7e1b commit ff82872

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

drivers/iommu/intel/dmar.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ static void dmar_pci_bus_del_dev(struct dmar_pci_notify_info *info)
333333
dmar_iommu_notify_scope_dev(info);
334334
}
335335

336+
static inline void vf_inherit_msi_domain(struct pci_dev *pdev)
337+
{
338+
dev_set_msi_domain(&pdev->dev, dev_get_msi_domain(&pdev->physfn->dev));
339+
}
340+
336341
static int dmar_pci_bus_notifier(struct notifier_block *nb,
337342
unsigned long action, void *data)
338343
{
@@ -342,8 +347,20 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb,
342347
/* Only care about add/remove events for physical functions.
343348
* For VFs we actually do the lookup based on the corresponding
344349
* PF in device_to_iommu() anyway. */
345-
if (pdev->is_virtfn)
350+
if (pdev->is_virtfn) {
351+
/*
352+
* Ensure that the VF device inherits the irq domain of the
353+
* PF device. Ideally the device would inherit the domain
354+
* from the bus, but DMAR can have multiple units per bus
355+
* which makes this impossible. The VF 'bus' could inherit
356+
* from the PF device, but that's yet another x86'sism to
357+
* inflict on everybody else.
358+
*/
359+
if (action == BUS_NOTIFY_ADD_DEVICE)
360+
vf_inherit_msi_domain(pdev);
346361
return NOTIFY_DONE;
362+
}
363+
347364
if (action != BUS_NOTIFY_ADD_DEVICE &&
348365
action != BUS_NOTIFY_REMOVED_DEVICE)
349366
return NOTIFY_DONE;

0 commit comments

Comments
 (0)