driver core: Replace dev->dma_iommu with dev_dma_iommu()

In C, bitfields are not necessarily safe to modify from multiple
threads without locking. Switch "dma_iommu" over to the "flags" field
so modifications are safe.

Cc: Leon Romanovsky <leon@kernel.org>
Cc: Robin Murphy <robin.murphy@arm.com>
Cc: Christoph Hellwig <hch@lst.de>
Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://patch.msgid.link/20260406162231.v5.3.Id20d5973cbff542fea290e13177e9423f5d81342@changeid
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
Douglas Anderson 2026-04-06 16:22:56 -07:00 committed by Danilo Krummrich
parent f2648bb315
commit 7fa1e85cfe
4 changed files with 14 additions and 12 deletions

View File

@ -2142,18 +2142,21 @@ EXPORT_SYMBOL_GPL(dma_iova_destroy);
void iommu_setup_dma_ops(struct device *dev, struct iommu_domain *domain)
{
bool dma_iommu;
if (dev_is_pci(dev))
dev->iommu->pci_32bit_workaround = !iommu_dma_forcedac;
dev->dma_iommu = iommu_is_dma_domain(domain);
if (dev->dma_iommu && iommu_dma_init_domain(domain, dev))
dma_iommu = iommu_is_dma_domain(domain);
dev_assign_dma_iommu(dev, dma_iommu);
if (dma_iommu && iommu_dma_init_domain(domain, dev))
goto out_err;
return;
out_err:
pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops\n",
dev_name(dev));
dev->dma_iommu = false;
dev_clear_dma_iommu(dev);
}
static bool has_msi_cookie(const struct iommu_domain *domain)

View File

@ -590,9 +590,8 @@ static void iommu_deinit_device(struct device *dev)
dev->iommu_group = NULL;
module_put(ops->owner);
dev_iommu_free(dev);
#ifdef CONFIG_IOMMU_DMA
dev->dma_iommu = false;
#endif
if (IS_ENABLED(CONFIG_IOMMU_DMA))
dev_clear_dma_iommu(dev);
}
static struct iommu_domain *pasid_array_entry_to_domain(void *entry)

View File

@ -515,11 +515,14 @@ struct device_physical_location {
* @DEV_FLAG_CAN_MATCH: The device has matched with a driver at least once or it
* is in a bus (like AMBA) which can't check for matching drivers
* until other devices probe successfully.
* @DEV_FLAG_DMA_IOMMU: Device is using default IOMMU implementation for DMA and
* doesn't rely on dma_ops structure.
* @DEV_FLAG_COUNT: Number of defined struct_device_flags.
*/
enum struct_device_flags {
DEV_FLAG_READY_TO_PROBE = 0,
DEV_FLAG_CAN_MATCH = 1,
DEV_FLAG_DMA_IOMMU = 2,
DEV_FLAG_COUNT
};
@ -614,8 +617,6 @@ enum struct_device_flags {
* for dma allocations. This flag is managed by the dma ops
* instance from ->dma_supported.
* @dma_skip_sync: DMA sync operations can be skipped for coherent buffers.
* @dma_iommu: Device is using default IOMMU implementation for DMA and
* doesn't rely on dma_ops structure.
* @flags: DEV_FLAG_XXX flags. Use atomic bitfield operations to modify.
*
* At the lowest level, every device in a Linux system is represented by an
@ -735,9 +736,6 @@ struct device {
#ifdef CONFIG_DMA_NEED_SYNC
bool dma_skip_sync:1;
#endif
#ifdef CONFIG_IOMMU_DMA
bool dma_iommu:1;
#endif
DECLARE_BITMAP(flags, DEV_FLAG_COUNT);
};
@ -766,6 +764,7 @@ static inline bool dev_test_and_set_##accessor_name(struct device *dev) \
__create_dev_flag_accessors(ready_to_probe, DEV_FLAG_READY_TO_PROBE);
__create_dev_flag_accessors(can_match, DEV_FLAG_CAN_MATCH);
__create_dev_flag_accessors(dma_iommu, DEV_FLAG_DMA_IOMMU);
#undef __create_dev_flag_accessors

View File

@ -7,12 +7,13 @@
#ifndef _LINUX_IOMMU_DMA_H
#define _LINUX_IOMMU_DMA_H
#include <linux/device.h>
#include <linux/dma-direction.h>
#ifdef CONFIG_IOMMU_DMA
static inline bool use_dma_iommu(struct device *dev)
{
return dev->dma_iommu;
return dev_dma_iommu(dev);
}
#else
static inline bool use_dma_iommu(struct device *dev)