linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7] iommu/vt-d: Some cleanups
@ 2022-11-03  5:53 Lu Baolu
  2022-11-03  5:53 ` [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path Lu Baolu
                   ` (6 more replies)
  0 siblings, 7 replies; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

Hi,

This series includes some cleanups in the Intel IOMMU implementation
after the IOMMU core implemented the blocking domain. The cleanup work
is mainly in the attach_dev/device_probe/device_release paths.

Please help to review.

Best regards,
baolu

Lu Baolu (7):
  iommu/vt-d: Allocate pasid table in device probe path
  iommu/vt-d: Add blocking domain support
  iommu/vt-d: Use device_block_translation() in dev_attach error path
  iommu/vt-d: Fold dmar_remove_one_dev_info() into its caller
  iommu/vt-d: Rename domain_add_dev_info()
  iommu/vt-d: Remove unnecessary domain_context_mapped()
  iommu/vt-d: Use real field for indication of first level

 drivers/iommu/intel/iommu.h |  15 +--
 drivers/iommu/intel/iommu.c | 190 ++++++++++++++++--------------------
 2 files changed, 89 insertions(+), 116 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path
  2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
@ 2022-11-03  5:53 ` Lu Baolu
  2022-11-04  2:06   ` Tian, Kevin
  2022-11-03  5:53 ` [PATCH 2/7] iommu/vt-d: Add blocking domain support Lu Baolu
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

Whether or not a domain is attached to the device, the pasid table should
always be valid as long as it has been probed. This moves the pasid table
allocation from the domain attaching device path to device probe path and
frees it in the device release path.

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

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index a934a46bb9e6..e28faba1095f 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2477,13 +2477,6 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
 
 	/* PASID table is mandatory for a PCI device in scalable mode. */
 	if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
-		ret = intel_pasid_alloc_table(dev);
-		if (ret) {
-			dev_err(dev, "PASID table allocation failed\n");
-			dmar_remove_one_dev_info(dev);
-			return ret;
-		}
-
 		/* Setup the PASID entry for requests without PASID: */
 		if (hw_pass_through && domain_type_is_si(domain))
 			ret = intel_pasid_setup_pass_through(iommu, domain,
@@ -4108,7 +4101,6 @@ static void dmar_remove_one_dev_info(struct device *dev)
 
 		iommu_disable_dev_iotlb(info);
 		domain_context_clear(info);
-		intel_pasid_free_table(info->dev);
 	}
 
 	spin_lock_irqsave(&domain->lock, flags);
@@ -4470,6 +4462,7 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 	struct device_domain_info *info;
 	struct intel_iommu *iommu;
 	u8 bus, devfn;
+	int ret;
 
 	iommu = device_to_iommu(dev, &bus, &devfn);
 	if (!iommu || !iommu->iommu.ops)
@@ -4513,6 +4506,16 @@ static struct iommu_device *intel_iommu_probe_device(struct device *dev)
 
 	dev_iommu_priv_set(dev, info);
 
+	if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
+		ret = intel_pasid_alloc_table(dev);
+		if (ret) {
+			dev_err(dev, "PASID table allocation failed\n");
+			dev_iommu_priv_set(dev, NULL);
+			kfree(info);
+			return ERR_PTR(ret);
+		}
+	}
+
 	return &iommu->iommu;
 }
 
@@ -4521,6 +4524,7 @@ static void intel_iommu_release_device(struct device *dev)
 	struct device_domain_info *info = dev_iommu_priv_get(dev);
 
 	dmar_remove_one_dev_info(dev);
+	intel_pasid_free_table(dev);
 	dev_iommu_priv_set(dev, NULL);
 	kfree(info);
 	set_dma_ops(dev, NULL);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 2/7] iommu/vt-d: Add blocking domain support
  2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
  2022-11-03  5:53 ` [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path Lu Baolu
@ 2022-11-03  5:53 ` Lu Baolu
  2022-11-04  2:11   ` Tian, Kevin
  2022-11-03  5:53 ` [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path Lu Baolu
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

The Intel IOMMU hardwares support blocking DMA transactions by clearing
the translation table entries. This implements a real blocking domain to
avoid using an empty UNMANAGED domain. The detach_dev callback of the
domain ops is not used in any path. Remove it to avoid dead code as well.

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

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index e28faba1095f..7374a03cbe27 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -278,6 +278,7 @@ static LIST_HEAD(dmar_satc_units);
 	list_for_each_entry(rmrr, &dmar_rmrr_units, list)
 
 static void dmar_remove_one_dev_info(struct device *dev);
+static void intel_iommu_domain_free(struct iommu_domain *domain);
 
 int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
 int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
@@ -4132,12 +4133,58 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
 	return 0;
 }
 
+/*
+ * Clear the page table pointer in context or pasid table entries so that
+ * all DMA requests without PASID from the device are blocked. If the page
+ * table has been set, clean up the data structures.
+ */
+static void device_block_translation(struct device *dev)
+{
+	struct device_domain_info *info = dev_iommu_priv_get(dev);
+	struct intel_iommu *iommu = info->iommu;
+	unsigned long flags;
+
+	if (!dev_is_real_dma_subdevice(dev)) {
+		if (sm_supported(iommu))
+			intel_pasid_tear_down_entry(iommu, dev,
+						    PASID_RID2PASID, false);
+		else
+			domain_context_clear(info);
+	}
+
+	if (!info->domain)
+		return;
+
+	spin_lock_irqsave(&info->domain->lock, flags);
+	list_del(&info->link);
+	spin_unlock_irqrestore(&info->domain->lock, flags);
+
+	domain_detach_iommu(info->domain, iommu);
+	info->domain = NULL;
+}
+
+static int blocking_domain_attach_dev(struct iommu_domain *domain,
+				      struct device *dev)
+{
+	device_block_translation(dev);
+	return 0;
+}
+
+static struct iommu_domain blocking_domain = {
+	.ops = &(const struct iommu_domain_ops) {
+		.attach_dev	= blocking_domain_attach_dev,
+		.free		= intel_iommu_domain_free
+	}
+};
+
 static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 {
 	struct dmar_domain *dmar_domain;
 	struct iommu_domain *domain;
 
 	switch (type) {
+	case IOMMU_DOMAIN_BLOCKED:
+		return &blocking_domain;
 	case IOMMU_DOMAIN_DMA:
 	case IOMMU_DOMAIN_DMA_FQ:
 	case IOMMU_DOMAIN_UNMANAGED:
@@ -4172,7 +4219,7 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 
 static void intel_iommu_domain_free(struct iommu_domain *domain)
 {
-	if (domain != &si_domain->domain)
+	if (domain != &si_domain->domain && domain != &blocking_domain)
 		domain_exit(to_dmar_domain(domain));
 }
 
@@ -4246,12 +4293,6 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 	return domain_add_dev_info(to_dmar_domain(domain), dev);
 }
 
-static void intel_iommu_detach_device(struct iommu_domain *domain,
-				      struct device *dev)
-{
-	dmar_remove_one_dev_info(dev);
-}
-
 static int intel_iommu_map(struct iommu_domain *domain,
 			   unsigned long iova, phys_addr_t hpa,
 			   size_t size, int iommu_prot, gfp_t gfp)
@@ -4759,7 +4800,6 @@ const struct iommu_ops intel_iommu_ops = {
 #endif
 	.default_domain_ops = &(const struct iommu_domain_ops) {
 		.attach_dev		= intel_iommu_attach_device,
-		.detach_dev		= intel_iommu_detach_device,
 		.map_pages		= intel_iommu_map_pages,
 		.unmap_pages		= intel_iommu_unmap_pages,
 		.iotlb_sync_map		= intel_iommu_iotlb_sync_map,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path
  2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
  2022-11-03  5:53 ` [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path Lu Baolu
  2022-11-03  5:53 ` [PATCH 2/7] iommu/vt-d: Add blocking domain support Lu Baolu
@ 2022-11-03  5:53 ` Lu Baolu
  2022-11-04  2:18   ` Tian, Kevin
  2022-11-03  5:53 ` [PATCH 4/7] iommu/vt-d: Fold dmar_remove_one_dev_info() into its caller Lu Baolu
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

If domain attaching to device fails, the IOMMU driver should bring the
device to blocking DMA state. The upper layer is expected to recover it
by attaching a new domain. Use device_block_translation() in the error
path of dev_attach to make the behavior specific.

The difference between device_block_translation() and the previous
dmar_remove_one_dev_info() is that the latter disables PCIe ATS and the
related PCIe features. This is unnecessary as these features are not per
domain capabilities, disabling them during domain switching is
unnecessary.

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

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 7374a03cbe27..b956c411f2bb 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -277,8 +277,8 @@ static LIST_HEAD(dmar_satc_units);
 #define for_each_rmrr_units(rmrr) \
 	list_for_each_entry(rmrr, &dmar_rmrr_units, list)
 
-static void dmar_remove_one_dev_info(struct device *dev);
 static void intel_iommu_domain_free(struct iommu_domain *domain);
+static void device_block_translation(struct device *dev);
 
 int dmar_disabled = !IS_ENABLED(CONFIG_INTEL_IOMMU_DEFAULT_ON);
 int intel_iommu_sm = IS_ENABLED(CONFIG_INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON);
@@ -2490,7 +2490,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
 					dev, PASID_RID2PASID);
 		if (ret) {
 			dev_err(dev, "Setup RID2PASID failed\n");
-			dmar_remove_one_dev_info(dev);
+			device_block_translation(dev);
 			return ret;
 		}
 	}
@@ -2498,7 +2498,7 @@ static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
 	ret = domain_context_mapping(domain, dev);
 	if (ret) {
 		dev_err(dev, "Domain context map failed\n");
-		dmar_remove_one_dev_info(dev);
+		device_block_translation(dev);
 		return ret;
 	}
 
@@ -4283,7 +4283,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 		struct device_domain_info *info = dev_iommu_priv_get(dev);
 
 		if (info->domain)
-			dmar_remove_one_dev_info(dev);
+			device_block_translation(dev);
 	}
 
 	ret = prepare_domain_attach_device(domain, dev);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 4/7] iommu/vt-d: Fold dmar_remove_one_dev_info() into its caller
  2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
                   ` (2 preceding siblings ...)
  2022-11-03  5:53 ` [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path Lu Baolu
@ 2022-11-03  5:53 ` Lu Baolu
  2022-11-03  5:53 ` [PATCH 5/7] iommu/vt-d: Rename domain_add_dev_info() Lu Baolu
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

Fold dmar_remove_one_dev_info() into intel_iommu_release_device() which
is its only caller. Replace most of the code with
device_block_translation() to make the code neat and tidy.

Rename iommu_disable_dev_iotlb() to iommu_disable_pci_caps() to pair with
iommu_enable_pci_caps().

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

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index b956c411f2bb..393e07ac4c21 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -1443,7 +1443,7 @@ static void iommu_enable_pci_caps(struct device_domain_info *info)
 	}
 }
 
-static void iommu_disable_dev_iotlb(struct device_domain_info *info)
+static void iommu_disable_pci_caps(struct device_domain_info *info)
 {
 	struct pci_dev *pdev;
 
@@ -4088,30 +4088,6 @@ static void domain_context_clear(struct device_domain_info *info)
 			       &domain_context_clear_one_cb, info);
 }
 
-static void dmar_remove_one_dev_info(struct device *dev)
-{
-	struct device_domain_info *info = dev_iommu_priv_get(dev);
-	struct dmar_domain *domain = info->domain;
-	struct intel_iommu *iommu = info->iommu;
-	unsigned long flags;
-
-	if (!dev_is_real_dma_subdevice(info->dev)) {
-		if (dev_is_pci(info->dev) && sm_supported(iommu))
-			intel_pasid_tear_down_entry(iommu, info->dev,
-					PASID_RID2PASID, false);
-
-		iommu_disable_dev_iotlb(info);
-		domain_context_clear(info);
-	}
-
-	spin_lock_irqsave(&domain->lock, flags);
-	list_del(&info->link);
-	spin_unlock_irqrestore(&domain->lock, flags);
-
-	domain_detach_iommu(domain, iommu);
-	info->domain = NULL;
-}
-
 static int md_domain_init(struct dmar_domain *domain, int guest_width)
 {
 	int adjust_width;
@@ -4564,7 +4540,10 @@ static void intel_iommu_release_device(struct device *dev)
 {
 	struct device_domain_info *info = dev_iommu_priv_get(dev);
 
-	dmar_remove_one_dev_info(dev);
+	iommu_disable_pci_caps(info);
+	domain_context_clear(info);
+	device_block_translation(dev);
+
 	intel_pasid_free_table(dev);
 	dev_iommu_priv_set(dev, NULL);
 	kfree(info);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 5/7] iommu/vt-d: Rename domain_add_dev_info()
  2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
                   ` (3 preceding siblings ...)
  2022-11-03  5:53 ` [PATCH 4/7] iommu/vt-d: Fold dmar_remove_one_dev_info() into its caller Lu Baolu
@ 2022-11-03  5:53 ` Lu Baolu
  2022-11-03  5:53 ` [PATCH 6/7] iommu/vt-d: Remove unnecessary domain_context_mapped() Lu Baolu
  2022-11-03  5:53 ` [PATCH 7/7] iommu/vt-d: Use real field for indication of first level Lu Baolu
  6 siblings, 0 replies; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

dmar_domain_attach_device() is more meaningful according to what this
helper does.

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

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 393e07ac4c21..6ec5dd4e461b 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -2456,7 +2456,8 @@ static int __init si_domain_init(int hw)
 	return 0;
 }
 
-static int domain_add_dev_info(struct dmar_domain *domain, struct device *dev)
+static int dmar_domain_attach_device(struct dmar_domain *domain,
+				     struct device *dev)
 {
 	struct device_domain_info *info = dev_iommu_priv_get(dev);
 	struct intel_iommu *iommu;
@@ -4266,7 +4267,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 	if (ret)
 		return ret;
 
-	return domain_add_dev_info(to_dmar_domain(domain), dev);
+	return dmar_domain_attach_device(to_dmar_domain(domain), dev);
 }
 
 static int intel_iommu_map(struct iommu_domain *domain,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 6/7] iommu/vt-d: Remove unnecessary domain_context_mapped()
  2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
                   ` (4 preceding siblings ...)
  2022-11-03  5:53 ` [PATCH 5/7] iommu/vt-d: Rename domain_add_dev_info() Lu Baolu
@ 2022-11-03  5:53 ` Lu Baolu
  2022-11-04  2:19   ` Tian, Kevin
  2022-11-03  5:53 ` [PATCH 7/7] iommu/vt-d: Use real field for indication of first level Lu Baolu
  6 siblings, 1 reply; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

The device_domain_info::domain accurately records the domain attached to
the device. It is unnecessary to check whether the context is present in
the attach_dev path. Remove it to make the code neat.

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

diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 6ec5dd4e461b..5c7a574fad38 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -780,19 +780,6 @@ static void domain_flush_cache(struct dmar_domain *domain,
 		clflush_cache_range(addr, size);
 }
 
-static int device_context_mapped(struct intel_iommu *iommu, u8 bus, u8 devfn)
-{
-	struct context_entry *context;
-	int ret = 0;
-
-	spin_lock(&iommu->lock);
-	context = iommu_context_addr(iommu, bus, devfn, 0);
-	if (context)
-		ret = context_present(context);
-	spin_unlock(&iommu->lock);
-	return ret;
-}
-
 static void free_context_table(struct intel_iommu *iommu)
 {
 	struct context_entry *context;
@@ -2100,30 +2087,6 @@ domain_context_mapping(struct dmar_domain *domain, struct device *dev)
 				      &domain_context_mapping_cb, &data);
 }
 
-static int domain_context_mapped_cb(struct pci_dev *pdev,
-				    u16 alias, void *opaque)
-{
-	struct intel_iommu *iommu = opaque;
-
-	return !device_context_mapped(iommu, PCI_BUS_NUM(alias), alias & 0xff);
-}
-
-static int domain_context_mapped(struct device *dev)
-{
-	struct intel_iommu *iommu;
-	u8 bus, devfn;
-
-	iommu = device_to_iommu(dev, &bus, &devfn);
-	if (!iommu)
-		return -ENODEV;
-
-	if (!dev_is_pci(dev))
-		return device_context_mapped(iommu, bus, devfn);
-
-	return !pci_for_each_dma_alias(to_pci_dev(dev),
-				       domain_context_mapped_cb, iommu);
-}
-
 /* Returns a number of VTD pages, but aligned to MM page size */
 static inline unsigned long aligned_nrpages(unsigned long host_addr,
 					    size_t size)
@@ -4247,6 +4210,7 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
 static int intel_iommu_attach_device(struct iommu_domain *domain,
 				     struct device *dev)
 {
+	struct device_domain_info *info = dev_iommu_priv_get(dev);
 	int ret;
 
 	if (domain->type == IOMMU_DOMAIN_UNMANAGED &&
@@ -4255,13 +4219,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 		return -EPERM;
 	}
 
-	/* normally dev is not mapped */
-	if (unlikely(domain_context_mapped(dev))) {
-		struct device_domain_info *info = dev_iommu_priv_get(dev);
-
-		if (info->domain)
-			device_block_translation(dev);
-	}
+	if (info->domain)
+		device_block_translation(dev);
 
 	ret = prepare_domain_attach_device(domain, dev);
 	if (ret)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* [PATCH 7/7] iommu/vt-d: Use real field for indication of first level
  2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
                   ` (5 preceding siblings ...)
  2022-11-03  5:53 ` [PATCH 6/7] iommu/vt-d: Remove unnecessary domain_context_mapped() Lu Baolu
@ 2022-11-03  5:53 ` Lu Baolu
  2022-11-04  2:20   ` Tian, Kevin
  6 siblings, 1 reply; 18+ messages in thread
From: Lu Baolu @ 2022-11-03  5:53 UTC (permalink / raw)
  To: iommu
  Cc: Joerg Roedel, Kevin Tian, Will Deacon, Robin Murphy, Liu Yi L,
	Jacob jun Pan, linux-kernel, Lu Baolu

The dmar_domain uses bit field members to indicate the behaviors. Add
a bit field for using first level and remove the flags member to avoid
duplication.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 drivers/iommu/intel/iommu.h | 15 +++++----------
 drivers/iommu/intel/iommu.c | 25 ++++++++++---------------
 2 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 251a609fdce3..7b7234689cb4 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -515,14 +515,6 @@ struct context_entry {
 	u64 hi;
 };
 
-/*
- * When VT-d works in the scalable mode, it allows DMA translation to
- * happen through either first level or second level page table. This
- * bit marks that the DMA translation for the domain goes through the
- * first level page table, otherwise, it goes through the second level.
- */
-#define DOMAIN_FLAG_USE_FIRST_LEVEL		BIT(1)
-
 struct iommu_domain_info {
 	struct intel_iommu *iommu;
 	unsigned int refcnt;		/* Refcount of devices per iommu */
@@ -539,6 +531,11 @@ struct dmar_domain {
 	u8 iommu_coherency: 1;		/* indicate coherency of iommu access */
 	u8 force_snooping : 1;		/* Create IOPTEs with snoop control */
 	u8 set_pte_snp:1;
+	u8 use_first_level:1;		/* DMA translation for the domain goes
+					 * through the first level page table,
+					 * otherwise, goes through the second
+					 * level.
+					 */
 
 	spinlock_t lock;		/* Protect device tracking lists */
 	struct list_head devices;	/* all devices' list */
@@ -548,8 +545,6 @@ struct dmar_domain {
 
 	/* adjusted guest address width, 0 is level 2 30-bit */
 	int		agaw;
-
-	int		flags;		/* flags to find out type of domain */
 	int		iommu_superpage;/* Level of superpages supported:
 					   0 == 4KiB (no superpages), 1 == 2MiB,
 					   2 == 1GiB, 3 == 512GiB, 4 == 1TiB */
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 5c7a574fad38..9fb13250d84a 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -383,11 +383,6 @@ static inline int domain_type_is_si(struct dmar_domain *domain)
 	return domain->domain.type == IOMMU_DOMAIN_IDENTITY;
 }
 
-static inline bool domain_use_first_level(struct dmar_domain *domain)
-{
-	return domain->flags & DOMAIN_FLAG_USE_FIRST_LEVEL;
-}
-
 static inline int domain_pfn_supported(struct dmar_domain *domain,
 				       unsigned long pfn)
 {
@@ -501,7 +496,7 @@ static int domain_update_iommu_superpage(struct dmar_domain *domain,
 	rcu_read_lock();
 	for_each_active_iommu(iommu, drhd) {
 		if (iommu != skip) {
-			if (domain && domain_use_first_level(domain)) {
+			if (domain && domain->use_first_level) {
 				if (!cap_fl1gp_support(iommu->cap))
 					mask = 0x1;
 			} else {
@@ -579,7 +574,7 @@ static void domain_update_iommu_cap(struct dmar_domain *domain)
 	 * paging and 57-bits with 5-level paging). Hence, skip bit
 	 * [N-1].
 	 */
-	if (domain_use_first_level(domain))
+	if (domain->use_first_level)
 		domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw - 1);
 	else
 		domain->domain.geometry.aperture_end = __DOMAIN_MAX_ADDR(domain->gaw);
@@ -947,7 +942,7 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
 
 			domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
 			pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
-			if (domain_use_first_level(domain)) {
+			if (domain->use_first_level) {
 				pteval |= DMA_FL_PTE_XD | DMA_FL_PTE_US;
 				if (iommu_is_dma_domain(&domain->domain))
 					pteval |= DMA_FL_PTE_ACCESS;
@@ -1500,7 +1495,7 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
 	if (ih)
 		ih = 1 << 6;
 
-	if (domain_use_first_level(domain)) {
+	if (domain->use_first_level) {
 		qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, pages, ih);
 	} else {
 		unsigned long bitmask = aligned_pages - 1;
@@ -1554,7 +1549,7 @@ static inline void __mapping_notify_one(struct intel_iommu *iommu,
 	 * It's a non-present to present mapping. Only flush if caching mode
 	 * and second level.
 	 */
-	if (cap_caching_mode(iommu->cap) && !domain_use_first_level(domain))
+	if (cap_caching_mode(iommu->cap) && !domain->use_first_level)
 		iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
 	else
 		iommu_flush_write_buffer(iommu);
@@ -1570,7 +1565,7 @@ static void intel_flush_iotlb_all(struct iommu_domain *domain)
 		struct intel_iommu *iommu = info->iommu;
 		u16 did = domain_id_iommu(dmar_domain, iommu);
 
-		if (domain_use_first_level(dmar_domain))
+		if (dmar_domain->use_first_level)
 			qi_flush_piotlb(iommu, did, PASID_RID2PASID, 0, -1, 0);
 		else
 			iommu->flush.flush_iotlb(iommu, did, 0, 0,
@@ -1743,7 +1738,7 @@ static struct dmar_domain *alloc_domain(unsigned int type)
 
 	domain->nid = NUMA_NO_NODE;
 	if (first_level_by_default(type))
-		domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
+		domain->use_first_level = true;
 	domain->has_iotlb_device = false;
 	INIT_LIST_HEAD(&domain->devices);
 	spin_lock_init(&domain->lock);
@@ -2176,7 +2171,7 @@ __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
 
 	attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
 	attr |= DMA_FL_PTE_PRESENT;
-	if (domain_use_first_level(domain)) {
+	if (domain->use_first_level) {
 		attr |= DMA_FL_PTE_XD | DMA_FL_PTE_US | DMA_FL_PTE_ACCESS;
 		if (prot & DMA_PTE_WRITE)
 			attr |= DMA_FL_PTE_DIRTY;
@@ -2446,7 +2441,7 @@ static int dmar_domain_attach_device(struct dmar_domain *domain,
 		if (hw_pass_through && domain_type_is_si(domain))
 			ret = intel_pasid_setup_pass_through(iommu, domain,
 					dev, PASID_RID2PASID);
-		else if (domain_use_first_level(domain))
+		else if (domain->use_first_level)
 			ret = domain_setup_first_level(iommu, domain, dev,
 					PASID_RID2PASID);
 		else
@@ -4390,7 +4385,7 @@ static void domain_set_force_snooping(struct dmar_domain *domain)
 	 * Second level page table supports per-PTE snoop control. The
 	 * iommu_map() interface will handle this by setting SNP bit.
 	 */
-	if (!domain_use_first_level(domain)) {
+	if (!domain->use_first_level) {
 		domain->set_pte_snp = true;
 		return;
 	}
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path
  2022-11-03  5:53 ` [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path Lu Baolu
@ 2022-11-04  2:06   ` Tian, Kevin
  2022-11-05  1:09     ` Baolu Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Tian, Kevin @ 2022-11-04  2:06 UTC (permalink / raw)
  To: Lu Baolu, iommu
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L, Pan,
	Jacob jun, linux-kernel

> From: Lu Baolu <baolu.lu@linux.intel.com>
> Sent: Thursday, November 3, 2022 1:53 PM
> 
> @@ -4513,6 +4506,16 @@ static struct iommu_device
> *intel_iommu_probe_device(struct device *dev)
> 
>  	dev_iommu_priv_set(dev, info);
> 
> +	if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
> +		ret = intel_pasid_alloc_table(dev);
> +		if (ret) {
> +			dev_err(dev, "PASID table allocation failed\n");
> +			dev_iommu_priv_set(dev, NULL);
> +			kfree(info);
> +			return ERR_PTR(ret);
> +		}
> +	}
> +

move the added lines before dev_iommu_priv_set()

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 2/7] iommu/vt-d: Add blocking domain support
  2022-11-03  5:53 ` [PATCH 2/7] iommu/vt-d: Add blocking domain support Lu Baolu
@ 2022-11-04  2:11   ` Tian, Kevin
  2022-11-05  1:54     ` Baolu Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Tian, Kevin @ 2022-11-04  2:11 UTC (permalink / raw)
  To: Lu Baolu, iommu
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L, Pan,
	Jacob jun, linux-kernel

> From: Lu Baolu <baolu.lu@linux.intel.com>
> Sent: Thursday, November 3, 2022 1:53 PM
> 
> +/*
> + * Clear the page table pointer in context or pasid table entries so that
> + * all DMA requests without PASID from the device are blocked. If the page
> + * table has been set, clean up the data structures.
> + */
> +static void device_block_translation(struct device *dev)

given this helper will be used both by existing paths and the new block
domain, it makes more sense to have it work with existing paths first
i.e. merging with patch3 and then add block domain after.

> +{
> +	struct device_domain_info *info = dev_iommu_priv_get(dev);
> +	struct intel_iommu *iommu = info->iommu;
> +	unsigned long flags;
> +
> +	if (!dev_is_real_dma_subdevice(dev)) {
> +		if (sm_supported(iommu))
> +			intel_pasid_tear_down_entry(iommu, dev,
> +						    PASID_RID2PASID, false);

Since commit 4140d77a aliases devices don't share pasid table,
which implies that pci_for_each_dma_alias() is required as did
in domain_context_clear().

> +		else
> +			domain_context_clear(info);
> +	}
> +
> +	if (!info->domain)
> +		return;
> +
> +	spin_lock_irqsave(&info->domain->lock, flags);
> +	list_del(&info->link);
> +	spin_unlock_irqrestore(&info->domain->lock, flags);
> +
> +	domain_detach_iommu(info->domain, iommu);
> +	info->domain = NULL;
> +}
> +

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path
  2022-11-03  5:53 ` [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path Lu Baolu
@ 2022-11-04  2:18   ` Tian, Kevin
  2022-11-05  2:09     ` Baolu Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Tian, Kevin @ 2022-11-04  2:18 UTC (permalink / raw)
  To: Lu Baolu, iommu
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L, Pan,
	Jacob jun, linux-kernel

> From: Lu Baolu <baolu.lu@linux.intel.com>
> Sent: Thursday, November 3, 2022 1:53 PM
> 
> If domain attaching to device fails, the IOMMU driver should bring the
> device to blocking DMA state. The upper layer is expected to recover it
> by attaching a new domain. Use device_block_translation() in the error
> path of dev_attach to make the behavior specific.
> 
> The difference between device_block_translation() and the previous
> dmar_remove_one_dev_info() is that the latter disables PCIe ATS and the
> related PCIe features. This is unnecessary as these features are not per
> domain capabilities, disabling them during domain switching is
> unnecessary.

well, the opposite argument is that when the DMA is blocked what is
the point of enabling ATS/PRI on the device.

btw this change is partial. @attach_dev still calls iommu_enable_pci_caps()
which always tries to enable PCI capabilities w/o checking whether they
have been enabled or not. Then user will hit -EBUSY when related PCI
helpers are called.

another difference worthy of pointing out is that in scalable mode it is
the RID2PASID entry instead of context entry being cleared.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 6/7] iommu/vt-d: Remove unnecessary domain_context_mapped()
  2022-11-03  5:53 ` [PATCH 6/7] iommu/vt-d: Remove unnecessary domain_context_mapped() Lu Baolu
@ 2022-11-04  2:19   ` Tian, Kevin
  0 siblings, 0 replies; 18+ messages in thread
From: Tian, Kevin @ 2022-11-04  2:19 UTC (permalink / raw)
  To: Lu Baolu, iommu
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L, Pan,
	Jacob jun, linux-kernel

> From: Lu Baolu <baolu.lu@linux.intel.com>
> Sent: Thursday, November 3, 2022 1:53 PM
> 
> The device_domain_info::domain accurately records the domain attached to
> the device. It is unnecessary to check whether the context is present in
> the attach_dev path. Remove it to make the code neat.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>

Reviewed-by: Kevin Tian <kevin.tian@intel.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 7/7] iommu/vt-d: Use real field for indication of first level
  2022-11-03  5:53 ` [PATCH 7/7] iommu/vt-d: Use real field for indication of first level Lu Baolu
@ 2022-11-04  2:20   ` Tian, Kevin
  0 siblings, 0 replies; 18+ messages in thread
From: Tian, Kevin @ 2022-11-04  2:20 UTC (permalink / raw)
  To: Lu Baolu, iommu
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L, Pan,
	Jacob jun, linux-kernel

> From: Lu Baolu <baolu.lu@linux.intel.com>
> Sent: Thursday, November 3, 2022 1:53 PM
> 
> The dmar_domain uses bit field members to indicate the behaviors. Add
> a bit field for using first level and remove the flags member to avoid
> duplication.
> 
> Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>

Reviewed-by: Kevin Tian <kevin.tian@intel.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path
  2022-11-04  2:06   ` Tian, Kevin
@ 2022-11-05  1:09     ` Baolu Lu
  2022-11-05  1:33       ` Tian, Kevin
  0 siblings, 1 reply; 18+ messages in thread
From: Baolu Lu @ 2022-11-05  1:09 UTC (permalink / raw)
  To: Tian, Kevin, iommu
  Cc: baolu.lu, Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L,
	Pan, Jacob jun, linux-kernel

On 2022/11/4 10:06, Tian, Kevin wrote:
>> From: Lu Baolu <baolu.lu@linux.intel.com>
>> Sent: Thursday, November 3, 2022 1:53 PM
>>
>> @@ -4513,6 +4506,16 @@ static struct iommu_device
>> *intel_iommu_probe_device(struct device *dev)
>>
>>   	dev_iommu_priv_set(dev, info);
>>
>> +	if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
>> +		ret = intel_pasid_alloc_table(dev);
>> +		if (ret) {
>> +			dev_err(dev, "PASID table allocation failed\n");
>> +			dev_iommu_priv_set(dev, NULL);
>> +			kfree(info);
>> +			return ERR_PTR(ret);
>> +		}
>> +	}
>> +
> 
> move the added lines before dev_iommu_priv_set()

intel_pasid_alloc_table() needs to reference info and store the pasid
table into it.

Best regards,
baolu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path
  2022-11-05  1:09     ` Baolu Lu
@ 2022-11-05  1:33       ` Tian, Kevin
  0 siblings, 0 replies; 18+ messages in thread
From: Tian, Kevin @ 2022-11-05  1:33 UTC (permalink / raw)
  To: Baolu Lu, iommu
  Cc: Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L, Pan,
	Jacob jun, linux-kernel

> From: Baolu Lu <baolu.lu@linux.intel.com>
> Sent: Saturday, November 5, 2022 9:10 AM
> 
> On 2022/11/4 10:06, Tian, Kevin wrote:
> >> From: Lu Baolu <baolu.lu@linux.intel.com>
> >> Sent: Thursday, November 3, 2022 1:53 PM
> >>
> >> @@ -4513,6 +4506,16 @@ static struct iommu_device
> >> *intel_iommu_probe_device(struct device *dev)
> >>
> >>   	dev_iommu_priv_set(dev, info);
> >>
> >> +	if (sm_supported(iommu) && !dev_is_real_dma_subdevice(dev)) {
> >> +		ret = intel_pasid_alloc_table(dev);
> >> +		if (ret) {
> >> +			dev_err(dev, "PASID table allocation failed\n");
> >> +			dev_iommu_priv_set(dev, NULL);
> >> +			kfree(info);
> >> +			return ERR_PTR(ret);
> >> +		}
> >> +	}
> >> +
> >
> > move the added lines before dev_iommu_priv_set()
> 
> intel_pasid_alloc_table() needs to reference info and store the pasid
> table into it.
> 

Yes, I overlooked it.

Reviewed-by: Kevin Tian <kevin.tian@intel.com>

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 2/7] iommu/vt-d: Add blocking domain support
  2022-11-04  2:11   ` Tian, Kevin
@ 2022-11-05  1:54     ` Baolu Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Baolu Lu @ 2022-11-05  1:54 UTC (permalink / raw)
  To: Tian, Kevin, iommu
  Cc: baolu.lu, Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L,
	Pan, Jacob jun, linux-kernel

On 2022/11/4 10:11, Tian, Kevin wrote:
>> From: Lu Baolu <baolu.lu@linux.intel.com>
>> Sent: Thursday, November 3, 2022 1:53 PM
>>
>> +/*
>> + * Clear the page table pointer in context or pasid table entries so that
>> + * all DMA requests without PASID from the device are blocked. If the page
>> + * table has been set, clean up the data structures.
>> + */
>> +static void device_block_translation(struct device *dev)
> 
> given this helper will be used both by existing paths and the new block
> domain, it makes more sense to have it work with existing paths first
> i.e. merging with patch3 and then add block domain after.

Yes. Sounds good.

> 
>> +{
>> +	struct device_domain_info *info = dev_iommu_priv_get(dev);
>> +	struct intel_iommu *iommu = info->iommu;
>> +	unsigned long flags;
>> +
>> +	if (!dev_is_real_dma_subdevice(dev)) {
>> +		if (sm_supported(iommu))
>> +			intel_pasid_tear_down_entry(iommu, dev,
>> +						    PASID_RID2PASID, false);
> 
> Since commit 4140d77a aliases devices don't share pasid table,
> which implies that pci_for_each_dma_alias() is required as did
> in domain_context_clear().

The PCI alias devices have already been covered by the iommu group
concept in the iommu core. On the contrary, I've been thinking about
retiring pci_for_each_dma_alias() in domain_context_clear().



> 
>> +		else
>> +			domain_context_clear(info);
>> +	}
>> +
>> +	if (!info->domain)
>> +		return;
>> +
>> +	spin_lock_irqsave(&info->domain->lock, flags);
>> +	list_del(&info->link);
>> +	spin_unlock_irqrestore(&info->domain->lock, flags);
>> +
>> +	domain_detach_iommu(info->domain, iommu);
>> +	info->domain = NULL;
>> +}
>> +

Best regards,
baolu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path
  2022-11-04  2:18   ` Tian, Kevin
@ 2022-11-05  2:09     ` Baolu Lu
  2022-11-05  2:59       ` Baolu Lu
  0 siblings, 1 reply; 18+ messages in thread
From: Baolu Lu @ 2022-11-05  2:09 UTC (permalink / raw)
  To: Tian, Kevin, iommu
  Cc: baolu.lu, Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L,
	Pan, Jacob jun, linux-kernel

On 2022/11/4 10:18, Tian, Kevin wrote:
>> From: Lu Baolu <baolu.lu@linux.intel.com>
>> Sent: Thursday, November 3, 2022 1:53 PM
>>
>> If domain attaching to device fails, the IOMMU driver should bring the
>> device to blocking DMA state. The upper layer is expected to recover it
>> by attaching a new domain. Use device_block_translation() in the error
>> path of dev_attach to make the behavior specific.
>>
>> The difference between device_block_translation() and the previous
>> dmar_remove_one_dev_info() is that the latter disables PCIe ATS and the
>> related PCIe features. This is unnecessary as these features are not per
>> domain capabilities, disabling them during domain switching is
>> unnecessary.
> 
> well, the opposite argument is that when the DMA is blocked what is
> the point of enabling ATS/PRI on the device.

It's not "DMA is blocked", but "DMA without PASID is blocked". :-)

As above term implies, it's conceptually incorrect to disable ATS/PRI
only because DMA without PASID is about to blocked.

> 
> btw this change is partial. @attach_dev still calls iommu_enable_pci_caps()
> which always tries to enable PCI capabilities w/o checking whether they
> have been enabled or not. Then user will hit -EBUSY when related PCI
> helpers are called.

Good catch!

How about moving iommu_enable/disable_pci_caps() into
iommu_probe/release_device() path? I may look into details if there's no
significant arch gaps.

> 
> another difference worthy of pointing out is that in scalable mode it is
> the RID2PASID entry instead of context entry being cleared.

Yes. Will update the commit message.

Best regards,
baolu

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path
  2022-11-05  2:09     ` Baolu Lu
@ 2022-11-05  2:59       ` Baolu Lu
  0 siblings, 0 replies; 18+ messages in thread
From: Baolu Lu @ 2022-11-05  2:59 UTC (permalink / raw)
  To: Tian, Kevin, iommu
  Cc: baolu.lu, Joerg Roedel, Will Deacon, Robin Murphy, Liu, Yi L,
	Pan, Jacob jun, linux-kernel

On 2022/11/5 10:09, Baolu Lu wrote:
>>
>> btw this change is partial. @attach_dev still calls 
>> iommu_enable_pci_caps()
>> which always tries to enable PCI capabilities w/o checking whether they
>> have been enabled or not. Then user will hit -EBUSY when related PCI
>> helpers are called.
> 
> Good catch!
> 
> How about moving iommu_enable/disable_pci_caps() into
> iommu_probe/release_device() path? I may look into details if there's no
> significant arch gaps.

After reconsideration, it seems that this is not a feasible solution.
This changes the order in which PCI devices enable DMA.In addition, for
the kdump kernel, this is not feasible because there may be on-going DMA
on the device.

Perhaps I can make the iommu_enable_pci_caps() reentrant.

Best regards,
baolu

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2022-11-05  2:59 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-11-03  5:53 [PATCH 0/7] iommu/vt-d: Some cleanups Lu Baolu
2022-11-03  5:53 ` [PATCH 1/7] iommu/vt-d: Allocate pasid table in device probe path Lu Baolu
2022-11-04  2:06   ` Tian, Kevin
2022-11-05  1:09     ` Baolu Lu
2022-11-05  1:33       ` Tian, Kevin
2022-11-03  5:53 ` [PATCH 2/7] iommu/vt-d: Add blocking domain support Lu Baolu
2022-11-04  2:11   ` Tian, Kevin
2022-11-05  1:54     ` Baolu Lu
2022-11-03  5:53 ` [PATCH 3/7] iommu/vt-d: Use device_block_translation() in dev_attach error path Lu Baolu
2022-11-04  2:18   ` Tian, Kevin
2022-11-05  2:09     ` Baolu Lu
2022-11-05  2:59       ` Baolu Lu
2022-11-03  5:53 ` [PATCH 4/7] iommu/vt-d: Fold dmar_remove_one_dev_info() into its caller Lu Baolu
2022-11-03  5:53 ` [PATCH 5/7] iommu/vt-d: Rename domain_add_dev_info() Lu Baolu
2022-11-03  5:53 ` [PATCH 6/7] iommu/vt-d: Remove unnecessary domain_context_mapped() Lu Baolu
2022-11-04  2:19   ` Tian, Kevin
2022-11-03  5:53 ` [PATCH 7/7] iommu/vt-d: Use real field for indication of first level Lu Baolu
2022-11-04  2:20   ` Tian, Kevin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).