[RFC PATCH 4/4] iommu: Determine default domain type before allocating domain

Lu Baolu
2020-01-01T05:37:35Z

Determine the default domain type for each group and use it to
allocate the iommu domain.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/iommu/iommu.c | 35 ++++++++++++++++++++++++++++++++---
1 file changed, 32 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 716326a2ee5b..fc1df1acbd25 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -43,6 +43,7 @@ struct iommu_group {
int id;
struct iommu_domain *default_domain;
struct iommu_domain *domain;
+ unsigned int def_domain_type;
};

struct group_device {
@@ -1383,6 +1384,33 @@ static int alloc_iommu_group(struct device *dev, void *data)
return 0;
}

+static void get_group_def_domain_type(struct iommu_group *group)
+{
+ struct group_device *tmp = NULL;
+
+ mutex_lock(&group->mutex);
+ list_for_each_entry(tmp, &group->devices, list) {
+ struct device *dev = tmp->dev;
+
+ /*
+ * If there are any untrusted devices in the group, force
+ * IOMMU_DOMAIN_DMA to prevent DMA attack from malicious
+ * devices.
+ */
+ if (dev_is_pci(dev) && to_pci_dev(dev)->untrusted) {
+ group->def_domain_type = IOMMU_DOMAIN_DMA;
+ break;
+ }
+
+ if (dev->iommu_passthrough)
+ group->def_domain_type = IOMMU_DOMAIN_IDENTITY;
+ }
+ mutex_unlock(&group->mutex);
+
+ if (!group->def_domain_type)
+ group->def_domain_type = iommu_def_domain_type;
+}
+
/**
* iommu_group_get_for_dev - Find or create the IOMMU group for a device
* @dev: target device
@@ -1412,13 +1440,14 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
if (!group->default_domain) {
struct iommu_domain *dom;

- dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
- if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
+ get_group_def_domain_type(group);
+ dom = __iommu_domain_alloc(dev->bus, group->def_domain_type);
+ if (!dom && group->def_domain_type != IOMMU_DOMAIN_DMA) {
dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
if (dom) {
dev_warn(dev,
"failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
- iommu_def_domain_type);
+ group->def_domain_type);
}
}

--
2.17.1