aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/mm
diff options
context:
space:
mode:
authorLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2016-07-01 12:50:10 -0400
committerCatalin Marinas <catalin.marinas@arm.com>2016-07-08 13:06:04 -0400
commit16c11325cc44f0614a45e584d439e195059c3f5a (patch)
tree627f73411c416acee852480df7f88f228e7dfe49 /arch/arm64/mm
parent19a469a58720ea96b649b06fb09ddfd3e831aa69 (diff)
arm64: mm: change IOMMU notifier action to attach DMA ops
Current bus notifier in ARM64 (__iommu_attach_notifier) attempts to attach dma_ops to a device on BUS_NOTIFY_ADD_DEVICE action notification. This will cause issues on ACPI based systems, where PCI devices can be added before the IOMMUs the devices are attached to had a chance to be probed, causing failures on attempts to attach dma_ops in that the domain for the respective IOMMU may not be set-up yet by the time the bus notifier is run. Devices dma_ops do not require to be set-up till the matching device drivers are probed. This means that instead of running the notifier attaching dma_ops to devices (__iommu_attach_notifier) on BUS_NOTIFY_ADD_DEVICE action, it can be run just before the device driver is bound to the device in question (on action BUS_NOTIFY_BIND_DRIVER) so that it is certain that its IOMMU group and domain are set-up accordingly at the time the notifier is triggered. This patch changes the notifier action upon which dma_ops are attached to devices and defer it to driver binding time, so that IOMMU devices have a chance to be probed and to register their bus notifiers before the dma_ops attach sequence for a device is actually carried out. As a result we also no longer need worry about racing with iommu_bus_notifier(), or about retrying the queue in case devices were added too early on DT-based systems, so clean up the notifier itself plus the additional workaround from 722ec35f7fae ("arm64: dma-mapping: fix handling of devices registered before arch_initcall") Acked-by: Will Deacon <will.deacon@arm.com> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> [rm: get rid of other now-redundant bits] Signed-off-by: Robin Murphy <robin.murphy@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/mm')
-rw-r--r--arch/arm64/mm/dma-mapping.c22
1 files changed, 5 insertions, 17 deletions
diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
index 46a4157adc17..f6c55afab3e2 100644
--- a/arch/arm64/mm/dma-mapping.c
+++ b/arch/arm64/mm/dma-mapping.c
@@ -861,15 +861,16 @@ static int __iommu_attach_notifier(struct notifier_block *nb,
861{ 861{
862 struct iommu_dma_notifier_data *master, *tmp; 862 struct iommu_dma_notifier_data *master, *tmp;
863 863
864 if (action != BUS_NOTIFY_ADD_DEVICE) 864 if (action != BUS_NOTIFY_BIND_DRIVER)
865 return 0; 865 return 0;
866 866
867 mutex_lock(&iommu_dma_notifier_lock); 867 mutex_lock(&iommu_dma_notifier_lock);
868 list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) { 868 list_for_each_entry_safe(master, tmp, &iommu_dma_masters, list) {
869 if (do_iommu_attach(master->dev, master->ops, 869 if (data == master->dev && do_iommu_attach(master->dev,
870 master->dma_base, master->size)) { 870 master->ops, master->dma_base, master->size)) {
871 list_del(&master->list); 871 list_del(&master->list);
872 kfree(master); 872 kfree(master);
873 break;
873 } 874 }
874 } 875 }
875 mutex_unlock(&iommu_dma_notifier_lock); 876 mutex_unlock(&iommu_dma_notifier_lock);
@@ -883,17 +884,8 @@ static int __init register_iommu_dma_ops_notifier(struct bus_type *bus)
883 884
884 if (!nb) 885 if (!nb)
885 return -ENOMEM; 886 return -ENOMEM;
886 /* 887
887 * The device must be attached to a domain before the driver probe
888 * routine gets a chance to start allocating DMA buffers. However,
889 * the IOMMU driver also needs a chance to configure the iommu_group
890 * via its add_device callback first, so we need to make the attach
891 * happen between those two points. Since the IOMMU core uses a bus
892 * notifier with default priority for add_device, do the same but
893 * with a lower priority to ensure the appropriate ordering.
894 */
895 nb->notifier_call = __iommu_attach_notifier; 888 nb->notifier_call = __iommu_attach_notifier;
896 nb->priority = -100;
897 889
898 ret = bus_register_notifier(bus, nb); 890 ret = bus_register_notifier(bus, nb);
899 if (ret) { 891 if (ret) {
@@ -917,10 +909,6 @@ static int __init __iommu_dma_init(void)
917 if (!ret) 909 if (!ret)
918 ret = register_iommu_dma_ops_notifier(&pci_bus_type); 910 ret = register_iommu_dma_ops_notifier(&pci_bus_type);
919#endif 911#endif
920
921 /* handle devices queued before this arch_initcall */
922 if (!ret)
923 __iommu_attach_notifier(NULL, BUS_NOTIFY_ADD_DEVICE, NULL);
924 return ret; 912 return ret;
925} 913}
926arch_initcall(__iommu_dma_init); 914arch_initcall(__iommu_dma_init);