Commit b67483b3 authored by Robin Murphy's avatar Robin Murphy Committed by Joerg Roedel

iommu/dma: Centralise iommu_setup_dma_ops()

It's somewhat hard to see, but arm64's arch_setup_dma_ops() should only
ever call iommu_setup_dma_ops() after a successful iommu_probe_device(),
which means there should be no harm in achieving the same order of
operations by running it off the back of iommu_probe_device() itself.
This then puts it in line with the x86 and s390 .probe_finalize bodges,
letting us pull it all into the main flow properly. As a bonus this lets
us fold in and de-scope the PCI workaround setup as well.

At this point we can also then pull the call up inside the group mutex,
and avoid having to think about whether iommu_group_store_type() could
theoretically race and free the domain if iommu_setup_dma_ops() ran just
*before* iommu_device_use_default_domain() claims it... Furthermore we
replace one .probe_finalize call completely, since the only remaining
implementations are now one which only needs to run once for the initial
boot-time probe, and two which themselves render that path unreachable.

This leaves us a big step closer to realistically being able to unpick
the variety of different things that iommu_setup_dma_ops() has been
muddling together, and further streamline iommu-dma into core API flows
in future.

Reviewed-by: Lu Baolu <baolu.lu@linux.intel.com> # For Intel IOMMU
Reviewed-by: default avatarJason Gunthorpe <jgg@nvidia.com>
Tested-by: default avatarHanjun Guo <guohanjun@huawei.com>
Signed-off-by: default avatarRobin Murphy <robin.murphy@arm.com>
Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Link: https://lore.kernel.org/r/bebea331c1d688b34d9862eefd5ede47503961b8.1713523152.git.robin.murphy@arm.comSigned-off-by: default avatarJoerg Roedel <jroedel@suse.de>
parent ad4750b0
...@@ -58,8 +58,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size, ...@@ -58,8 +58,6 @@ void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
ARCH_DMA_MINALIGN, cls); ARCH_DMA_MINALIGN, cls);
dev->dma_coherent = coherent; dev->dma_coherent = coherent;
if (device_iommu_mapped(dev))
iommu_setup_dma_ops(dev, dma_base, dma_base + size - 1);
xen_setup_dma_ops(dev); xen_setup_dma_ops(dev);
} }
...@@ -2175,13 +2175,6 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev) ...@@ -2175,13 +2175,6 @@ static struct iommu_device *amd_iommu_probe_device(struct device *dev)
return iommu_dev; return iommu_dev;
} }
static void amd_iommu_probe_finalize(struct device *dev)
{
/* Domains are initialized for this device - have a look what we ended up with */
set_dma_ops(dev, NULL);
iommu_setup_dma_ops(dev, 0, U64_MAX);
}
static void amd_iommu_release_device(struct device *dev) static void amd_iommu_release_device(struct device *dev)
{ {
struct amd_iommu *iommu; struct amd_iommu *iommu;
...@@ -2784,7 +2777,6 @@ const struct iommu_ops amd_iommu_ops = { ...@@ -2784,7 +2777,6 @@ const struct iommu_ops amd_iommu_ops = {
.domain_alloc_user = amd_iommu_domain_alloc_user, .domain_alloc_user = amd_iommu_domain_alloc_user,
.probe_device = amd_iommu_probe_device, .probe_device = amd_iommu_probe_device,
.release_device = amd_iommu_release_device, .release_device = amd_iommu_release_device,
.probe_finalize = amd_iommu_probe_finalize,
.device_group = amd_iommu_device_group, .device_group = amd_iommu_device_group,
.get_resv_regions = amd_iommu_get_resv_regions, .get_resv_regions = amd_iommu_get_resv_regions,
.is_attach_deferred = amd_iommu_is_attach_deferred, .is_attach_deferred = amd_iommu_is_attach_deferred,
......
...@@ -1741,25 +1741,20 @@ static const struct dma_map_ops iommu_dma_ops = { ...@@ -1741,25 +1741,20 @@ static const struct dma_map_ops iommu_dma_ops = {
.max_mapping_size = iommu_dma_max_mapping_size, .max_mapping_size = iommu_dma_max_mapping_size,
}; };
/* void iommu_setup_dma_ops(struct device *dev)
* The IOMMU core code allocates the default DMA domain, which the underlying
* IOMMU driver needs to support via the dma-iommu layer.
*/
void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
{ {
struct iommu_domain *domain = iommu_get_domain_for_dev(dev); struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
if (!domain) if (dev_is_pci(dev))
goto out_err; dev->iommu->pci_32bit_workaround = !iommu_dma_forcedac;
/*
* The IOMMU core code allocates the default DMA domain, which the
* underlying IOMMU driver needs to support via the dma-iommu layer.
*/
if (iommu_is_dma_domain(domain)) { if (iommu_is_dma_domain(domain)) {
if (iommu_dma_init_domain(domain, dev)) if (iommu_dma_init_domain(domain, dev))
goto out_err; goto out_err;
dev->dma_ops = &iommu_dma_ops; dev->dma_ops = &iommu_dma_ops;
} else if (dev->dma_ops == &iommu_dma_ops) {
/* Clean up if we've switched *from* a DMA domain */
dev->dma_ops = NULL;
} }
return; return;
...@@ -1767,7 +1762,6 @@ void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit) ...@@ -1767,7 +1762,6 @@ void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n", pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
dev_name(dev)); dev_name(dev));
} }
EXPORT_SYMBOL_GPL(iommu_setup_dma_ops);
static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev, static struct iommu_dma_msi_page *iommu_dma_get_msi_page(struct device *dev,
phys_addr_t msi_addr, struct iommu_domain *domain) phys_addr_t msi_addr, struct iommu_domain *domain)
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#ifdef CONFIG_IOMMU_DMA #ifdef CONFIG_IOMMU_DMA
void iommu_setup_dma_ops(struct device *dev);
int iommu_get_dma_cookie(struct iommu_domain *domain); int iommu_get_dma_cookie(struct iommu_domain *domain);
void iommu_put_dma_cookie(struct iommu_domain *domain); void iommu_put_dma_cookie(struct iommu_domain *domain);
...@@ -17,13 +19,13 @@ int iommu_dma_init_fq(struct iommu_domain *domain); ...@@ -17,13 +19,13 @@ int iommu_dma_init_fq(struct iommu_domain *domain);
void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list); void iommu_dma_get_resv_regions(struct device *dev, struct list_head *list);
extern bool iommu_dma_forcedac; extern bool iommu_dma_forcedac;
static inline void iommu_dma_set_pci_32bit_workaround(struct device *dev)
{
dev->iommu->pci_32bit_workaround = !iommu_dma_forcedac;
}
#else /* CONFIG_IOMMU_DMA */ #else /* CONFIG_IOMMU_DMA */
static inline void iommu_setup_dma_ops(struct device *dev)
{
}
static inline int iommu_dma_init_fq(struct iommu_domain *domain) static inline int iommu_dma_init_fq(struct iommu_domain *domain)
{ {
return -EINVAL; return -EINVAL;
...@@ -42,9 +44,5 @@ static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_he ...@@ -42,9 +44,5 @@ static inline void iommu_dma_get_resv_regions(struct device *dev, struct list_he
{ {
} }
static inline void iommu_dma_set_pci_32bit_workaround(struct device *dev)
{
}
#endif /* CONFIG_IOMMU_DMA */ #endif /* CONFIG_IOMMU_DMA */
#endif /* __DMA_IOMMU_H */ #endif /* __DMA_IOMMU_H */
...@@ -4349,12 +4349,6 @@ static void intel_iommu_release_device(struct device *dev) ...@@ -4349,12 +4349,6 @@ static void intel_iommu_release_device(struct device *dev)
set_dma_ops(dev, NULL); set_dma_ops(dev, NULL);
} }
static void intel_iommu_probe_finalize(struct device *dev)
{
set_dma_ops(dev, NULL);
iommu_setup_dma_ops(dev, 0, U64_MAX);
}
static void intel_iommu_get_resv_regions(struct device *device, static void intel_iommu_get_resv_regions(struct device *device,
struct list_head *head) struct list_head *head)
{ {
...@@ -4834,7 +4828,6 @@ const struct iommu_ops intel_iommu_ops = { ...@@ -4834,7 +4828,6 @@ const struct iommu_ops intel_iommu_ops = {
.domain_alloc = intel_iommu_domain_alloc, .domain_alloc = intel_iommu_domain_alloc,
.domain_alloc_user = intel_iommu_domain_alloc_user, .domain_alloc_user = intel_iommu_domain_alloc_user,
.probe_device = intel_iommu_probe_device, .probe_device = intel_iommu_probe_device,
.probe_finalize = intel_iommu_probe_finalize,
.release_device = intel_iommu_release_device, .release_device = intel_iommu_release_device,
.get_resv_regions = intel_iommu_get_resv_regions, .get_resv_regions = intel_iommu_get_resv_regions,
.device_group = intel_iommu_device_group, .device_group = intel_iommu_device_group,
......
...@@ -581,10 +581,11 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list ...@@ -581,10 +581,11 @@ static int __iommu_probe_device(struct device *dev, struct list_head *group_list
if (list_empty(&group->entry)) if (list_empty(&group->entry))
list_add_tail(&group->entry, group_list); list_add_tail(&group->entry, group_list);
} }
mutex_unlock(&group->mutex);
if (dev_is_pci(dev)) if (group->default_domain)
iommu_dma_set_pci_32bit_workaround(dev); iommu_setup_dma_ops(dev);
mutex_unlock(&group->mutex);
return 0; return 0;
...@@ -1828,6 +1829,8 @@ int bus_iommu_probe(const struct bus_type *bus) ...@@ -1828,6 +1829,8 @@ int bus_iommu_probe(const struct bus_type *bus)
mutex_unlock(&group->mutex); mutex_unlock(&group->mutex);
return ret; return ret;
} }
for_each_group_device(group, gdev)
iommu_setup_dma_ops(gdev->dev);
mutex_unlock(&group->mutex); mutex_unlock(&group->mutex);
/* /*
...@@ -3066,18 +3069,9 @@ static ssize_t iommu_group_store_type(struct iommu_group *group, ...@@ -3066,18 +3069,9 @@ static ssize_t iommu_group_store_type(struct iommu_group *group,
if (ret) if (ret)
goto out_unlock; goto out_unlock;
/*
* Release the mutex here because ops->probe_finalize() call-back of
* some vendor IOMMU drivers calls arm_iommu_attach_device() which
* in-turn might call back into IOMMU core code, where it tries to take
* group->mutex, resulting in a deadlock.
*/
mutex_unlock(&group->mutex);
/* Make sure dma_ops is appropriatley set */ /* Make sure dma_ops is appropriatley set */
for_each_group_device(group, gdev) for_each_group_device(group, gdev)
iommu_group_do_probe_finalize(gdev->dev); iommu_setup_dma_ops(gdev->dev);
return count;
out_unlock: out_unlock:
mutex_unlock(&group->mutex); mutex_unlock(&group->mutex);
......
...@@ -695,11 +695,6 @@ static size_t s390_iommu_unmap_pages(struct iommu_domain *domain, ...@@ -695,11 +695,6 @@ static size_t s390_iommu_unmap_pages(struct iommu_domain *domain,
return size; return size;
} }
static void s390_iommu_probe_finalize(struct device *dev)
{
iommu_setup_dma_ops(dev, 0, U64_MAX);
}
struct zpci_iommu_ctrs *zpci_get_iommu_ctrs(struct zpci_dev *zdev) struct zpci_iommu_ctrs *zpci_get_iommu_ctrs(struct zpci_dev *zdev)
{ {
if (!zdev || !zdev->s390_domain) if (!zdev || !zdev->s390_domain)
...@@ -785,7 +780,6 @@ static const struct iommu_ops s390_iommu_ops = { ...@@ -785,7 +780,6 @@ static const struct iommu_ops s390_iommu_ops = {
.capable = s390_iommu_capable, .capable = s390_iommu_capable,
.domain_alloc_paging = s390_domain_alloc_paging, .domain_alloc_paging = s390_domain_alloc_paging,
.probe_device = s390_iommu_probe_device, .probe_device = s390_iommu_probe_device,
.probe_finalize = s390_iommu_probe_finalize,
.release_device = s390_iommu_release_device, .release_device = s390_iommu_release_device,
.device_group = generic_device_group, .device_group = generic_device_group,
.pgsize_bitmap = SZ_4K, .pgsize_bitmap = SZ_4K,
......
...@@ -1025,15 +1025,6 @@ static struct iommu_device *viommu_probe_device(struct device *dev) ...@@ -1025,15 +1025,6 @@ static struct iommu_device *viommu_probe_device(struct device *dev)
return ERR_PTR(ret); return ERR_PTR(ret);
} }
static void viommu_probe_finalize(struct device *dev)
{
#ifndef CONFIG_ARCH_HAS_SETUP_DMA_OPS
/* First clear the DMA ops in case we're switching from a DMA domain */
set_dma_ops(dev, NULL);
iommu_setup_dma_ops(dev, 0, U64_MAX);
#endif
}
static void viommu_release_device(struct device *dev) static void viommu_release_device(struct device *dev)
{ {
struct viommu_endpoint *vdev = dev_iommu_priv_get(dev); struct viommu_endpoint *vdev = dev_iommu_priv_get(dev);
...@@ -1073,7 +1064,6 @@ static struct iommu_ops viommu_ops = { ...@@ -1073,7 +1064,6 @@ static struct iommu_ops viommu_ops = {
.capable = viommu_capable, .capable = viommu_capable,
.domain_alloc = viommu_domain_alloc, .domain_alloc = viommu_domain_alloc,
.probe_device = viommu_probe_device, .probe_device = viommu_probe_device,
.probe_finalize = viommu_probe_finalize,
.release_device = viommu_release_device, .release_device = viommu_release_device,
.device_group = viommu_device_group, .device_group = viommu_device_group,
.get_resv_regions = viommu_get_resv_regions, .get_resv_regions = viommu_get_resv_regions,
......
...@@ -1446,9 +1446,6 @@ static inline void iommu_debugfs_setup(void) {} ...@@ -1446,9 +1446,6 @@ static inline void iommu_debugfs_setup(void) {}
#ifdef CONFIG_IOMMU_DMA #ifdef CONFIG_IOMMU_DMA
#include <linux/msi.h> #include <linux/msi.h>
/* Setup call for arch DMA mapping code */
void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit);
int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base); int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base);
int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr); int iommu_dma_prepare_msi(struct msi_desc *desc, phys_addr_t msi_addr);
...@@ -1459,10 +1456,6 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg); ...@@ -1459,10 +1456,6 @@ void iommu_dma_compose_msi_msg(struct msi_desc *desc, struct msi_msg *msg);
struct msi_desc; struct msi_desc;
struct msi_msg; struct msi_msg;
static inline void iommu_setup_dma_ops(struct device *dev, u64 dma_base, u64 dma_limit)
{
}
static inline int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base) static inline int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
{ {
return -ENODEV; return -ENODEV;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment