Loading Documentation/devicetree/bindings/iommu/arm,smmu.txt +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ conditions. "arm,smmu-v1" "arm,smmu-v2" "arm,mmu-400" "arm,mmu-401" "arm,mmu-500" depending on the particular implementation and/or the Loading drivers/base/core.c +3 −0 Original line number Diff line number Diff line Loading @@ -1211,6 +1211,9 @@ void device_del(struct device *dev) */ if (platform_notify_remove) platform_notify_remove(dev); if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_REMOVED_DEVICE, dev); kobject_uevent(&dev->kobj, KOBJ_REMOVE); cleanup_device_parent(dev); kobject_del(&dev->kobj); Loading drivers/infiniband/hw/usnic/usnic_uiom.c +1 −1 Original line number Diff line number Diff line Loading @@ -507,7 +507,7 @@ int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev) if (err) goto out_free_dev; if (!iommu_domain_has_cap(pd->domain, IOMMU_CAP_CACHE_COHERENCY)) { if (!iommu_capable(dev->bus, IOMMU_CAP_CACHE_COHERENCY)) { usnic_err("IOMMU of %s does not support cache coherency\n", dev_name(dev)); err = -EINVAL; Loading drivers/iommu/amd_iommu.c +68 −49 Original line number Diff line number Diff line Loading @@ -87,6 +87,27 @@ int amd_iommu_max_glx_val = -1; static struct dma_map_ops amd_iommu_dma_ops; /* * This struct contains device specific data for the IOMMU */ struct iommu_dev_data { struct list_head list; /* For domain->dev_list */ struct list_head dev_data_list; /* For global dev_data_list */ struct list_head alias_list; /* Link alias-groups together */ struct iommu_dev_data *alias_data;/* The alias dev_data */ struct protection_domain *domain; /* Domain the device is bound to */ u16 devid; /* PCI Device ID */ bool iommu_v2; /* Device can make use of IOMMUv2 */ bool passthrough; /* Default for device is pt_domain */ struct { bool enabled; int qdep; } ats; /* ATS state */ bool pri_tlp; /* PASID TLB required for PPR completions */ u32 errata; /* Bitmap for errata to apply */ }; /* * general struct to manage commands send to an IOMMU */ Loading Loading @@ -114,8 +135,9 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid) if (!dev_data) return NULL; INIT_LIST_HEAD(&dev_data->alias_list); dev_data->devid = devid; atomic_set(&dev_data->bind, 0); spin_lock_irqsave(&dev_data_list_lock, flags); list_add_tail(&dev_data->dev_data_list, &dev_data_list); Loading Loading @@ -260,17 +282,13 @@ static bool check_device(struct device *dev) return true; } static int init_iommu_group(struct device *dev) static void init_iommu_group(struct device *dev) { struct iommu_group *group; group = iommu_group_get_for_dev(dev); if (IS_ERR(group)) return PTR_ERR(group); if (!IS_ERR(group)) iommu_group_put(group); return 0; } static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) Loading Loading @@ -340,7 +358,6 @@ static int iommu_init_device(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct iommu_dev_data *dev_data; u16 alias; int ret; if (dev->archdata.iommu) return 0; Loading @@ -362,12 +379,9 @@ static int iommu_init_device(struct device *dev) return -ENOTSUPP; } dev_data->alias_data = alias_data; } ret = init_iommu_group(dev); if (ret) { free_dev_data(dev_data); return ret; /* Add device to the alias_list */ list_add(&dev_data->alias_list, &alias_data->alias_list); } if (pci_iommuv2_capable(pdev)) { Loading Loading @@ -455,6 +469,15 @@ int __init amd_iommu_init_devices(void) goto out_free; } /* * Initialize IOMMU groups only after iommu_init_device() has * had a chance to populate any IVRS defined aliases. */ for_each_pci_dev(pdev) { if (check_device(&pdev->dev)) init_iommu_group(&pdev->dev); } return 0; out_free: Loading Loading @@ -1368,6 +1391,9 @@ static int iommu_map_page(struct protection_domain *dom, count = PAGE_SIZE_PTE_COUNT(page_size); pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL); if (!pte) return -ENOMEM; for (i = 0; i < count; ++i) if (IOMMU_PTE_PRESENT(pte[i])) return -EBUSY; Loading Loading @@ -2122,35 +2148,29 @@ static void do_detach(struct iommu_dev_data *dev_data) static int __attach_device(struct iommu_dev_data *dev_data, struct protection_domain *domain) { struct iommu_dev_data *head, *entry; int ret; /* lock domain */ spin_lock(&domain->lock); if (dev_data->alias_data != NULL) { struct iommu_dev_data *alias_data = dev_data->alias_data; /* Some sanity checks */ ret = -EBUSY; if (alias_data->domain != NULL && alias_data->domain != domain) goto out_unlock; head = dev_data; if (dev_data->domain != NULL && dev_data->domain != domain) goto out_unlock; if (head->alias_data != NULL) head = head->alias_data; /* Do real assignment */ if (alias_data->domain == NULL) do_attach(alias_data, domain); /* Now we have the root of the alias group, if any */ atomic_inc(&alias_data->bind); } ret = -EBUSY; if (head->domain != NULL) goto out_unlock; if (dev_data->domain == NULL) do_attach(dev_data, domain); /* Attach alias group root */ do_attach(head, domain); atomic_inc(&dev_data->bind); /* Attach other devices in the alias group */ list_for_each_entry(entry, &head->alias_list, alias_list) do_attach(entry, domain); ret = 0; Loading Loading @@ -2298,6 +2318,7 @@ static int attach_device(struct device *dev, */ static void __detach_device(struct iommu_dev_data *dev_data) { struct iommu_dev_data *head, *entry; struct protection_domain *domain; unsigned long flags; Loading @@ -2307,15 +2328,14 @@ static void __detach_device(struct iommu_dev_data *dev_data) spin_lock_irqsave(&domain->lock, flags); if (dev_data->alias_data != NULL) { struct iommu_dev_data *alias_data = dev_data->alias_data; head = dev_data; if (head->alias_data != NULL) head = head->alias_data; if (atomic_dec_and_test(&alias_data->bind)) do_detach(alias_data); } list_for_each_entry(entry, &head->alias_list, alias_list) do_detach(entry); if (atomic_dec_and_test(&dev_data->bind)) do_detach(dev_data); do_detach(head); spin_unlock_irqrestore(&domain->lock, flags); Loading Loading @@ -2415,6 +2435,7 @@ static int device_change_notifier(struct notifier_block *nb, case BUS_NOTIFY_ADD_DEVICE: iommu_init_device(dev); init_iommu_group(dev); /* * dev_data is still NULL and Loading Loading @@ -3158,7 +3179,6 @@ static void cleanup_domain(struct protection_domain *domain) entry = list_first_entry(&domain->dev_list, struct iommu_dev_data, list); __detach_device(entry); atomic_set(&entry->bind, 0); } write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); Loading Loading @@ -3384,20 +3404,20 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, return paddr; } static int amd_iommu_domain_has_cap(struct iommu_domain *domain, unsigned long cap) static bool amd_iommu_capable(enum iommu_cap cap) { switch (cap) { case IOMMU_CAP_CACHE_COHERENCY: return 1; return true; case IOMMU_CAP_INTR_REMAP: return irq_remapping_enabled; return (irq_remapping_enabled == 1); } return 0; return false; } static const struct iommu_ops amd_iommu_ops = { .capable = amd_iommu_capable, .domain_init = amd_iommu_domain_init, .domain_destroy = amd_iommu_domain_destroy, .attach_dev = amd_iommu_attach_device, Loading @@ -3405,7 +3425,6 @@ static const struct iommu_ops amd_iommu_ops = { .map = amd_iommu_map, .unmap = amd_iommu_unmap, .iova_to_phys = amd_iommu_iova_to_phys, .domain_has_cap = amd_iommu_domain_has_cap, .pgsize_bitmap = AMD_IOMMU_PGSIZES, }; Loading Loading @@ -4235,7 +4254,7 @@ static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq, return 0; } static int setup_hpet_msi(unsigned int irq, unsigned int id) static int alloc_hpet_msi(unsigned int irq, unsigned int id) { struct irq_2_irte *irte_info; struct irq_cfg *cfg; Loading Loading @@ -4274,6 +4293,6 @@ struct irq_remap_ops amd_iommu_irq_ops = { .compose_msi_msg = compose_msi_msg, .msi_alloc_irq = msi_alloc_irq, .msi_setup_irq = msi_setup_irq, .setup_hpet_msi = setup_hpet_msi, .alloc_hpet_msi = alloc_hpet_msi, }; #endif drivers/iommu/amd_iommu_init.c +15 −6 Original line number Diff line number Diff line Loading @@ -712,7 +712,7 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu, set_iommu_for_device(iommu, devid); } static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line) { struct devid_map *entry; struct list_head *list; Loading @@ -731,6 +731,8 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) pr_info("AMD-Vi: Command-line override present for %s id %d - ignoring\n", type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id); *devid = entry->devid; return 0; } Loading @@ -739,7 +741,7 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) return -ENOMEM; entry->id = id; entry->devid = devid; entry->devid = *devid; entry->cmd_line = cmd_line; list_add_tail(&entry->list, list); Loading @@ -754,7 +756,7 @@ static int __init add_early_maps(void) for (i = 0; i < early_ioapic_map_size; ++i) { ret = add_special_device(IVHD_SPECIAL_IOAPIC, early_ioapic_map[i].id, early_ioapic_map[i].devid, &early_ioapic_map[i].devid, early_ioapic_map[i].cmd_line); if (ret) return ret; Loading @@ -763,7 +765,7 @@ static int __init add_early_maps(void) for (i = 0; i < early_hpet_map_size; ++i) { ret = add_special_device(IVHD_SPECIAL_HPET, early_hpet_map[i].id, early_hpet_map[i].devid, &early_hpet_map[i].devid, early_hpet_map[i].cmd_line); if (ret) return ret; Loading Loading @@ -978,10 +980,17 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, PCI_SLOT(devid), PCI_FUNC(devid)); set_dev_entry_from_acpi(iommu, devid, e->flags, 0); ret = add_special_device(type, handle, devid, false); ret = add_special_device(type, handle, &devid, false); if (ret) return ret; /* * add_special_device might update the devid in case a * command-line override is present. So call * set_dev_entry_from_acpi after add_special_device. */ set_dev_entry_from_acpi(iommu, devid, e->flags, 0); break; } default: Loading Loading
Documentation/devicetree/bindings/iommu/arm,smmu.txt +1 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ conditions. "arm,smmu-v1" "arm,smmu-v2" "arm,mmu-400" "arm,mmu-401" "arm,mmu-500" depending on the particular implementation and/or the Loading
drivers/base/core.c +3 −0 Original line number Diff line number Diff line Loading @@ -1211,6 +1211,9 @@ void device_del(struct device *dev) */ if (platform_notify_remove) platform_notify_remove(dev); if (dev->bus) blocking_notifier_call_chain(&dev->bus->p->bus_notifier, BUS_NOTIFY_REMOVED_DEVICE, dev); kobject_uevent(&dev->kobj, KOBJ_REMOVE); cleanup_device_parent(dev); kobject_del(&dev->kobj); Loading
drivers/infiniband/hw/usnic/usnic_uiom.c +1 −1 Original line number Diff line number Diff line Loading @@ -507,7 +507,7 @@ int usnic_uiom_attach_dev_to_pd(struct usnic_uiom_pd *pd, struct device *dev) if (err) goto out_free_dev; if (!iommu_domain_has_cap(pd->domain, IOMMU_CAP_CACHE_COHERENCY)) { if (!iommu_capable(dev->bus, IOMMU_CAP_CACHE_COHERENCY)) { usnic_err("IOMMU of %s does not support cache coherency\n", dev_name(dev)); err = -EINVAL; Loading
drivers/iommu/amd_iommu.c +68 −49 Original line number Diff line number Diff line Loading @@ -87,6 +87,27 @@ int amd_iommu_max_glx_val = -1; static struct dma_map_ops amd_iommu_dma_ops; /* * This struct contains device specific data for the IOMMU */ struct iommu_dev_data { struct list_head list; /* For domain->dev_list */ struct list_head dev_data_list; /* For global dev_data_list */ struct list_head alias_list; /* Link alias-groups together */ struct iommu_dev_data *alias_data;/* The alias dev_data */ struct protection_domain *domain; /* Domain the device is bound to */ u16 devid; /* PCI Device ID */ bool iommu_v2; /* Device can make use of IOMMUv2 */ bool passthrough; /* Default for device is pt_domain */ struct { bool enabled; int qdep; } ats; /* ATS state */ bool pri_tlp; /* PASID TLB required for PPR completions */ u32 errata; /* Bitmap for errata to apply */ }; /* * general struct to manage commands send to an IOMMU */ Loading Loading @@ -114,8 +135,9 @@ static struct iommu_dev_data *alloc_dev_data(u16 devid) if (!dev_data) return NULL; INIT_LIST_HEAD(&dev_data->alias_list); dev_data->devid = devid; atomic_set(&dev_data->bind, 0); spin_lock_irqsave(&dev_data_list_lock, flags); list_add_tail(&dev_data->dev_data_list, &dev_data_list); Loading Loading @@ -260,17 +282,13 @@ static bool check_device(struct device *dev) return true; } static int init_iommu_group(struct device *dev) static void init_iommu_group(struct device *dev) { struct iommu_group *group; group = iommu_group_get_for_dev(dev); if (IS_ERR(group)) return PTR_ERR(group); if (!IS_ERR(group)) iommu_group_put(group); return 0; } static int __last_alias(struct pci_dev *pdev, u16 alias, void *data) Loading Loading @@ -340,7 +358,6 @@ static int iommu_init_device(struct device *dev) struct pci_dev *pdev = to_pci_dev(dev); struct iommu_dev_data *dev_data; u16 alias; int ret; if (dev->archdata.iommu) return 0; Loading @@ -362,12 +379,9 @@ static int iommu_init_device(struct device *dev) return -ENOTSUPP; } dev_data->alias_data = alias_data; } ret = init_iommu_group(dev); if (ret) { free_dev_data(dev_data); return ret; /* Add device to the alias_list */ list_add(&dev_data->alias_list, &alias_data->alias_list); } if (pci_iommuv2_capable(pdev)) { Loading Loading @@ -455,6 +469,15 @@ int __init amd_iommu_init_devices(void) goto out_free; } /* * Initialize IOMMU groups only after iommu_init_device() has * had a chance to populate any IVRS defined aliases. */ for_each_pci_dev(pdev) { if (check_device(&pdev->dev)) init_iommu_group(&pdev->dev); } return 0; out_free: Loading Loading @@ -1368,6 +1391,9 @@ static int iommu_map_page(struct protection_domain *dom, count = PAGE_SIZE_PTE_COUNT(page_size); pte = alloc_pte(dom, bus_addr, page_size, NULL, GFP_KERNEL); if (!pte) return -ENOMEM; for (i = 0; i < count; ++i) if (IOMMU_PTE_PRESENT(pte[i])) return -EBUSY; Loading Loading @@ -2122,35 +2148,29 @@ static void do_detach(struct iommu_dev_data *dev_data) static int __attach_device(struct iommu_dev_data *dev_data, struct protection_domain *domain) { struct iommu_dev_data *head, *entry; int ret; /* lock domain */ spin_lock(&domain->lock); if (dev_data->alias_data != NULL) { struct iommu_dev_data *alias_data = dev_data->alias_data; /* Some sanity checks */ ret = -EBUSY; if (alias_data->domain != NULL && alias_data->domain != domain) goto out_unlock; head = dev_data; if (dev_data->domain != NULL && dev_data->domain != domain) goto out_unlock; if (head->alias_data != NULL) head = head->alias_data; /* Do real assignment */ if (alias_data->domain == NULL) do_attach(alias_data, domain); /* Now we have the root of the alias group, if any */ atomic_inc(&alias_data->bind); } ret = -EBUSY; if (head->domain != NULL) goto out_unlock; if (dev_data->domain == NULL) do_attach(dev_data, domain); /* Attach alias group root */ do_attach(head, domain); atomic_inc(&dev_data->bind); /* Attach other devices in the alias group */ list_for_each_entry(entry, &head->alias_list, alias_list) do_attach(entry, domain); ret = 0; Loading Loading @@ -2298,6 +2318,7 @@ static int attach_device(struct device *dev, */ static void __detach_device(struct iommu_dev_data *dev_data) { struct iommu_dev_data *head, *entry; struct protection_domain *domain; unsigned long flags; Loading @@ -2307,15 +2328,14 @@ static void __detach_device(struct iommu_dev_data *dev_data) spin_lock_irqsave(&domain->lock, flags); if (dev_data->alias_data != NULL) { struct iommu_dev_data *alias_data = dev_data->alias_data; head = dev_data; if (head->alias_data != NULL) head = head->alias_data; if (atomic_dec_and_test(&alias_data->bind)) do_detach(alias_data); } list_for_each_entry(entry, &head->alias_list, alias_list) do_detach(entry); if (atomic_dec_and_test(&dev_data->bind)) do_detach(dev_data); do_detach(head); spin_unlock_irqrestore(&domain->lock, flags); Loading Loading @@ -2415,6 +2435,7 @@ static int device_change_notifier(struct notifier_block *nb, case BUS_NOTIFY_ADD_DEVICE: iommu_init_device(dev); init_iommu_group(dev); /* * dev_data is still NULL and Loading Loading @@ -3158,7 +3179,6 @@ static void cleanup_domain(struct protection_domain *domain) entry = list_first_entry(&domain->dev_list, struct iommu_dev_data, list); __detach_device(entry); atomic_set(&entry->bind, 0); } write_unlock_irqrestore(&amd_iommu_devtable_lock, flags); Loading Loading @@ -3384,20 +3404,20 @@ static phys_addr_t amd_iommu_iova_to_phys(struct iommu_domain *dom, return paddr; } static int amd_iommu_domain_has_cap(struct iommu_domain *domain, unsigned long cap) static bool amd_iommu_capable(enum iommu_cap cap) { switch (cap) { case IOMMU_CAP_CACHE_COHERENCY: return 1; return true; case IOMMU_CAP_INTR_REMAP: return irq_remapping_enabled; return (irq_remapping_enabled == 1); } return 0; return false; } static const struct iommu_ops amd_iommu_ops = { .capable = amd_iommu_capable, .domain_init = amd_iommu_domain_init, .domain_destroy = amd_iommu_domain_destroy, .attach_dev = amd_iommu_attach_device, Loading @@ -3405,7 +3425,6 @@ static const struct iommu_ops amd_iommu_ops = { .map = amd_iommu_map, .unmap = amd_iommu_unmap, .iova_to_phys = amd_iommu_iova_to_phys, .domain_has_cap = amd_iommu_domain_has_cap, .pgsize_bitmap = AMD_IOMMU_PGSIZES, }; Loading Loading @@ -4235,7 +4254,7 @@ static int msi_setup_irq(struct pci_dev *pdev, unsigned int irq, return 0; } static int setup_hpet_msi(unsigned int irq, unsigned int id) static int alloc_hpet_msi(unsigned int irq, unsigned int id) { struct irq_2_irte *irte_info; struct irq_cfg *cfg; Loading Loading @@ -4274,6 +4293,6 @@ struct irq_remap_ops amd_iommu_irq_ops = { .compose_msi_msg = compose_msi_msg, .msi_alloc_irq = msi_alloc_irq, .msi_setup_irq = msi_setup_irq, .setup_hpet_msi = setup_hpet_msi, .alloc_hpet_msi = alloc_hpet_msi, }; #endif
drivers/iommu/amd_iommu_init.c +15 −6 Original line number Diff line number Diff line Loading @@ -712,7 +712,7 @@ static void __init set_dev_entry_from_acpi(struct amd_iommu *iommu, set_iommu_for_device(iommu, devid); } static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) static int __init add_special_device(u8 type, u8 id, u16 *devid, bool cmd_line) { struct devid_map *entry; struct list_head *list; Loading @@ -731,6 +731,8 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) pr_info("AMD-Vi: Command-line override present for %s id %d - ignoring\n", type == IVHD_SPECIAL_IOAPIC ? "IOAPIC" : "HPET", id); *devid = entry->devid; return 0; } Loading @@ -739,7 +741,7 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line) return -ENOMEM; entry->id = id; entry->devid = devid; entry->devid = *devid; entry->cmd_line = cmd_line; list_add_tail(&entry->list, list); Loading @@ -754,7 +756,7 @@ static int __init add_early_maps(void) for (i = 0; i < early_ioapic_map_size; ++i) { ret = add_special_device(IVHD_SPECIAL_IOAPIC, early_ioapic_map[i].id, early_ioapic_map[i].devid, &early_ioapic_map[i].devid, early_ioapic_map[i].cmd_line); if (ret) return ret; Loading @@ -763,7 +765,7 @@ static int __init add_early_maps(void) for (i = 0; i < early_hpet_map_size; ++i) { ret = add_special_device(IVHD_SPECIAL_HPET, early_hpet_map[i].id, early_hpet_map[i].devid, &early_hpet_map[i].devid, early_hpet_map[i].cmd_line); if (ret) return ret; Loading Loading @@ -978,10 +980,17 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu, PCI_SLOT(devid), PCI_FUNC(devid)); set_dev_entry_from_acpi(iommu, devid, e->flags, 0); ret = add_special_device(type, handle, devid, false); ret = add_special_device(type, handle, &devid, false); if (ret) return ret; /* * add_special_device might update the devid in case a * command-line override is present. So call * set_dev_entry_from_acpi after add_special_device. */ set_dev_entry_from_acpi(iommu, devid, e->flags, 0); break; } default: Loading