Skip to content

Commit 3f0c625

Browse files
lsgunthjoergroedel
authored andcommitted
iommu/vt-d: Allow interrupts from the entire bus for aliased devices
When a device has multiple aliases that all are from the same bus, we program the IRTE to accept requests from any matching device on the bus. This is so NTB devices which can have requests from multiple bus-devfns can pass MSI interrupts through across the bridge. Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Cc: David Woodhouse <dwmw2@infradead.org> Cc: Joerg Roedel <joro@8bytes.org> Cc: Jacob Pan <jacob.jun.pan@linux.intel.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
1 parent 9ca8261 commit 3f0c625

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

drivers/iommu/intel_irq_remapping.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,8 @@ static int set_hpet_sid(struct irte *irte, u8 id)
368368
struct set_msi_sid_data {
369369
struct pci_dev *pdev;
370370
u16 alias;
371+
int count;
372+
int busmatch_count;
371373
};
372374

373375
static int set_msi_sid_cb(struct pci_dev *pdev, u16 alias, void *opaque)
@@ -376,6 +378,10 @@ static int set_msi_sid_cb(struct pci_dev *pdev, u16 alias, void *opaque)
376378

377379
data->pdev = pdev;
378380
data->alias = alias;
381+
data->count++;
382+
383+
if (PCI_BUS_NUM(alias) == pdev->bus->number)
384+
data->busmatch_count++;
379385

380386
return 0;
381387
}
@@ -387,6 +393,8 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev)
387393
if (!irte || !dev)
388394
return -1;
389395

396+
data.count = 0;
397+
data.busmatch_count = 0;
390398
pci_for_each_dma_alias(dev, set_msi_sid_cb, &data);
391399

392400
/*
@@ -395,6 +403,11 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev)
395403
* device is the case of a PCIe-to-PCI bridge, where the alias is for
396404
* the subordinate bus. In this case we can only verify the bus.
397405
*
406+
* If there are multiple aliases, all with the same bus number,
407+
* then all we can do is verify the bus. This is typical in NTB
408+
* hardware which use proxy IDs where the device will generate traffic
409+
* from multiple devfn numbers on the same bus.
410+
*
398411
* If the alias device is on a different bus than our source device
399412
* then we have a topology based alias, use it.
400413
*
@@ -405,6 +418,8 @@ static int set_msi_sid(struct irte *irte, struct pci_dev *dev)
405418
if (PCI_BUS_NUM(data.alias) != data.pdev->bus->number)
406419
set_irte_verify_bus(irte, PCI_BUS_NUM(data.alias),
407420
dev->bus->number);
421+
else if (data.count >= 2 && data.busmatch_count == data.count)
422+
set_irte_verify_bus(irte, dev->bus->number, dev->bus->number);
408423
else if (data.pdev->bus->number != dev->bus->number)
409424
set_irte_sid(irte, SVT_VERIFY_SID_SQ, SQ_ALL_16, data.alias);
410425
else

0 commit comments

Comments
 (0)