Skip to content

Commit

Permalink
iommu: Introduce device_iommu_capable()
Browse files Browse the repository at this point in the history
iommu_capable() only really works for systems where all IOMMU instances
are completely homogeneous, and all devices are IOMMU-mapped. Implement
the new variant which will be able to give a more accurate answer for
whichever device the caller is actually interested in, and even more so
once all the external users have been converted and we can reliably pass
the device pointer through the internal driver interface too.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/8407eb9586677995b7a9fd70d0fd82d85929a9bb.1650878781.git.robin.murphy@arm.com
Signed-off-by: Joerg Roedel <jroedel@suse.de>
  • Loading branch information
Robin Murphy authored and Joerg Roedel committed Apr 28, 2022
1 parent f316ba0 commit ed36d04
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
23 changes: 23 additions & 0 deletions drivers/iommu/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1906,6 +1906,29 @@ bool iommu_present(struct bus_type *bus)
}
EXPORT_SYMBOL_GPL(iommu_present);

/**
* device_iommu_capable() - check for a general IOMMU capability
* @dev: device to which the capability would be relevant, if available
* @cap: IOMMU capability
*
* Return: true if an IOMMU is present and supports the given capability
* for the given device, otherwise false.
*/
bool device_iommu_capable(struct device *dev, enum iommu_cap cap)
{
const struct iommu_ops *ops;

if (!dev->iommu || !dev->iommu->iommu_dev)
return false;

ops = dev_iommu_ops(dev);
if (!ops->capable)
return false;

return ops->capable(cap);
}
EXPORT_SYMBOL_GPL(device_iommu_capable);

bool iommu_capable(struct bus_type *bus, enum iommu_cap cap)
{
if (!bus->iommu_ops || !bus->iommu_ops->capable)
Expand Down
6 changes: 6 additions & 0 deletions include/linux/iommu.h
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,7 @@ static inline const struct iommu_ops *dev_iommu_ops(struct device *dev)
extern int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops);
extern int bus_iommu_probe(struct bus_type *bus);
extern bool iommu_present(struct bus_type *bus);
extern bool device_iommu_capable(struct device *dev, enum iommu_cap cap);
extern bool iommu_capable(struct bus_type *bus, enum iommu_cap cap);
extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
extern struct iommu_group *iommu_group_get_by_id(int id);
Expand Down Expand Up @@ -689,6 +690,11 @@ static inline bool iommu_present(struct bus_type *bus)
return false;
}

static inline bool device_iommu_capable(struct device *dev, enum iommu_cap cap)
{
return false;
}

static inline bool iommu_capable(struct bus_type *bus, enum iommu_cap cap)
{
return false;
Expand Down

0 comments on commit ed36d04

Please sign in to comment.