aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/iommu.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2014-09-19 12:03:06 -0400
committerJoerg Roedel <jroedel@suse.de>2014-09-25 10:39:06 -0400
commitf096c061f5525d1b35a65b793057b52061dcb486 (patch)
tree9d79f925e4fc7820ea39686bd0bef3eb757891e6 /drivers/iommu/iommu.c
parentd943b0ffba153cd63f836647b873b445842a2f58 (diff)
iommu: Rework iommu_group_get_for_pci_dev()
It turns out that our assumption that aliases are always to the same slot isn't true. One particular platform reports an IVRS alias of the SATA controller (00:11.0) for the legacy IDE controller (00:14.1). When we hit this, we attempt to use a single IOMMU group for everything on the same bus, which in this case is the root complex. We already have multiple groups defined for the root complex by this point, resulting in multiple WARN_ON hits. This patch makes these sorts of aliases work again with IOMMU groups by reworking how we search through the PCI address space to find existing groups. This should also now handle looped dependencies and all sorts of crazy inter-dependencies that we'll likely never see. The recursion used here should never be very deep. It's unlikely to have individual aliases and only theoretical that we'd ever see a chain where one alias causes us to search through to yet another alias. We're also only dealing with PCIe device on a single bus, which means we'll typically only see multiple slots in use on the root complex. Loops are also a theoretically possibility, which I've tested using fake DMA alias quirks and prevent from causing problems using a bitmap of the devfn space that's been visited. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Cc: stable@vger.kernel.org # 3.17 Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/iommu.c')
-rw-r--r--drivers/iommu/iommu.c163
1 files changed, 96 insertions, 67 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index d2d242fcaa3d..b59826aa5531 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -30,6 +30,7 @@
30#include <linux/notifier.h> 30#include <linux/notifier.h>
31#include <linux/err.h> 31#include <linux/err.h>
32#include <linux/pci.h> 32#include <linux/pci.h>
33#include <linux/bitops.h>
33#include <trace/events/iommu.h> 34#include <trace/events/iommu.h>
34 35
35static struct kset *iommu_group_kset; 36static struct kset *iommu_group_kset;
@@ -519,6 +520,9 @@ int iommu_group_id(struct iommu_group *group)
519} 520}
520EXPORT_SYMBOL_GPL(iommu_group_id); 521EXPORT_SYMBOL_GPL(iommu_group_id);
521 522
523static struct iommu_group *get_pci_alias_group(struct pci_dev *pdev,
524 unsigned long *devfns);
525
522/* 526/*
523 * To consider a PCI device isolated, we require ACS to support Source 527 * To consider a PCI device isolated, we require ACS to support Source
524 * Validation, Request Redirection, Completer Redirection, and Upstream 528 * Validation, Request Redirection, Completer Redirection, and Upstream
@@ -529,6 +533,86 @@ EXPORT_SYMBOL_GPL(iommu_group_id);
529 */ 533 */
530#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF) 534#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
531 535
536/*
537 * For multifunction devices which are not isolated from each other, find
538 * all the other non-isolated functions and look for existing groups. For
539 * each function, we also need to look for aliases to or from other devices
540 * that may already have a group.
541 */
542static struct iommu_group *get_pci_function_alias_group(struct pci_dev *pdev,
543 unsigned long *devfns)
544{
545 struct pci_dev *tmp = NULL;
546 struct iommu_group *group;
547
548 if (!pdev->multifunction || pci_acs_enabled(pdev, REQ_ACS_FLAGS))
549 return NULL;
550
551 for_each_pci_dev(tmp) {
552 if (tmp == pdev || tmp->bus != pdev->bus ||
553 PCI_SLOT(tmp->devfn) != PCI_SLOT(pdev->devfn) ||
554 pci_acs_enabled(tmp, REQ_ACS_FLAGS))
555 continue;
556
557 group = get_pci_alias_group(tmp, devfns);
558 if (group) {
559 pci_dev_put(tmp);
560 return group;
561 }
562 }
563
564 return NULL;
565}
566
567/*
568 * Look for aliases to or from the given device for exisiting groups. The
569 * dma_alias_devfn only supports aliases on the same bus, therefore the search
570 * space is quite small (especially since we're really only looking at pcie
571 * device, and therefore only expect multiple slots on the root complex or
572 * downstream switch ports). It's conceivable though that a pair of
573 * multifunction devices could have aliases between them that would cause a
574 * loop. To prevent this, we use a bitmap to track where we've been.
575 */
576static struct iommu_group *get_pci_alias_group(struct pci_dev *pdev,
577 unsigned long *devfns)
578{
579 struct pci_dev *tmp = NULL;
580 struct iommu_group *group;
581
582 if (test_and_set_bit(pdev->devfn & 0xff, devfns))
583 return NULL;
584
585 group = iommu_group_get(&pdev->dev);
586 if (group)
587 return group;
588
589 for_each_pci_dev(tmp) {
590 if (tmp == pdev || tmp->bus != pdev->bus)
591 continue;
592
593 /* We alias them or they alias us */
594 if (((pdev->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) &&
595 pdev->dma_alias_devfn == tmp->devfn) ||
596 ((tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN) &&
597 tmp->dma_alias_devfn == pdev->devfn)) {
598
599 group = get_pci_alias_group(tmp, devfns);
600 if (group) {
601 pci_dev_put(tmp);
602 return group;
603 }
604
605 group = get_pci_function_alias_group(tmp, devfns);
606 if (group) {
607 pci_dev_put(tmp);
608 return group;
609 }
610 }
611 }
612
613 return NULL;
614}
615
532struct group_for_pci_data { 616struct group_for_pci_data {
533 struct pci_dev *pdev; 617 struct pci_dev *pdev;
534 struct iommu_group *group; 618 struct iommu_group *group;
@@ -557,7 +641,7 @@ static struct iommu_group *iommu_group_get_for_pci_dev(struct pci_dev *pdev)
557 struct group_for_pci_data data; 641 struct group_for_pci_data data;
558 struct pci_bus *bus; 642 struct pci_bus *bus;
559 struct iommu_group *group = NULL; 643 struct iommu_group *group = NULL;
560 struct pci_dev *tmp; 644 u64 devfns[4] = { 0 };
561 645
562 /* 646 /*
563 * Find the upstream DMA alias for the device. A device must not 647 * Find the upstream DMA alias for the device. A device must not
@@ -591,76 +675,21 @@ static struct iommu_group *iommu_group_get_for_pci_dev(struct pci_dev *pdev)
591 } 675 }
592 676
593 /* 677 /*
594 * Next we need to consider DMA alias quirks. If one device aliases 678 * Look for existing groups on device aliases. If we alias another
595 * to another, they should be grouped together. It's theoretically 679 * device or another device aliases us, use the same group.
596 * possible that aliases could create chains of devices where each
597 * device aliases another device. If we then factor in multifunction
598 * ACS grouping requirements, each alias could incorporate a new slot
599 * with multiple functions, each with aliases. This is all extremely
600 * unlikely as DMA alias quirks are typically only used for PCIe
601 * devices where we usually have a single slot per bus. Furthermore,
602 * the alias quirk is usually to another function within the slot
603 * (and ACS multifunction is not supported) or to a different slot
604 * that doesn't physically exist. The likely scenario is therefore
605 * that everything on the bus gets grouped together. To reduce the
606 * problem space, share the IOMMU group for all devices on the bus
607 * if a DMA alias quirk is present on the bus.
608 */
609 tmp = NULL;
610 for_each_pci_dev(tmp) {
611 if (tmp->bus != pdev->bus ||
612 !(tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN))
613 continue;
614
615 pci_dev_put(tmp);
616 tmp = NULL;
617
618 /* We have an alias quirk, search for an existing group */
619 for_each_pci_dev(tmp) {
620 struct iommu_group *group_tmp;
621
622 if (tmp->bus != pdev->bus)
623 continue;
624
625 group_tmp = iommu_group_get(&tmp->dev);
626 if (!group) {
627 group = group_tmp;
628 continue;
629 }
630
631 if (group_tmp) {
632 WARN_ON(group != group_tmp);
633 iommu_group_put(group_tmp);
634 }
635 }
636
637 return group ? group : iommu_group_alloc();
638 }
639
640 /*
641 * Non-multifunction devices or multifunction devices supporting
642 * ACS get their own group.
643 */ 680 */
644 if (!pdev->multifunction || pci_acs_enabled(pdev, REQ_ACS_FLAGS)) 681 group = get_pci_alias_group(pdev, (unsigned long *)devfns);
645 return iommu_group_alloc(); 682 if (group)
683 return group;
646 684
647 /* 685 /*
648 * Multifunction devices not supporting ACS share a group with other 686 * Look for existing groups on non-isolated functions on the same
649 * similar devices in the same slot. 687 * slot and aliases of those funcions, if any. No need to clear
688 * the search bitmap, the tested devfns are still valid.
650 */ 689 */
651 tmp = NULL; 690 group = get_pci_function_alias_group(pdev, (unsigned long *)devfns);
652 for_each_pci_dev(tmp) { 691 if (group)
653 if (tmp == pdev || tmp->bus != pdev->bus || 692 return group;
654 PCI_SLOT(tmp->devfn) != PCI_SLOT(pdev->devfn) ||
655 pci_acs_enabled(tmp, REQ_ACS_FLAGS))
656 continue;
657
658 group = iommu_group_get(&tmp->dev);
659 if (group) {
660 pci_dev_put(tmp);
661 return group;
662 }
663 }
664 693
665 /* No shared group found, allocate new */ 694 /* No shared group found, allocate new */
666 return iommu_group_alloc(); 695 return iommu_group_alloc();