On 1/6/2023 3:33 AM, Jason Gunthorpe wrote:
Compute the isolated_msi over all the devices in the IOMMU group because
iommufd and vfio both need to know that the entire group is isolated
before granting access to it.
Tested-by: Matthew Rosato <mjrosato@xxxxxxxxxxxxx>
Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx>
Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx>
---
drivers/iommu/iommu.c | 26 ++++++++++++++++++++++++++
include/linux/iommu.h | 1 +
2 files changed, 27 insertions(+)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index de91dd88705bd3..7f744904e02f4d 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -30,6 +30,7 @@
#include <linux/cc_platform.h>
#include <trace/events/iommu.h>
#include <linux/sched/mm.h>
+#include <linux/msi.h>
#include "dma-iommu.h"
@@ -1897,6 +1898,31 @@ bool device_iommu_capable(struct device *dev, enum iommu_cap cap)
}
EXPORT_SYMBOL_GPL(device_iommu_capable);
+/**
+ * iommu_group_has_isolated_msi() - Compute msi_device_has_isolated_msi()
+ * for a group
+ * @group: Group to query
+ *
+ * IOMMU groups should not have differing values of
+ * msi_device_has_isolated_msi() for devices in a group. However nothing
+ * directly prevents this, so ensure mistakes don't result in isolation failures
+ * by checking that all the devices are the same.
+ */
+bool iommu_group_has_isolated_msi(struct iommu_group *group)
+{
+ struct group_device *group_dev;
+ bool ret = true;
+
+ mutex_lock(&group->mutex);
+ list_for_each_entry(group_dev, &group->devices, list)
+ ret &= msi_device_has_isolated_msi(group_dev->dev) ||
+ device_iommu_capable(group_dev->dev,
+ IOMMU_CAP_INTR_REMAP);
+ mutex_unlock(&group->mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iommu_group_has_isolated_msi);
+
/**
* iommu_set_fault_handler() - set a fault handler for an iommu domain
* @domain: iommu domain
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 46e1347bfa2286..9b7a9fa5ad28d3 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -455,6 +455,7 @@ static inline const struct iommu_ops *dev_iommu_ops(struct device *dev)
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_group_has_isolated_msi(struct iommu_group *group);
This lacks a static inline definition when CONFIG_IOMMU_API is false?
extern struct iommu_domain *iommu_domain_alloc(struct bus_type *bus);
extern struct iommu_group *iommu_group_get_by_id(int id);
extern void iommu_domain_free(struct iommu_domain *domain);
Others look good to me. With above addressed,
Reviewed-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>
--
Best regards,
baolu