···1111extern int force_iommu, no_iommu;1212extern int iommu_pass_through;1313extern int iommu_detected;1414+extern int iommu_group_mf;1415#else1516#define iommu_pass_through (0)1617#define no_iommu (1)1718#define iommu_detected (0)1919+#define iommu_group_mf (0)1820#endif1921extern void iommu_dma_init(void);2022extern void machvec_init(const char *name);
+1
arch/ia64/kernel/pci-dma.c
···3333#endif34343535int iommu_pass_through;3636+int iommu_group_mf;36373738/* Dummy device used for NULL arguments (normally ISA). Better would3839 be probably a smaller DMA mask, but this is bug-to-bug compatible
+1
arch/x86/include/asm/iommu.h
···55extern int force_iommu, no_iommu;66extern int iommu_detected;77extern int iommu_pass_through;88+extern int iommu_group_mf;89910/* 10 seconds */1011#define DMAR_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
+11
arch/x86/kernel/pci-dma.c
···4545 */4646int iommu_pass_through __read_mostly;47474848+/*4949+ * Group multi-function PCI devices into a single device-group for the5050+ * iommu_device_group interface. This tells the iommu driver to pretend5151+ * it cannot distinguish between functions of a device, exposing only one5252+ * group for the device. Useful for disallowing use of individual PCI5353+ * functions from userspace drivers.5454+ */5555+int iommu_group_mf __read_mostly;5656+4857extern struct iommu_table_entry __iommu_table[], __iommu_table_end[];49585059/* Dummy device used for NULL arguments (normally ISA). */···178169#endif179170 if (!strncmp(p, "pt", 2))180171 iommu_pass_through = 1;172172+ if (!strncmp(p, "group_mf", 8))173173+ iommu_group_mf = 1;181174182175 gart_parse_options(p);183176
···40804080 return 0;40814081}4082408240834083+/*40844084+ * Group numbers are arbitrary. Device with the same group number40854085+ * indicate the iommu cannot differentiate between them. To avoid40864086+ * tracking used groups we just use the seg|bus|devfn of the lowest40874087+ * level we're able to differentiate devices40884088+ */40894089+static int intel_iommu_device_group(struct device *dev, unsigned int *groupid)40904090+{40914091+ struct pci_dev *pdev = to_pci_dev(dev);40924092+ struct pci_dev *bridge;40934093+ union {40944094+ struct {40954095+ u8 devfn;40964096+ u8 bus;40974097+ u16 segment;40984098+ } pci;40994099+ u32 group;41004100+ } id;41014101+41024102+ if (iommu_no_mapping(dev))41034103+ return -ENODEV;41044104+41054105+ id.pci.segment = pci_domain_nr(pdev->bus);41064106+ id.pci.bus = pdev->bus->number;41074107+ id.pci.devfn = pdev->devfn;41084108+41094109+ if (!device_to_iommu(id.pci.segment, id.pci.bus, id.pci.devfn))41104110+ return -ENODEV;41114111+41124112+ bridge = pci_find_upstream_pcie_bridge(pdev);41134113+ if (bridge) {41144114+ if (pci_is_pcie(bridge)) {41154115+ id.pci.bus = bridge->subordinate->number;41164116+ id.pci.devfn = 0;41174117+ } else {41184118+ id.pci.bus = bridge->bus->number;41194119+ id.pci.devfn = bridge->devfn;41204120+ }41214121+ }41224122+41234123+ if (!pdev->is_virtfn && iommu_group_mf)41244124+ id.pci.devfn = PCI_DEVFN(PCI_SLOT(id.pci.devfn), 0);41254125+41264126+ *groupid = id.group;41274127+41284128+ return 0;41294129+}41304130+40834131static struct iommu_ops intel_iommu_ops = {40844132 .domain_init = intel_iommu_domain_init,40854133 .domain_destroy = intel_iommu_domain_destroy,···41374089 .unmap = intel_iommu_unmap,41384090 .iova_to_phys = intel_iommu_iova_to_phys,41394091 .domain_has_cap = intel_iommu_domain_has_cap,40924092+ .device_group = intel_iommu_device_group,41404093 .pgsize_bitmap = INTEL_IOMMU_PGSIZES,41414094};41424095
+60
drivers/iommu/iommu.c
···2727#include <linux/errno.h>2828#include <linux/iommu.h>29293030+static ssize_t show_iommu_group(struct device *dev,3131+ struct device_attribute *attr, char *buf)3232+{3333+ unsigned int groupid;3434+3535+ if (iommu_device_group(dev, &groupid))3636+ return 0;3737+3838+ return sprintf(buf, "%u", groupid);3939+}4040+static DEVICE_ATTR(iommu_group, S_IRUGO, show_iommu_group, NULL);4141+4242+static int add_iommu_group(struct device *dev, void *data)4343+{4444+ unsigned int groupid;4545+4646+ if (iommu_device_group(dev, &groupid) == 0)4747+ return device_create_file(dev, &dev_attr_iommu_group);4848+4949+ return 0;5050+}5151+5252+static int remove_iommu_group(struct device *dev)5353+{5454+ unsigned int groupid;5555+5656+ if (iommu_device_group(dev, &groupid) == 0)5757+ device_remove_file(dev, &dev_attr_iommu_group);5858+5959+ return 0;6060+}6161+6262+static int iommu_device_notifier(struct notifier_block *nb,6363+ unsigned long action, void *data)6464+{6565+ struct device *dev = data;6666+6767+ if (action == BUS_NOTIFY_ADD_DEVICE)6868+ return add_iommu_group(dev, NULL);6969+ else if (action == BUS_NOTIFY_DEL_DEVICE)7070+ return remove_iommu_group(dev);7171+7272+ return 0;7373+}7474+7575+static struct notifier_block iommu_device_nb = {7676+ .notifier_call = iommu_device_notifier,7777+};7878+3079static void iommu_bus_init(struct bus_type *bus, struct iommu_ops *ops)3180{8181+ bus_register_notifier(bus, &iommu_device_nb);8282+ bus_for_each_dev(bus, NULL, NULL, add_iommu_group);3283}33843485/**···332281 return unmapped;333282}334283EXPORT_SYMBOL_GPL(iommu_unmap);284284+285285+int iommu_device_group(struct device *dev, unsigned int *groupid)286286+{287287+ if (iommu_present(dev->bus) && dev->bus->iommu_ops->device_group)288288+ return dev->bus->iommu_ops->device_group(dev, groupid);289289+290290+ return -ENODEV;291291+}292292+EXPORT_SYMBOL_GPL(iommu_device_group);
+7
include/linux/iommu.h
···7474 unsigned long iova);7575 int (*domain_has_cap)(struct iommu_domain *domain,7676 unsigned long cap);7777+ int (*device_group)(struct device *dev, unsigned int *groupid);7778 unsigned long pgsize_bitmap;7879};7980···9695 unsigned long cap);9796extern void iommu_set_fault_handler(struct iommu_domain *domain,9897 iommu_fault_handler_t handler);9898+extern int iommu_device_group(struct device *dev, unsigned int *groupid);9999100100/**101101 * report_iommu_fault() - report about an IOMMU fault to the IOMMU framework···193191static inline void iommu_set_fault_handler(struct iommu_domain *domain,194192 iommu_fault_handler_t handler)195193{194194+}195195+196196+static inline int iommu_device_group(struct device *dev, unsigned int *groupid)197197+{198198+ return -ENODEV;196199}197200198201#endif /* CONFIG_IOMMU_API */