aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/iommu.c
diff options
context:
space:
mode:
authorAlex Williamson <alex.williamson@redhat.com>2014-07-03 11:51:18 -0400
committerJoerg Roedel <jroedel@suse.de>2014-07-04 06:35:58 -0400
commit104a1c13ac66e40cf8c6ae74d76ff14ff24b9b01 (patch)
treee54d1840d8b0a7b2896a1678c277048fb1bf337e /drivers/iommu/iommu.c
parent4c834452aad01531db949414f94f817a86348d59 (diff)
iommu/core: Create central IOMMU group lookup/creation interface
Currently each IOMMU driver that supports IOMMU groups has its own code for discovering the base device used in grouping. This code is generally not specific to the IOMMU hardware, but to the bus of the devices managed by the IOMMU. We can therefore create a common interface for supporting devices on different buses. Signed-off-by: Alex Williamson <alex.williamson@redhat.com> Signed-off-by: Joerg Roedel <jroedel@suse.de>
Diffstat (limited to 'drivers/iommu/iommu.c')
-rw-r--r--drivers/iommu/iommu.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index e5555fcfe703..d061c8677a81 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -29,6 +29,7 @@
29#include <linux/idr.h> 29#include <linux/idr.h>
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 <trace/events/iommu.h> 33#include <trace/events/iommu.h>
33 34
34static struct kset *iommu_group_kset; 35static struct kset *iommu_group_kset;
@@ -514,6 +515,187 @@ int iommu_group_id(struct iommu_group *group)
514} 515}
515EXPORT_SYMBOL_GPL(iommu_group_id); 516EXPORT_SYMBOL_GPL(iommu_group_id);
516 517
518/*
519 * To consider a PCI device isolated, we require ACS to support Source
520 * Validation, Request Redirection, Completer Redirection, and Upstream
521 * Forwarding. This effectively means that devices cannot spoof their
522 * requester ID, requests and completions cannot be redirected, and all
523 * transactions are forwarded upstream, even as it passes through a
524 * bridge where the target device is downstream.
525 */
526#define REQ_ACS_FLAGS (PCI_ACS_SV | PCI_ACS_RR | PCI_ACS_CR | PCI_ACS_UF)
527
528struct group_for_pci_data {
529 struct pci_dev *pdev;
530 struct iommu_group *group;
531};
532
533/*
534 * DMA alias iterator callback, return the last seen device. Stop and return
535 * the IOMMU group if we find one along the way.
536 */
537static int get_pci_alias_or_group(struct pci_dev *pdev, u16 alias, void *opaque)
538{
539 struct group_for_pci_data *data = opaque;
540
541 data->pdev = pdev;
542 data->group = iommu_group_get(&pdev->dev);
543
544 return data->group != NULL;
545}
546
547/*
548 * Use standard PCI bus topology, isolation features, and DMA alias quirks
549 * to find or create an IOMMU group for a device.
550 */
551static struct iommu_group *iommu_group_get_for_pci_dev(struct pci_dev *pdev)
552{
553 struct group_for_pci_data data;
554 struct pci_bus *bus;
555 struct iommu_group *group = NULL;
556 struct pci_dev *tmp;
557
558 /*
559 * Find the upstream DMA alias for the device. A device must not
560 * be aliased due to topology in order to have its own IOMMU group.
561 * If we find an alias along the way that already belongs to a
562 * group, use it.
563 */
564 if (pci_for_each_dma_alias(pdev, get_pci_alias_or_group, &data))
565 return data.group;
566
567 pdev = data.pdev;
568
569 /*
570 * Continue upstream from the point of minimum IOMMU granularity
571 * due to aliases to the point where devices are protected from
572 * peer-to-peer DMA by PCI ACS. Again, if we find an existing
573 * group, use it.
574 */
575 for (bus = pdev->bus; !pci_is_root_bus(bus); bus = bus->parent) {
576 if (!bus->self)
577 continue;
578
579 if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS))
580 break;
581
582 pdev = bus->self;
583
584 group = iommu_group_get(&pdev->dev);
585 if (group)
586 return group;
587 }
588
589 /*
590 * Next we need to consider DMA alias quirks. If one device aliases
591 * to another, they should be grouped together. It's theoretically
592 * possible that aliases could create chains of devices where each
593 * device aliases another device. If we then factor in multifunction
594 * ACS grouping requirements, each alias could incorporate a new slot
595 * with multiple functions, each with aliases. This is all extremely
596 * unlikely as DMA alias quirks are typically only used for PCIe
597 * devices where we usually have a single slot per bus. Furthermore,
598 * the alias quirk is usually to another function within the slot
599 * (and ACS multifunction is not supported) or to a different slot
600 * that doesn't physically exist. The likely scenario is therefore
601 * that everything on the bus gets grouped together. To reduce the
602 * problem space, share the IOMMU group for all devices on the bus
603 * if a DMA alias quirk is present on the bus.
604 */
605 tmp = NULL;
606 for_each_pci_dev(tmp) {
607 if (tmp->bus != pdev->bus ||
608 !(tmp->dev_flags & PCI_DEV_FLAGS_DMA_ALIAS_DEVFN))
609 continue;
610
611 pci_dev_put(tmp);
612 tmp = NULL;
613
614 /* We have an alias quirk, search for an existing group */
615 for_each_pci_dev(tmp) {
616 struct iommu_group *group_tmp;
617
618 if (tmp->bus != pdev->bus)
619 continue;
620
621 group_tmp = iommu_group_get(&tmp->dev);
622 if (!group) {
623 group = group_tmp;
624 continue;
625 }
626
627 if (group_tmp) {
628 WARN_ON(group != group_tmp);
629 iommu_group_put(group_tmp);
630 }
631 }
632
633 return group ? group : iommu_group_alloc();
634 }
635
636 /*
637 * Non-multifunction devices or multifunction devices supporting
638 * ACS get their own group.
639 */
640 if (!pdev->multifunction || pci_acs_enabled(pdev, REQ_ACS_FLAGS))
641 return iommu_group_alloc();
642
643 /*
644 * Multifunction devices not supporting ACS share a group with other
645 * similar devices in the same slot.
646 */
647 tmp = NULL;
648 for_each_pci_dev(tmp) {
649 if (tmp == pdev || tmp->bus != pdev->bus ||
650 PCI_SLOT(tmp->devfn) != PCI_SLOT(pdev->devfn) ||
651 pci_acs_enabled(tmp, REQ_ACS_FLAGS))
652 continue;
653
654 group = iommu_group_get(&tmp->dev);
655 if (group) {
656 pci_dev_put(tmp);
657 return group;
658 }
659 }
660
661 /* No shared group found, allocate new */
662 return iommu_group_alloc();
663}
664
665/**
666 * iommu_group_get_for_dev - Find or create the IOMMU group for a device
667 * @dev: target device
668 *
669 * This function is intended to be called by IOMMU drivers and extended to
670 * support common, bus-defined algorithms when determining or creating the
671 * IOMMU group for a device. On success, the caller will hold a reference
672 * to the returned IOMMU group, which will already include the provided
673 * device. The reference should be released with iommu_group_put().
674 */
675struct iommu_group *iommu_group_get_for_dev(struct device *dev)
676{
677 struct iommu_group *group = ERR_PTR(-EIO);
678 int ret;
679
680 group = iommu_group_get(dev);
681 if (group)
682 return group;
683
684 if (dev_is_pci(dev))
685 group = iommu_group_get_for_pci_dev(to_pci_dev(dev));
686
687 if (IS_ERR(group))
688 return group;
689
690 ret = iommu_group_add_device(group, dev);
691 if (ret) {
692 iommu_group_put(group);
693 return ERR_PTR(ret);
694 }
695
696 return group;
697}
698
517static int add_iommu_group(struct device *dev, void *data) 699static int add_iommu_group(struct device *dev, void *data)
518{ 700{
519 struct iommu_ops *ops = data; 701 struct iommu_ops *ops = data;