···52525353static int _do_recover(struct pci_dev *pdev, struct zpci_dev *zdev)5454{5555- u8 status;5655 int ret;57565857 pci_stop_and_remove_bus_device(pdev);···6970 return ret;7071 }71727272- ret = zpci_enable_device(zdev);7373- if (ret)7474- return ret;7373+ ret = zpci_reenable_device(zdev);75747676- if (zdev->dma_table) {7777- ret = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,7878- virt_to_phys(zdev->dma_table), &status);7979- if (ret)8080- zpci_disable_device(zdev);8181- }8275 return ret;8376}8477
+5
drivers/acpi/arm64/dma.c
···2626 else2727 end = (1ULL << 32) - 1;28282929+ if (dev->dma_range_map) {3030+ dev_dbg(dev, "dma_range_map already set\n");3131+ return;3232+ }3333+2934 ret = acpi_dma_get_range(dev, &map);3035 if (!ret && map) {3136 end = dma_range_map_max(map);
-7
drivers/acpi/scan.c
···16321632 err = viot_iommu_configure(dev);16331633 mutex_unlock(&iommu_probe_device_lock);1634163416351635- /*16361636- * If we have reason to believe the IOMMU driver missed the initial16371637- * iommu_probe_device() call for dev, replay it to get things in order.16381638- */16391639- if (!err && dev->bus)16401640- err = iommu_probe_device(dev);16411641-16421635 return err;16431636}16441637
+2-1
drivers/amba/bus.c
···364364 ret = acpi_dma_configure(dev, attr);365365 }366366367367- if (!ret && !drv->driver_managed_dma) {367367+ /* @drv may not be valid when we're called from the IOMMU layer */368368+ if (!ret && dev->driver && !drv->driver_managed_dma) {368369 ret = iommu_device_use_default_domain(dev);369370 if (ret)370371 arch_teardown_dma_ops(dev);
+2-1
drivers/base/platform.c
···14511451 attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));14521452 ret = acpi_dma_configure(dev, attr);14531453 }14541454- if (ret || drv->driver_managed_dma)14541454+ /* @drv may not be valid when we're called from the IOMMU layer */14551455+ if (ret || !dev->driver || drv->driver_managed_dma)14551456 return ret;1456145714571458 ret = iommu_device_use_default_domain(dev);
+2-1
drivers/bus/fsl-mc/fsl-mc-bus.c
···153153 else154154 ret = acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id);155155156156- if (!ret && !mc_drv->driver_managed_dma) {156156+ /* @mc_drv may not be valid when we're called from the IOMMU layer */157157+ if (!ret && dev->driver && !mc_drv->driver_managed_dma) {157158 ret = iommu_device_use_default_domain(dev);158159 if (ret)159160 arch_teardown_dma_ops(dev);
+2-1
drivers/cdx/cdx.c
···360360 return ret;361361 }362362363363- if (!ret && !cdx_drv->driver_managed_dma) {363363+ /* @cdx_drv may not be valid when we're called from the IOMMU layer */364364+ if (!ret && dev->driver && !cdx_drv->driver_managed_dma) {364365 ret = iommu_device_use_default_domain(dev);365366 if (ret)366367 arch_teardown_dma_ops(dev);
+1-3
drivers/iommu/Kconfig
···154154 select DMA_OPS_HELPERS155155 select IOMMU_API156156 select IOMMU_IOVA157157- select IRQ_MSI_IOMMU158157 select NEED_SG_DMA_LENGTH159158 select NEED_SG_DMA_FLAGS if SWIOTLB160159···482483483484config MTK_IOMMU_V1484485 tristate "MediaTek IOMMU Version 1 (M4U gen1) Support"485485- depends on ARM486486- depends on ARCH_MEDIATEK || COMPILE_TEST486486+ depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST487487 select ARM_DMA_USE_IOMMU488488 select IOMMU_API489489 select MEMORY
···932932 context_clear_entry(context);933933 __iommu_flush_cache(iommu, context, sizeof(*context));934934 spin_unlock(&iommu->lock);935935- intel_context_flush_present(info, context, did, false);935935+ intel_context_flush_no_pasid(info, context, did);936936}937937938938static int pci_pasid_table_teardown(struct pci_dev *pdev, u16 alias, void *data)···992992 context_set_sm_dte(context);993993 if (info->pasid_supported)994994 context_set_pasid(context);995995+ if (info->pri_supported)996996+ context_set_sm_pre(context);995997996998 context_set_fault_enable(context);997999 context_set_present(context);···1119111711201118/*11211119 * Cache invalidations after change in a context table entry that was present11221122- * according to the Spec 6.5.3.3 (Guidance to Software for Invalidations). If11231123- * IOMMU is in scalable mode and all PASID table entries of the device were11241124- * non-present, set flush_domains to false. Otherwise, true.11201120+ * according to the Spec 6.5.3.3 (Guidance to Software for Invalidations).11211121+ * This helper can only be used when IOMMU is working in the legacy mode or11221122+ * IOMMU is in scalable mode but all PASID table entries of the device are11231123+ * non-present.11251124 */11261126-void intel_context_flush_present(struct device_domain_info *info,11271127- struct context_entry *context,11281128- u16 did, bool flush_domains)11251125+void intel_context_flush_no_pasid(struct device_domain_info *info,11261126+ struct context_entry *context, u16 did)11291127{11301128 struct intel_iommu *iommu = info->iommu;11311131- struct pasid_entry *pte;11321132- int i;1133112911341130 /*11351131 * Device-selective context-cache invalidation. The Domain-ID field···11481148 __context_flush_dev_iotlb(info);1149114911501150 return;11511151- }11521152-11531153- /*11541154- * For scalable mode:11551155- * - Domain-selective PASID-cache invalidation to affected domains11561156- * - Domain-selective IOTLB invalidation to affected domains11571157- * - Global Device-TLB invalidation to affected functions11581158- */11591159- if (flush_domains) {11601160- /*11611161- * If the IOMMU is running in scalable mode and there might11621162- * be potential PASID translations, the caller should hold11631163- * the lock to ensure that context changes and cache flushes11641164- * are atomic.11651165- */11661166- assert_spin_locked(&iommu->lock);11671167- for (i = 0; i < info->pasid_table->max_pasid; i++) {11681168- pte = intel_pasid_get_entry(info->dev, i);11691169- if (!pte || !pasid_pte_is_present(pte))11701170- continue;11711171-11721172- did = pasid_get_domain_id(pte);11731173- qi_flush_pasid_cache(iommu, did, QI_PC_ALL_PASIDS, 0);11741174- iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);11751175- }11761151 }1177115211781153 __context_flush_dev_iotlb(info);
+1-1
drivers/iommu/intel/prq.c
···6767 u16 sid, did;68686969 info = dev_iommu_priv_get(dev);7070- if (!info->pri_enabled)7070+ if (!info->iopf_refcount)7171 return;72727373 iommu = info->iommu;
+43
drivers/iommu/intel/svm.c
···110110 .free_notifier = intel_mm_free_notifier,111111};112112113113+static int intel_iommu_sva_supported(struct device *dev)114114+{115115+ struct device_domain_info *info = dev_iommu_priv_get(dev);116116+ struct intel_iommu *iommu;117117+118118+ if (!info || dmar_disabled)119119+ return -EINVAL;120120+121121+ iommu = info->iommu;122122+ if (!iommu)123123+ return -EINVAL;124124+125125+ if (!(iommu->flags & VTD_FLAG_SVM_CAPABLE))126126+ return -ENODEV;127127+128128+ if (!info->pasid_enabled || !info->ats_enabled)129129+ return -EINVAL;130130+131131+ /*132132+ * Devices having device-specific I/O fault handling should not133133+ * support PCI/PRI. The IOMMU side has no means to check the134134+ * capability of device-specific IOPF. Therefore, IOMMU can only135135+ * default that if the device driver enables SVA on a non-PRI136136+ * device, it will handle IOPF in its own way.137137+ */138138+ if (!info->pri_supported)139139+ return 0;140140+141141+ /* Devices supporting PRI should have it enabled. */142142+ if (!info->pri_enabled)143143+ return -EINVAL;144144+145145+ return 0;146146+}147147+113148static int intel_svm_set_dev_pasid(struct iommu_domain *domain,114149 struct device *dev, ioasid_t pasid,115150 struct iommu_domain *old)···155120 struct dev_pasid_info *dev_pasid;156121 unsigned long sflags;157122 int ret = 0;123123+124124+ ret = intel_iommu_sva_supported(dev);125125+ if (ret)126126+ return ret;158127159128 dev_pasid = domain_add_dev_pasid(domain, dev, pasid);160129 if (IS_ERR(dev_pasid))···199160{200161 struct dmar_domain *domain;201162 int ret;163163+164164+ ret = intel_iommu_sva_supported(dev);165165+ if (ret)166166+ return ERR_PTR(ret);202167203168 domain = kzalloc(sizeof(*domain), GFP_KERNEL);204169 if (!domain)
+1-1
drivers/iommu/io-pgtable-dart.c
···135135 pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_START, 0);136136 pte |= FIELD_PREP(APPLE_DART_PTE_SUBPAGE_END, 0xfff);137137138138- pte |= APPLE_DART1_PTE_PROT_SP_DIS;139138 pte |= APPLE_DART_PTE_VALID;140139141140 for (i = 0; i < num_entries; i++)···210211 dart_iopte pte = 0;211212212213 if (data->iop.fmt == APPLE_DART) {214214+ pte |= APPLE_DART1_PTE_PROT_SP_DIS;213215 if (!(prot & IOMMU_WRITE))214216 pte |= APPLE_DART1_PTE_PROT_NO_WRITE;215217 if (!(prot & IOMMU_READ))
···4545static bool iommu_dma_strict __read_mostly = IS_ENABLED(CONFIG_IOMMU_DEFAULT_DMA_STRICT);4646static u32 iommu_cmd_line __read_mostly;47474848+/* Tags used with xa_tag_pointer() in group->pasid_array */4949+enum { IOMMU_PASID_ARRAY_DOMAIN = 0, IOMMU_PASID_ARRAY_HANDLE = 1 };5050+4851struct iommu_group {4952 struct kobject kobj;5053 struct kobject *devices_kobj;···355352 return param;356353}357354358358-static void dev_iommu_free(struct device *dev)355355+void dev_iommu_free(struct device *dev)359356{360357 struct dev_iommu *param = dev->iommu;361358···407404 * Init the dev->iommu and dev->iommu_group in the struct device and get the408405 * driver probed409406 */410410-static int iommu_init_device(struct device *dev, const struct iommu_ops *ops)407407+static int iommu_init_device(struct device *dev)411408{409409+ const struct iommu_ops *ops;412410 struct iommu_device *iommu_dev;413411 struct iommu_group *group;414412 int ret;415413416414 if (!dev_iommu_get(dev))417415 return -ENOMEM;416416+ /*417417+ * For FDT-based systems and ACPI IORT/VIOT, the common firmware parsing418418+ * is buried in the bus dma_configure path. Properly unpicking that is419419+ * still a big job, so for now just invoke the whole thing. The device420420+ * already having a driver bound means dma_configure has already run and421421+ * either found no IOMMU to wait for, or we're in its replay call right422422+ * now, so either way there's no point calling it again.423423+ */424424+ if (!dev->driver && dev->bus->dma_configure) {425425+ mutex_unlock(&iommu_probe_device_lock);426426+ dev->bus->dma_configure(dev);427427+ mutex_lock(&iommu_probe_device_lock);428428+ }429429+ /*430430+ * At this point, relevant devices either now have a fwspec which will431431+ * match ops registered with a non-NULL fwnode, or we can reasonably432432+ * assume that only one of Intel, AMD, s390, PAMU or legacy SMMUv2 can433433+ * be present, and that any of their registered instances has suitable434434+ * ops for probing, and thus cheekily co-opt the same mechanism.435435+ */436436+ ops = iommu_fwspec_ops(dev->iommu->fwspec);437437+ if (!ops) {438438+ ret = -ENODEV;439439+ goto err_free;440440+ }418441419442 if (!try_module_get(ops->owner)) {420443 ret = -EINVAL;···543514544515static int __iommu_probe_device(struct device *dev, struct list_head *group_list)545516{546546- const struct iommu_ops *ops;547517 struct iommu_group *group;548518 struct group_device *gdev;549519 int ret;550520551551- /*552552- * For FDT-based systems and ACPI IORT/VIOT, drivers register IOMMU553553- * instances with non-NULL fwnodes, and client devices should have been554554- * identified with a fwspec by this point. Otherwise, we can currently555555- * assume that only one of Intel, AMD, s390, PAMU or legacy SMMUv2 can556556- * be present, and that any of their registered instances has suitable557557- * ops for probing, and thus cheekily co-opt the same mechanism.558558- */559559- ops = iommu_fwspec_ops(dev_iommu_fwspec_get(dev));560560- if (!ops)561561- return -ENODEV;562521 /*563522 * Serialise to avoid races between IOMMU drivers registering in564523 * parallel and/or the "replay" calls from ACPI/OF code via client···560543 if (dev->iommu_group)561544 return 0;562545563563- ret = iommu_init_device(dev, ops);546546+ ret = iommu_init_device(dev);564547 if (ret)565548 return ret;549549+ /*550550+ * And if we do now see any replay calls, they would indicate someone551551+ * misusing the dma_configure path outside bus code.552552+ */553553+ if (dev->driver)554554+ dev_WARN(dev, "late IOMMU probe at driver bind, something fishy here!\n");566555567556 group = dev->iommu_group;568557 gdev = iommu_group_alloc_device(group, dev);···21702147 return dev->iommu_group->default_domain;21712148}2172214921502150+static void *iommu_make_pasid_array_entry(struct iommu_domain *domain,21512151+ struct iommu_attach_handle *handle)21522152+{21532153+ if (handle) {21542154+ handle->domain = domain;21552155+ return xa_tag_pointer(handle, IOMMU_PASID_ARRAY_HANDLE);21562156+ }21572157+21582158+ return xa_tag_pointer(domain, IOMMU_PASID_ARRAY_DOMAIN);21592159+}21602160+21732161static int __iommu_attach_group(struct iommu_domain *domain,21742162 struct iommu_group *group)21752163{···22202186 return ret;22212187}22222188EXPORT_SYMBOL_GPL(iommu_attach_group);22232223-22242224-/**22252225- * iommu_group_replace_domain - replace the domain that a group is attached to22262226- * @group: IOMMU group that will be attached to the new domain22272227- * @new_domain: new IOMMU domain to replace with22282228- *22292229- * This API allows the group to switch domains without being forced to go to22302230- * the blocking domain in-between.22312231- *22322232- * If the currently attached domain is a core domain (e.g. a default_domain),22332233- * it will act just like the iommu_attach_group().22342234- */22352235-int iommu_group_replace_domain(struct iommu_group *group,22362236- struct iommu_domain *new_domain)22372237-{22382238- int ret;22392239-22402240- if (!new_domain)22412241- return -EINVAL;22422242-22432243- mutex_lock(&group->mutex);22442244- ret = __iommu_group_set_domain(group, new_domain);22452245- mutex_unlock(&group->mutex);22462246- return ret;22472247-}22482248-EXPORT_SYMBOL_NS_GPL(iommu_group_replace_domain, "IOMMUFD_INTERNAL");2249218922502190static int __iommu_device_set_domain(struct iommu_group *group,22512191 struct device *dev,···28572849 dev_iommu_fwspec_set(dev, NULL);28582850 }28592851}28602860-EXPORT_SYMBOL_GPL(iommu_fwspec_free);2861285228622853int iommu_fwspec_add_ids(struct device *dev, const u32 *ids, int num_ids)28632854{···31043097 return 0;3105309831063099 mutex_lock(&group->mutex);31003100+ /* We may race against bus_iommu_probe() finalising groups here */31013101+ if (!group->default_domain) {31023102+ ret = -EPROBE_DEFER;31033103+ goto unlock_out;31043104+ }31073105 if (group->owner_cnt) {31083106 if (group->domain != group->default_domain || group->owner ||31093107 !xa_empty(&group->pasid_array)) {···33863374 struct iommu_group *group = dev->iommu_group;33873375 struct group_device *device;33883376 const struct iommu_ops *ops;33773377+ void *entry;33893378 int ret;3390337933913380 if (!group)···34103397 }34113398 }3412339934133413- if (handle)34143414- handle->domain = domain;34003400+ entry = iommu_make_pasid_array_entry(domain, handle);3415340134163416- ret = xa_insert(&group->pasid_array, pasid, handle, GFP_KERNEL);34023402+ /*34033403+ * Entry present is a failure case. Use xa_insert() instead of34043404+ * xa_reserve().34053405+ */34063406+ ret = xa_insert(&group->pasid_array, pasid, XA_ZERO_ENTRY, GFP_KERNEL);34173407 if (ret)34183408 goto out_unlock;3419340934203410 ret = __iommu_set_group_pasid(domain, group, pasid);34213421- if (ret)34223422- xa_erase(&group->pasid_array, pasid);34113411+ if (ret) {34123412+ xa_release(&group->pasid_array, pasid);34133413+ goto out_unlock;34143414+ }34153415+34163416+ /*34173417+ * The xa_insert() above reserved the memory, and the group->mutex is34183418+ * held, this cannot fail. The new domain cannot be visible until the34193419+ * operation succeeds as we cannot tolerate PRIs becoming concurrently34203420+ * queued and then failing attach.34213421+ */34223422+ WARN_ON(xa_is_err(xa_store(&group->pasid_array,34233423+ pasid, entry, GFP_KERNEL)));34243424+34233425out_unlock:34243426 mutex_unlock(&group->mutex);34253427 return ret;···35083480iommu_attach_handle_get(struct iommu_group *group, ioasid_t pasid, unsigned int type)35093481{35103482 struct iommu_attach_handle *handle;34833483+ void *entry;3511348435123485 xa_lock(&group->pasid_array);35133513- handle = xa_load(&group->pasid_array, pasid);35143514- if (!handle)34863486+ entry = xa_load(&group->pasid_array, pasid);34873487+ if (!entry || xa_pointer_tag(entry) != IOMMU_PASID_ARRAY_HANDLE) {35153488 handle = ERR_PTR(-ENOENT);35163516- else if (type && handle->domain->type != type)35173517- handle = ERR_PTR(-EBUSY);34893489+ } else {34903490+ handle = xa_untag_pointer(entry);34913491+ if (type && handle->domain->type != type)34923492+ handle = ERR_PTR(-EBUSY);34933493+ }35183494 xa_unlock(&group->pasid_array);3519349535203496 return handle;···35413509 struct iommu_group *group,35423510 struct iommu_attach_handle *handle)35433511{35123512+ void *entry;35443513 int ret;3545351435463546- if (handle)35473547- handle->domain = domain;35153515+ if (!handle)35163516+ return -EINVAL;3548351735493518 mutex_lock(&group->mutex);35503550- ret = xa_insert(&group->pasid_array, IOMMU_NO_PASID, handle, GFP_KERNEL);35193519+ entry = iommu_make_pasid_array_entry(domain, handle);35203520+ ret = xa_insert(&group->pasid_array,35213521+ IOMMU_NO_PASID, XA_ZERO_ENTRY, GFP_KERNEL);35513522 if (ret)35523552- goto err_unlock;35233523+ goto out_unlock;3553352435543525 ret = __iommu_attach_group(domain, group);35553555- if (ret)35563556- goto err_erase;35573557- mutex_unlock(&group->mutex);35263526+ if (ret) {35273527+ xa_release(&group->pasid_array, IOMMU_NO_PASID);35283528+ goto out_unlock;35293529+ }3558353035593559- return 0;35603560-err_erase:35613561- xa_erase(&group->pasid_array, IOMMU_NO_PASID);35623562-err_unlock:35313531+ /*35323532+ * The xa_insert() above reserved the memory, and the group->mutex is35333533+ * held, this cannot fail. The new domain cannot be visible until the35343534+ * operation succeeds as we cannot tolerate PRIs becoming concurrently35353535+ * queued and then failing attach.35363536+ */35373537+ WARN_ON(xa_is_err(xa_store(&group->pasid_array,35383538+ IOMMU_NO_PASID, entry, GFP_KERNEL)));35393539+35403540+out_unlock:35633541 mutex_unlock(&group->mutex);35643542 return ret;35653543}···35993557 * @new_domain: new IOMMU domain to replace with36003558 * @handle: attach handle36013559 *36023602- * This is a variant of iommu_group_replace_domain(). It allows the caller to36033603- * provide an attach handle for the new domain and use it when the domain is36043604- * attached.35603560+ * This API allows the group to switch domains without being forced to go to35613561+ * the blocking domain in-between. It allows the caller to provide an attach35623562+ * handle for the new domain and use it when the domain is attached.35633563+ *35643564+ * If the currently attached domain is a core domain (e.g. a default_domain),35653565+ * it will act just like the iommu_attach_group_handle().36053566 */36063567int iommu_replace_group_handle(struct iommu_group *group,36073568 struct iommu_domain *new_domain,36083569 struct iommu_attach_handle *handle)36093570{36103610- void *curr;35713571+ void *curr, *entry;36113572 int ret;3612357336133613- if (!new_domain)35743574+ if (!new_domain || !handle)36143575 return -EINVAL;3615357636163577 mutex_lock(&group->mutex);36173617- if (handle) {36183618- ret = xa_reserve(&group->pasid_array, IOMMU_NO_PASID, GFP_KERNEL);36193619- if (ret)36203620- goto err_unlock;36213621- handle->domain = new_domain;36223622- }35783578+ entry = iommu_make_pasid_array_entry(new_domain, handle);35793579+ ret = xa_reserve(&group->pasid_array, IOMMU_NO_PASID, GFP_KERNEL);35803580+ if (ret)35813581+ goto err_unlock;3623358236243583 ret = __iommu_group_set_domain(group, new_domain);36253584 if (ret)36263585 goto err_release;3627358636283628- curr = xa_store(&group->pasid_array, IOMMU_NO_PASID, handle, GFP_KERNEL);35873587+ curr = xa_store(&group->pasid_array, IOMMU_NO_PASID, entry, GFP_KERNEL);36293588 WARN_ON(xa_is_err(curr));3630358936313590 mutex_unlock(&group->mutex);···36393596 return ret;36403597}36413598EXPORT_SYMBOL_NS_GPL(iommu_replace_group_handle, "IOMMUFD_INTERNAL");35993599+36003600+#if IS_ENABLED(CONFIG_IRQ_MSI_IOMMU)36013601+/**36023602+ * iommu_dma_prepare_msi() - Map the MSI page in the IOMMU domain36033603+ * @desc: MSI descriptor, will store the MSI page36043604+ * @msi_addr: MSI target address to be mapped36053605+ *36063606+ * The implementation of sw_msi() should take msi_addr and map it to36073607+ * an IOVA in the domain and call msi_desc_set_iommu_msi_iova() with the36083608+ * mapping information.36093609+ *36103610+ * Return: 0 on success or negative error code if the mapping failed.36113611+ */36123612+int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr)36133613+{36143614+ struct device *dev = msi_desc_to_dev(desc);36153615+ struct iommu_group *group = dev->iommu_group;36163616+ int ret = 0;36173617+36183618+ if (!group)36193619+ return 0;36203620+36213621+ mutex_lock(&group->mutex);36223622+ if (group->domain && group->domain->sw_msi)36233623+ ret = group->domain->sw_msi(group->domain, desc, msi_addr);36243624+ mutex_unlock(&group->mutex);36253625+ return ret;36263626+}36273627+#endif /* CONFIG_IRQ_MSI_IOMMU */
+245-23
drivers/iommu/iommufd/device.c
···55#include <linux/iommufd.h>66#include <linux/slab.h>77#include <uapi/linux/iommufd.h>88+#include <linux/msi.h>89910#include "../iommu-priv.h"1011#include "io_pagetable.h"···294293}295294EXPORT_SYMBOL_NS_GPL(iommufd_device_to_id, "IOMMUFD");296295297297-static int iommufd_group_setup_msi(struct iommufd_group *igroup,298298- struct iommufd_hwpt_paging *hwpt_paging)296296+/*297297+ * Get a iommufd_sw_msi_map for the msi physical address requested by the irq298298+ * layer. The mapping to IOVA is global to the iommufd file descriptor, every299299+ * domain that is attached to a device using the same MSI parameters will use300300+ * the same IOVA.301301+ */302302+static __maybe_unused struct iommufd_sw_msi_map *303303+iommufd_sw_msi_get_map(struct iommufd_ctx *ictx, phys_addr_t msi_addr,304304+ phys_addr_t sw_msi_start)299305{300300- phys_addr_t sw_msi_start = igroup->sw_msi_start;306306+ struct iommufd_sw_msi_map *cur;307307+ unsigned int max_pgoff = 0;308308+309309+ lockdep_assert_held(&ictx->sw_msi_lock);310310+311311+ list_for_each_entry(cur, &ictx->sw_msi_list, sw_msi_item) {312312+ if (cur->sw_msi_start != sw_msi_start)313313+ continue;314314+ max_pgoff = max(max_pgoff, cur->pgoff + 1);315315+ if (cur->msi_addr == msi_addr)316316+ return cur;317317+ }318318+319319+ if (ictx->sw_msi_id >=320320+ BITS_PER_BYTE * sizeof_field(struct iommufd_sw_msi_maps, bitmap))321321+ return ERR_PTR(-EOVERFLOW);322322+323323+ cur = kzalloc(sizeof(*cur), GFP_KERNEL);324324+ if (!cur)325325+ return ERR_PTR(-ENOMEM);326326+327327+ cur->sw_msi_start = sw_msi_start;328328+ cur->msi_addr = msi_addr;329329+ cur->pgoff = max_pgoff;330330+ cur->id = ictx->sw_msi_id++;331331+ list_add_tail(&cur->sw_msi_item, &ictx->sw_msi_list);332332+ return cur;333333+}334334+335335+static int iommufd_sw_msi_install(struct iommufd_ctx *ictx,336336+ struct iommufd_hwpt_paging *hwpt_paging,337337+ struct iommufd_sw_msi_map *msi_map)338338+{339339+ unsigned long iova;340340+341341+ lockdep_assert_held(&ictx->sw_msi_lock);342342+343343+ iova = msi_map->sw_msi_start + msi_map->pgoff * PAGE_SIZE;344344+ if (!test_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap)) {345345+ int rc;346346+347347+ rc = iommu_map(hwpt_paging->common.domain, iova,348348+ msi_map->msi_addr, PAGE_SIZE,349349+ IOMMU_WRITE | IOMMU_READ | IOMMU_MMIO,350350+ GFP_KERNEL_ACCOUNT);351351+ if (rc)352352+ return rc;353353+ __set_bit(msi_map->id, hwpt_paging->present_sw_msi.bitmap);354354+ }355355+ return 0;356356+}357357+358358+/*359359+ * Called by the irq code if the platform translates the MSI address through the360360+ * IOMMU. msi_addr is the physical address of the MSI page. iommufd will361361+ * allocate a fd global iova for the physical page that is the same on all362362+ * domains and devices.363363+ */364364+#ifdef CONFIG_IRQ_MSI_IOMMU365365+int iommufd_sw_msi(struct iommu_domain *domain, struct msi_desc *desc,366366+ phys_addr_t msi_addr)367367+{368368+ struct device *dev = msi_desc_to_dev(desc);369369+ struct iommufd_hwpt_paging *hwpt_paging;370370+ struct iommu_attach_handle *raw_handle;371371+ struct iommufd_attach_handle *handle;372372+ struct iommufd_sw_msi_map *msi_map;373373+ struct iommufd_ctx *ictx;374374+ unsigned long iova;301375 int rc;302376303377 /*304304- * If the IOMMU driver gives a IOMMU_RESV_SW_MSI then it is asking us to305305- * call iommu_get_msi_cookie() on its behalf. This is necessary to setup306306- * the MSI window so iommu_dma_prepare_msi() can install pages into our307307- * domain after request_irq(). If it is not done interrupts will not308308- * work on this domain.309309- *310310- * FIXME: This is conceptually broken for iommufd since we want to allow311311- * userspace to change the domains, eg switch from an identity IOAS to a312312- * DMA IOAS. There is currently no way to create a MSI window that313313- * matches what the IRQ layer actually expects in a newly created314314- * domain.378378+ * It is safe to call iommu_attach_handle_get() here because the iommu379379+ * core code invokes this under the group mutex which also prevents any380380+ * change of the attach handle for the duration of this function.315381 */316316- if (sw_msi_start != PHYS_ADDR_MAX && !hwpt_paging->msi_cookie) {317317- rc = iommu_get_msi_cookie(hwpt_paging->common.domain,318318- sw_msi_start);382382+ iommu_group_mutex_assert(dev);383383+384384+ raw_handle =385385+ iommu_attach_handle_get(dev->iommu_group, IOMMU_NO_PASID, 0);386386+ if (IS_ERR(raw_handle))387387+ return 0;388388+ hwpt_paging = find_hwpt_paging(domain->iommufd_hwpt);389389+390390+ handle = to_iommufd_handle(raw_handle);391391+ /* No IOMMU_RESV_SW_MSI means no change to the msi_msg */392392+ if (handle->idev->igroup->sw_msi_start == PHYS_ADDR_MAX)393393+ return 0;394394+395395+ ictx = handle->idev->ictx;396396+ guard(mutex)(&ictx->sw_msi_lock);397397+ /*398398+ * The input msi_addr is the exact byte offset of the MSI doorbell, we399399+ * assume the caller has checked that it is contained with a MMIO region400400+ * that is secure to map at PAGE_SIZE.401401+ */402402+ msi_map = iommufd_sw_msi_get_map(handle->idev->ictx,403403+ msi_addr & PAGE_MASK,404404+ handle->idev->igroup->sw_msi_start);405405+ if (IS_ERR(msi_map))406406+ return PTR_ERR(msi_map);407407+408408+ rc = iommufd_sw_msi_install(ictx, hwpt_paging, msi_map);409409+ if (rc)410410+ return rc;411411+ __set_bit(msi_map->id, handle->idev->igroup->required_sw_msi.bitmap);412412+413413+ iova = msi_map->sw_msi_start + msi_map->pgoff * PAGE_SIZE;414414+ msi_desc_set_iommu_msi_iova(desc, iova, PAGE_SHIFT);415415+ return 0;416416+}417417+#endif418418+419419+static int iommufd_group_setup_msi(struct iommufd_group *igroup,420420+ struct iommufd_hwpt_paging *hwpt_paging)421421+{422422+ struct iommufd_ctx *ictx = igroup->ictx;423423+ struct iommufd_sw_msi_map *cur;424424+425425+ if (igroup->sw_msi_start == PHYS_ADDR_MAX)426426+ return 0;427427+428428+ /*429429+ * Install all the MSI pages the device has been using into the domain430430+ */431431+ guard(mutex)(&ictx->sw_msi_lock);432432+ list_for_each_entry(cur, &ictx->sw_msi_list, sw_msi_item) {433433+ int rc;434434+435435+ if (cur->sw_msi_start != igroup->sw_msi_start ||436436+ !test_bit(cur->id, igroup->required_sw_msi.bitmap))437437+ continue;438438+439439+ rc = iommufd_sw_msi_install(ictx, hwpt_paging, cur);319440 if (rc)320441 return rc;321321-322322- /*323323- * iommu_get_msi_cookie() can only be called once per domain,324324- * it returns -EBUSY on later calls.325325- */326326- hwpt_paging->msi_cookie = true;327442 }328443 return 0;329444}···467350 }468351 }469352 return 0;353353+}354354+355355+/* The device attach/detach/replace helpers for attach_handle */356356+357357+static int iommufd_hwpt_attach_device(struct iommufd_hw_pagetable *hwpt,358358+ struct iommufd_device *idev)359359+{360360+ struct iommufd_attach_handle *handle;361361+ int rc;362362+363363+ lockdep_assert_held(&idev->igroup->lock);364364+365365+ handle = kzalloc(sizeof(*handle), GFP_KERNEL);366366+ if (!handle)367367+ return -ENOMEM;368368+369369+ if (hwpt->fault) {370370+ rc = iommufd_fault_iopf_enable(idev);371371+ if (rc)372372+ goto out_free_handle;373373+ }374374+375375+ handle->idev = idev;376376+ rc = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,377377+ &handle->handle);378378+ if (rc)379379+ goto out_disable_iopf;380380+381381+ return 0;382382+383383+out_disable_iopf:384384+ if (hwpt->fault)385385+ iommufd_fault_iopf_disable(idev);386386+out_free_handle:387387+ kfree(handle);388388+ return rc;389389+}390390+391391+static struct iommufd_attach_handle *392392+iommufd_device_get_attach_handle(struct iommufd_device *idev)393393+{394394+ struct iommu_attach_handle *handle;395395+396396+ lockdep_assert_held(&idev->igroup->lock);397397+398398+ handle =399399+ iommu_attach_handle_get(idev->igroup->group, IOMMU_NO_PASID, 0);400400+ if (IS_ERR(handle))401401+ return NULL;402402+ return to_iommufd_handle(handle);403403+}404404+405405+static void iommufd_hwpt_detach_device(struct iommufd_hw_pagetable *hwpt,406406+ struct iommufd_device *idev)407407+{408408+ struct iommufd_attach_handle *handle;409409+410410+ handle = iommufd_device_get_attach_handle(idev);411411+ iommu_detach_group_handle(hwpt->domain, idev->igroup->group);412412+ if (hwpt->fault) {413413+ iommufd_auto_response_faults(hwpt, handle);414414+ iommufd_fault_iopf_disable(idev);415415+ }416416+ kfree(handle);417417+}418418+419419+static int iommufd_hwpt_replace_device(struct iommufd_device *idev,420420+ struct iommufd_hw_pagetable *hwpt,421421+ struct iommufd_hw_pagetable *old)422422+{423423+ struct iommufd_attach_handle *handle, *old_handle =424424+ iommufd_device_get_attach_handle(idev);425425+ int rc;426426+427427+ handle = kzalloc(sizeof(*handle), GFP_KERNEL);428428+ if (!handle)429429+ return -ENOMEM;430430+431431+ if (hwpt->fault && !old->fault) {432432+ rc = iommufd_fault_iopf_enable(idev);433433+ if (rc)434434+ goto out_free_handle;435435+ }436436+437437+ handle->idev = idev;438438+ rc = iommu_replace_group_handle(idev->igroup->group, hwpt->domain,439439+ &handle->handle);440440+ if (rc)441441+ goto out_disable_iopf;442442+443443+ if (old->fault) {444444+ iommufd_auto_response_faults(hwpt, old_handle);445445+ if (!hwpt->fault)446446+ iommufd_fault_iopf_disable(idev);447447+ }448448+ kfree(old_handle);449449+450450+ return 0;451451+452452+out_disable_iopf:453453+ if (hwpt->fault && !old->fault)454454+ iommufd_fault_iopf_disable(idev);455455+out_free_handle:456456+ kfree(handle);457457+ return rc;470458}471459472460int iommufd_hw_pagetable_attach(struct iommufd_hw_pagetable *hwpt,
+5-125
drivers/iommu/iommufd/fault.c
···1717#include "../iommu-priv.h"1818#include "iommufd_private.h"19192020-static int iommufd_fault_iopf_enable(struct iommufd_device *idev)2020+int iommufd_fault_iopf_enable(struct iommufd_device *idev)2121{2222 struct device *dev = idev->dev;2323 int ret;···5050 return ret;5151}52525353-static void iommufd_fault_iopf_disable(struct iommufd_device *idev)5353+void iommufd_fault_iopf_disable(struct iommufd_device *idev)5454{5555 mutex_lock(&idev->iopf_lock);5656 if (!WARN_ON(idev->iopf_enabled == 0)) {···6060 mutex_unlock(&idev->iopf_lock);6161}62626363-static int __fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,6464- struct iommufd_device *idev)6565-{6666- struct iommufd_attach_handle *handle;6767- int ret;6868-6969- handle = kzalloc(sizeof(*handle), GFP_KERNEL);7070- if (!handle)7171- return -ENOMEM;7272-7373- handle->idev = idev;7474- ret = iommu_attach_group_handle(hwpt->domain, idev->igroup->group,7575- &handle->handle);7676- if (ret)7777- kfree(handle);7878-7979- return ret;8080-}8181-8282-int iommufd_fault_domain_attach_dev(struct iommufd_hw_pagetable *hwpt,8383- struct iommufd_device *idev)8484-{8585- int ret;8686-8787- if (!hwpt->fault)8888- return -EINVAL;8989-9090- ret = iommufd_fault_iopf_enable(idev);9191- if (ret)9292- return ret;9393-9494- ret = __fault_domain_attach_dev(hwpt, idev);9595- if (ret)9696- iommufd_fault_iopf_disable(idev);9797-9898- return ret;9999-}100100-101101-static void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,102102- struct iommufd_attach_handle *handle)6363+void iommufd_auto_response_faults(struct iommufd_hw_pagetable *hwpt,6464+ struct iommufd_attach_handle *handle)10365{10466 struct iommufd_fault *fault = hwpt->fault;10567 struct iopf_group *group, *next;···95133 iopf_free_group(group);96134 }97135 mutex_unlock(&fault->mutex);9898-}9999-100100-static struct iommufd_attach_handle *101101-iommufd_device_get_attach_handle(struct iommufd_device *idev)102102-{103103- struct iommu_attach_handle *handle;104104-105105- handle = iommu_attach_handle_get(idev->igroup->group, IOMMU_NO_PASID, 0);106106- if (IS_ERR(handle))107107- return NULL;108108-109109- return to_iommufd_handle(handle);110110-}111111-112112-void iommufd_fault_domain_detach_dev(struct iommufd_hw_pagetable *hwpt,113113- struct iommufd_device *idev)114114-{115115- struct iommufd_attach_handle *handle;116116-117117- handle = iommufd_device_get_attach_handle(idev);118118- iommu_detach_group_handle(hwpt->domain, idev->igroup->group);119119- iommufd_auto_response_faults(hwpt, handle);120120- iommufd_fault_iopf_disable(idev);121121- kfree(handle);122122-}123123-124124-static int __fault_domain_replace_dev(struct iommufd_device *idev,125125- struct iommufd_hw_pagetable *hwpt,126126- struct iommufd_hw_pagetable *old)127127-{128128- struct iommufd_attach_handle *handle, *curr = NULL;129129- int ret;130130-131131- if (old->fault)132132- curr = iommufd_device_get_attach_handle(idev);133133-134134- if (hwpt->fault) {135135- handle = kzalloc(sizeof(*handle), GFP_KERNEL);136136- if (!handle)137137- return -ENOMEM;138138-139139- handle->idev = idev;140140- ret = iommu_replace_group_handle(idev->igroup->group,141141- hwpt->domain, &handle->handle);142142- } else {143143- ret = iommu_replace_group_handle(idev->igroup->group,144144- hwpt->domain, NULL);145145- }146146-147147- if (!ret && curr) {148148- iommufd_auto_response_faults(old, curr);149149- kfree(curr);150150- }151151-152152- return ret;153153-}154154-155155-int iommufd_fault_domain_replace_dev(struct iommufd_device *idev,156156- struct iommufd_hw_pagetable *hwpt,157157- struct iommufd_hw_pagetable *old)158158-{159159- bool iopf_off = !hwpt->fault && old->fault;160160- bool iopf_on = hwpt->fault && !old->fault;161161- int ret;162162-163163- if (iopf_on) {164164- ret = iommufd_fault_iopf_enable(idev);165165- if (ret)166166- return ret;167167- }168168-169169- ret = __fault_domain_replace_dev(idev, hwpt, old);170170- if (ret) {171171- if (iopf_on)172172- iommufd_fault_iopf_disable(idev);173173- return ret;174174- }175175-176176- if (iopf_off)177177- iommufd_fault_iopf_disable(idev);178178-179179- return 0;180136}181137182138void iommufd_fault_destroy(struct iommufd_object *obj)···329449 struct iommufd_hw_pagetable *hwpt;330450 struct iommufd_fault *fault;331451332332- hwpt = group->attach_handle->domain->fault_data;452452+ hwpt = group->attach_handle->domain->iommufd_hwpt;333453 fault = hwpt->fault;334454335455 spin_lock(&fault->lock);
+4-1
drivers/iommu/iommufd/hw_pagetable.c
···156156 goto out_abort;157157 }158158 }159159+ iommu_domain_set_sw_msi(hwpt->domain, iommufd_sw_msi);159160160161 /*161162 * Set the coherency mode before we do iopt_table_add_domain() as some···252251 goto out_abort;253252 }254253 hwpt->domain->owner = ops;254254+ iommu_domain_set_sw_msi(hwpt->domain, iommufd_sw_msi);255255256256 if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED)) {257257 rc = -EINVAL;···309307 goto out_abort;310308 }311309 hwpt->domain->owner = viommu->iommu_dev->ops;310310+ iommu_domain_set_sw_msi(hwpt->domain, iommufd_sw_msi);312311313312 if (WARN_ON_ONCE(hwpt->domain->type != IOMMU_DOMAIN_NESTED)) {314313 rc = -EINVAL;···409406 }410407 hwpt->fault = fault;411408 hwpt->domain->iopf_handler = iommufd_fault_iopf_handler;412412- hwpt->domain->fault_data = hwpt;413409 refcount_inc(&fault->obj.users);414410 iommufd_put_object(ucmd->ictx, &fault->obj);415411 }412412+ hwpt->domain->iommufd_hwpt = hwpt;416413417414 cmd->out_hwpt_id = hwpt->obj.id;418415 rc = iommufd_ucmd_respond(ucmd, sizeof(*cmd));
···116116int of_iommu_configure(struct device *dev, struct device_node *master_np,117117 const u32 *id)118118{119119+ bool dev_iommu_present;119120 int err;120121121122 if (!master_np)···128127 mutex_unlock(&iommu_probe_device_lock);129128 return 0;130129 }130130+ dev_iommu_present = dev->iommu;131131132132 /*133133 * We don't currently walk up the tree looking for a parent IOMMU.···149147 err = of_iommu_configure_device(master_np, dev, id);150148 }151149152152- if (err)150150+ if (err && dev_iommu_present)153151 iommu_fwspec_free(dev);152152+ else if (err && dev->iommu)153153+ dev_iommu_free(dev);154154 mutex_unlock(&iommu_probe_device_lock);155155156156- if (!err && dev->bus)156156+ /*157157+ * If we're not on the iommu_probe_device() path (as indicated by the158158+ * initial dev->iommu) then try to simulate it. This should no longer159159+ * happen unless of_dma_configure() is being misused outside bus code.160160+ */161161+ if (!err && dev->bus && !dev_iommu_present)157162 err = iommu_probe_device(dev);158163159164 if (err && err != -EPROBE_DEFER)
+26-35
drivers/iommu/rockchip-iommu.c
···8888 dma_addr_t dt_dma;8989 spinlock_t iommus_lock; /* lock for iommus list */9090 spinlock_t dt_lock; /* lock for modifying page directory table */9191+ struct device *dma_dev;91929293 struct iommu_domain domain;9394};···124123 struct rk_iommu *iommu;125124};126125127127-static struct device *dma_dev;128126static const struct rk_iommu_ops *rk_ops;129127static struct iommu_domain rk_identity_domain;130128···132132{133133 size_t size = count * sizeof(u32); /* count of u32 entry */134134135135- dma_sync_single_for_device(dma_dev, dma, size, DMA_TO_DEVICE);135135+ dma_sync_single_for_device(dom->dma_dev, dma, size, DMA_TO_DEVICE);136136}137137138138static struct rk_iommu_domain *to_rk_domain(struct iommu_domain *dom)···734734 if (!page_table)735735 return ERR_PTR(-ENOMEM);736736737737- pt_dma = dma_map_single(dma_dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);738738- if (dma_mapping_error(dma_dev, pt_dma)) {739739- dev_err(dma_dev, "DMA mapping error while allocating page table\n");737737+ pt_dma = dma_map_single(rk_domain->dma_dev, page_table, SPAGE_SIZE, DMA_TO_DEVICE);738738+ if (dma_mapping_error(rk_domain->dma_dev, pt_dma)) {739739+ dev_err(rk_domain->dma_dev, "DMA mapping error while allocating page table\n");740740 iommu_free_page(page_table);741741 return ERR_PTR(-ENOMEM);742742 }···10511051static struct iommu_domain *rk_iommu_domain_alloc_paging(struct device *dev)10521052{10531053 struct rk_iommu_domain *rk_domain;10541054-10551055- if (!dma_dev)10561056- return NULL;10541054+ struct rk_iommu *iommu;1057105510581056 rk_domain = kzalloc(sizeof(*rk_domain), GFP_KERNEL);10591057 if (!rk_domain)···10661068 if (!rk_domain->dt)10671069 goto err_free_domain;1068107010691069- rk_domain->dt_dma = dma_map_single(dma_dev, rk_domain->dt,10711071+ iommu = rk_iommu_from_dev(dev);10721072+ rk_domain->dma_dev = iommu->dev;10731073+ rk_domain->dt_dma = dma_map_single(rk_domain->dma_dev, rk_domain->dt,10701074 SPAGE_SIZE, DMA_TO_DEVICE);10711071- if (dma_mapping_error(dma_dev, rk_domain->dt_dma)) {10721072- dev_err(dma_dev, "DMA map error for DT\n");10751075+ if (dma_mapping_error(rk_domain->dma_dev, rk_domain->dt_dma)) {10761076+ dev_err(rk_domain->dma_dev, "DMA map error for DT\n");10731077 goto err_free_dt;10741078 }10751079···11051105 if (rk_dte_is_pt_valid(dte)) {11061106 phys_addr_t pt_phys = rk_ops->pt_address(dte);11071107 u32 *page_table = phys_to_virt(pt_phys);11081108- dma_unmap_single(dma_dev, pt_phys,11081108+ dma_unmap_single(rk_domain->dma_dev, pt_phys,11091109 SPAGE_SIZE, DMA_TO_DEVICE);11101110 iommu_free_page(page_table);11111111 }11121112 }1113111311141114- dma_unmap_single(dma_dev, rk_domain->dt_dma,11141114+ dma_unmap_single(rk_domain->dma_dev, rk_domain->dt_dma,11151115 SPAGE_SIZE, DMA_TO_DEVICE);11161116 iommu_free_page(rk_domain->dt);11171117···11481148 struct platform_device *iommu_dev;11491149 struct rk_iommudata *data;1150115011511151- data = devm_kzalloc(dma_dev, sizeof(*data), GFP_KERNEL);11511151+ iommu_dev = of_find_device_by_node(args->np);11521152+11531153+ data = devm_kzalloc(&iommu_dev->dev, sizeof(*data), GFP_KERNEL);11521154 if (!data)11531155 return -ENOMEM;11541154-11551155- iommu_dev = of_find_device_by_node(args->np);1156115611571157 data->iommu = platform_get_drvdata(iommu_dev);11581158 data->iommu->domain = &rk_identity_domain;···12561256 if (err)12571257 return err;1258125812591259- err = iommu_device_sysfs_add(&iommu->iommu, dev, NULL, dev_name(dev));12601260- if (err)12611261- goto err_unprepare_clocks;12621262-12631263- err = iommu_device_register(&iommu->iommu, &rk_iommu_ops, dev);12641264- if (err)12651265- goto err_remove_sysfs;12661266-12671267- /*12681268- * Use the first registered IOMMU device for domain to use with DMA12691269- * API, since a domain might not physically correspond to a single12701270- * IOMMU device..12711271- */12721272- if (!dma_dev)12731273- dma_dev = &pdev->dev;12741274-12751259 pm_runtime_enable(dev);1276126012771261 for (i = 0; i < iommu->num_irq; i++) {···1274129012751291 dma_set_mask_and_coherent(dev, rk_ops->dma_bit_mask);1276129212931293+ err = iommu_device_sysfs_add(&iommu->iommu, dev, NULL, dev_name(dev));12941294+ if (err)12951295+ goto err_pm_disable;12961296+12971297+ err = iommu_device_register(&iommu->iommu, &rk_iommu_ops, dev);12981298+ if (err)12991299+ goto err_remove_sysfs;13001300+12771301 return 0;12781278-err_pm_disable:12791279- pm_runtime_disable(dev);12801302err_remove_sysfs:12811303 iommu_device_sysfs_remove(&iommu->iommu);12821282-err_unprepare_clocks:13041304+err_pm_disable:13051305+ pm_runtime_disable(dev);12831306 clk_bulk_unprepare(iommu->num_clocks, iommu->clocks);12841307 return err;12851308}
···9999 bool coherent, set_map = false;100100 int ret;101101102102+ if (dev->dma_range_map) {103103+ dev_dbg(dev, "dma_range_map already set\n");104104+ goto skip_map;105105+ }106106+102107 if (np == dev->of_node)103108 bus_np = __of_get_dma_parent(np);104109 else···124119 end = dma_range_map_max(map);125120 set_map = true;126121 }127127-122122+skip_map:128123 /*129124 * If @dev is expected to be DMA-capable then the bus code that created130125 * it should have initialised its dma_mask pointer by this point. For
+2-1
drivers/pci/pci-driver.c
···1653165316541654 pci_put_host_bridge_device(bridge);1655165516561656- if (!ret && !driver->driver_managed_dma) {16561656+ /* @driver may not be valid when we're called from the IOMMU layer */16571657+ if (!ret && dev->driver && !driver->driver_managed_dma) {16571658 ret = iommu_device_use_default_domain(dev);16581659 if (ret)16591660 arch_teardown_dma_ops(dev);
···166166 * @dev: Pointer to the device which uses this descriptor167167 * @msg: The last set MSI message cached for reuse168168 * @affinity: Optional pointer to a cpu affinity mask for this descriptor169169+ * @iommu_msi_iova: Optional shifted IOVA from the IOMMU to override the msi_addr.170170+ * Only used if iommu_msi_shift != 0171171+ * @iommu_msi_shift: Indicates how many bits of the original address should be172172+ * preserved when using iommu_msi_iova.169173 * @sysfs_attr: Pointer to sysfs device attribute170174 *171175 * @write_msi_msg: Callback that may be called when the MSI message···188184 struct msi_msg msg;189185 struct irq_affinity_desc *affinity;190186#ifdef CONFIG_IRQ_MSI_IOMMU191191- const void *iommu_cookie;187187+ u64 iommu_msi_iova : 58;188188+ u64 iommu_msi_shift : 6;192189#endif193190#ifdef CONFIG_SYSFS194191 struct device_attribute *sysfs_attrs;···290285291286#define msi_desc_to_dev(desc) ((desc)->dev)292287288288+static inline void msi_desc_set_iommu_msi_iova(struct msi_desc *desc, u64 msi_iova,289289+ unsigned int msi_shift)290290+{293291#ifdef CONFIG_IRQ_MSI_IOMMU294294-static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)295295-{296296- return desc->iommu_cookie;297297-}298298-299299-static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,300300- const void *iommu_cookie)301301-{302302- desc->iommu_cookie = iommu_cookie;303303-}304304-#else305305-static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc)306306-{307307- return NULL;308308-}309309-310310-static inline void msi_desc_set_iommu_cookie(struct msi_desc *desc,311311- const void *iommu_cookie)312312-{313313-}292292+ desc->iommu_msi_iova = msi_iova >> msi_shift;293293+ desc->iommu_msi_shift = msi_shift;314294#endif295295+}296296+297297+/**298298+ * msi_msg_set_addr() - Set MSI address in an MSI message299299+ *300300+ * @desc: MSI descriptor that may carry an IOVA base address for MSI via @iommu_msi_iova/shift301301+ * @msg: Target MSI message to set its address_hi and address_lo302302+ * @msi_addr: Physical address to set the MSI message303303+ *304304+ * Notes:305305+ * - Override @msi_addr using the IOVA base address in the @desc if @iommu_msi_shift is set306306+ * - Otherwise, simply set @msi_addr to @msg307307+ */308308+static inline void msi_msg_set_addr(struct msi_desc *desc, struct msi_msg *msg,309309+ phys_addr_t msi_addr)310310+{311311+#ifdef CONFIG_IRQ_MSI_IOMMU312312+ if (desc->iommu_msi_shift) {313313+ u64 msi_iova = desc->iommu_msi_iova << desc->iommu_msi_shift;314314+315315+ msg->address_hi = upper_32_bits(msi_iova);316316+ msg->address_lo = lower_32_bits(msi_iova) |317317+ (msi_addr & ((1 << desc->iommu_msi_shift) - 1));318318+ return;319319+ }320320+#endif321321+ msg->address_hi = upper_32_bits(msi_addr);322322+ msg->address_lo = lower_32_bits(msi_addr);323323+}315324316325int msi_domain_insert_msi_desc(struct device *dev, unsigned int domid,317326 struct msi_desc *init_desc);
+1
kernel/irq/Kconfig
···9696 bool9797 select IRQ_DOMAIN_HIERARCHY98989999+# irqchip drivers should select this if they call iommu_dma_prepare_msi()99100config IRQ_MSI_IOMMU100101 bool101102