aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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();