All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Sewart <jamessewart@arista.com>
To: Lu Baolu <baolu.lu@linux.intel.com>
Cc: iommu@lists.linux-foundation.org, Tom Murphy <tmurphy@arista.com>,
	Dmitry Safonov <dima@arista.com>,
	Jacob Pan <jacob.jun.pan@linux.intel.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 3/7] iommu/vt-d: Expose ISA direct mapping region via iommu_get_resv_regions
Date: Fri, 29 Mar 2019 15:26:46 +0000	[thread overview]
Message-ID: <8B1FC0C7-9BAC-498D-B1F0-0138EACF75C2@arista.com> (raw)
In-Reply-To: <6C211BF1-B5A0-4821-AB42-092B573DE667@arista.com>

[-- Attachment #1: Type: text/plain, Size: 2035 bytes --]

Hey Lu,

I’ve attached a preliminary v3, if you could take a look and run some tests 
that would be great.

Since v2 i’ve added your default domain type patches, the new device_group 
handler, and incorporated Jacob’s feedback.

> On 28 Mar 2019, at 18:37, James Sewart <jamessewart@arista.com> wrote:
> 
> Hey Lu,
> 
>> On 26 Mar 2019, at 01:24, Lu Baolu <baolu.lu@linux.intel.com> wrote:
>> 
>> Hi James,
>> 
>> On 3/25/19 8:57 PM, James Sewart wrote:
>>>>> Theres an issue that if we choose to alloc a new resv_region with type
>>>>> IOMMU_RESV_DIRECT, we will need to refactor intel_iommu_put_resv_regions
>>>>> to free this entry type which means refactoring the rmrr regions in
>>>>> get_resv_regions. Should this work be in this patchset?
>>>> Do you mean the rmrr regions are not allocated in get_resv_regions, but
>>>> are freed in put_resv_regions? I think we should fix this in this patch
>>>> set since this might impact the device passthrough if we don't do it.
>>> They’re not allocated and not freed currently, only type IOMMU_RESV_MSI is
>>> freed in put_resv_regions. If we allocate a new resv_region with type
>>> IOMMU_RESV_DIRECT for the isa region, then it won’t be freed. If we modify
>>> put_resv_regions to free type IOMMU_RESV_DIRECT, then we will try to free
>>> the static RMRR regions.
>>> Either the ISA region is static and not freed as with my implementation,
>>> or the RMRR regions are converted to be allocated on each call to
>>> get_resv_regions and freed in put_resv_regions.
>> 
>> By the way, there's another way in my mind. Let's add a new region type
>> for LPC devices, e.x. IOMMU_RESV_LPC, and then handle it in the same way
>> as those MSI regions. Just FYI.
> 
> This solution would require adding some extra code to 
> iommu_group_create_direct_mappings as currently only type 
> IOMMU_RESV_DIRECT is identity mapped, other types are only reserved.
> 
> 
>> 
>> Best regards,
>> Lu Baolu
> 
> Cheers,
> James.

Cheers,
James.


[-- Attachment #2: 0001-iommu-Move-iommu_group_create_direct_mappings-to-aft.patch --]
[-- Type: application/octet-stream, Size: 1289 bytes --]

From 798311d11929d45432641f20f2b869b112e8c956 Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Fri, 1 Mar 2019 16:03:40 +0000
Subject: [PATCH 1/9] iommu: Move iommu_group_create_direct_mappings to after
 device_attach

If an IOMMU driver requires to know which IOMMU a domain is associated
to initialise a domain then it will do so in device_attach, before which
it is not safe to call iommu_ops.

Signed-off-by: James Sewart <jamessewart@arista.com>

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 33a982e33716..88d589d56ded 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -652,8 +652,6 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)
 
 	dev->iommu_group = group;
 
-	iommu_group_create_direct_mappings(group, dev);
-
 	mutex_lock(&group->mutex);
 	list_add_tail(&device->list, &group->devices);
 	if (group->domain)
@@ -662,6 +660,8 @@ int iommu_group_add_device(struct iommu_group *group, struct device *dev)
 	if (ret)
 		goto err_put_group;
 
+	iommu_group_create_direct_mappings(group, dev);
+
 	/* Notify any listeners about change to group. */
 	blocking_notifier_call_chain(&group->notifier,
 				     IOMMU_GROUP_NOTIFY_ADD_DEVICE, dev);
-- 
2.17.1


[-- Attachment #3: 0002-iommu-vt-d-Implement-apply_resv_region-for-reserving.patch --]
[-- Type: application/octet-stream, Size: 1609 bytes --]

From 3bf87fef92f632b1bf789fcd2966d3f9bf707c43 Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Fri, 1 Mar 2019 16:24:59 +0000
Subject: [PATCH 2/9] iommu/vt-d: Implement apply_resv_region for reserving
 IOVA ranges

Used by iommu.c before creating identity mappings for reserved ranges to
ensure dma-ops won't ever remap these ranges

Signed-off-by: James Sewart <jamessewart@arista.com>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 28cb713d728c..3caa7b6fcdde 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5307,6 +5307,19 @@ static void intel_iommu_put_resv_regions(struct device *dev,
 	}
 }
 
+static void intel_iommu_apply_resv_region(struct device *dev,
+		struct iommu_domain *domain,
+		struct iommu_resv_region *region)
+{
+	struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+	unsigned long start, end;
+
+	start = IOVA_PFN(region->start);
+	end   = IOVA_PFN(region->start + region->length - 1);
+
+	WARN_ON_ONCE(reserve_iova(&dmar_domain->iovad, start, end) == NULL);
+}
+
 #ifdef CONFIG_INTEL_IOMMU_SVM
 int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
 {
@@ -5400,6 +5413,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.remove_device		= intel_iommu_remove_device,
 	.get_resv_regions	= intel_iommu_get_resv_regions,
 	.put_resv_regions	= intel_iommu_put_resv_regions,
+	.apply_resv_region	= intel_iommu_apply_resv_region,
 	.device_group		= pci_device_group,
 	.pgsize_bitmap		= INTEL_IOMMU_PGSIZES,
 };
-- 
2.17.1


[-- Attachment #4: 0003-iommu-vt-d-Expose-ISA-direct-mapping-region-via-iomm.patch --]
[-- Type: application/octet-stream, Size: 3328 bytes --]

From d7ccfb5297261d2781b3e29c2636ac94e9194569 Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Thu, 7 Mar 2019 17:57:15 +0000
Subject: [PATCH 3/9] iommu/vt-d: Expose ISA direct mapping region via
 iommu_get_resv_regions

To support mapping ISA region via iommu_group_create_direct_mappings,
make sure its exposed by iommu_get_resv_regions. This allows
deduplication of reserved region mappings

Signed-off-by: James Sewart <jamessewart@arista.com>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 3caa7b6fcdde..1075a7c74507 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -339,6 +339,8 @@ static LIST_HEAD(dmar_rmrr_units);
 #define for_each_rmrr_units(rmrr) \
 	list_for_each_entry(rmrr, &dmar_rmrr_units, list)
 
+static struct iommu_resv_region *isa_resv_region;
+
 /* bitmap for indexing intel_iommus */
 static int g_num_of_iommus;
 
@@ -2782,26 +2784,34 @@ static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
 					  rmrr->end_address);
 }
 
+static inline struct iommu_resv_region *iommu_get_isa_resv_region(void)
+{
+	if (!isa_resv_region)
+		isa_resv_region = iommu_alloc_resv_region(0,
+				16*1024*1024,
+				0, IOMMU_RESV_DIRECT);
+
+	return isa_resv_region;
+}
+
 #ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
-static inline void iommu_prepare_isa(void)
+static inline void iommu_prepare_isa(struct pci_dev *pdev)
 {
-	struct pci_dev *pdev;
 	int ret;
+	struct iommu_resv_region *reg = iommu_get_isa_resv_region();
 
-	pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
-	if (!pdev)
+	if (!reg)
 		return;
 
 	pr_info("Prepare 0-16MiB unity mapping for LPC\n");
-	ret = iommu_prepare_identity_map(&pdev->dev, 0, 16*1024*1024 - 1);
+	ret = iommu_prepare_identity_map(&pdev->dev, reg->start,
+			reg->start + reg->length - 1);
 
 	if (ret)
 		pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
-
-	pci_dev_put(pdev);
 }
 #else
-static inline void iommu_prepare_isa(void)
+static inline void iommu_prepare_isa(struct pci_dev *pdev)
 {
 	return;
 }
@@ -3290,6 +3300,7 @@ static int __init init_dmars(void)
 	struct dmar_rmrr_unit *rmrr;
 	bool copied_tables = false;
 	struct device *dev;
+	struct pci_dev *pdev;
 	struct intel_iommu *iommu;
 	int i, ret;
 
@@ -3470,7 +3481,11 @@ static int __init init_dmars(void)
 		}
 	}
 
-	iommu_prepare_isa();
+	pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
+	if (pdev) {
+		iommu_prepare_isa(pdev);
+		pci_dev_put(pdev);
+	}
 
 domains_done:
 
@@ -5274,6 +5289,7 @@ static void intel_iommu_get_resv_regions(struct device *device,
 	struct iommu_resv_region *reg;
 	struct dmar_rmrr_unit *rmrr;
 	struct device *i_dev;
+	struct pci_dev *pdev;
 	int i;
 
 	rcu_read_lock();
@@ -5288,6 +5304,14 @@ static void intel_iommu_get_resv_regions(struct device *device,
 	}
 	rcu_read_unlock();
 
+	if (dev_is_pci(device)) {
+		pdev = to_pci_dev(device);
+		if ((pdev->class >> 8) == PCI_CLASS_BRIDGE_ISA) {
+			reg = iommu_get_isa_resv_region();
+			list_add_tail(&reg->list, head);
+		}
+	}
+
 	reg = iommu_alloc_resv_region(IOAPIC_RANGE_START,
 				      IOAPIC_RANGE_END - IOAPIC_RANGE_START + 1,
 				      0, IOMMU_RESV_MSI);
-- 
2.17.1


[-- Attachment #5: 0004-iommu-vt-d-Create-an-IOMMU-group-for-devices-that-re.patch --]
[-- Type: application/octet-stream, Size: 1703 bytes --]

From f282a75bf3ed393e9eed57c0aa34a93097022e76 Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Sat, 9 Mar 2019 18:05:53 +0000
Subject: [PATCH 4/9] iommu/vt-d: Create an IOMMU group for devices that
 require an idenity map

Devices that require an identity map because of quirks or other reasons
should be put in their own IOMMU group so as to not end up with multiple
different domains per group.

Signed-off-by: James Sewart <jamessewart@arista.com>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 1075a7c74507..1db0ceb33020 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5424,6 +5424,22 @@ struct intel_iommu *intel_svm_device_to_iommu(struct device *dev)
 }
 #endif /* CONFIG_INTEL_IOMMU_SVM */
 
+static struct iommu_group *intel_identity_group;
+
+struct iommu_group *intel_iommu_pci_device_group(struct device *dev)
+{
+	if (iommu_no_mapping(dev)) {
+		if (!intel_identity_group) {
+			intel_identity_group = iommu_group_alloc();
+			if (IS_ERR(intel_identity_group))
+				return NULL;
+		}
+		return intel_identity_group;
+	}
+
+	return pci_device_group(dev);
+}
+
 const struct iommu_ops intel_iommu_ops = {
 	.capable		= intel_iommu_capable,
 	.domain_alloc		= intel_iommu_domain_alloc,
@@ -5438,7 +5454,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.get_resv_regions	= intel_iommu_get_resv_regions,
 	.put_resv_regions	= intel_iommu_put_resv_regions,
 	.apply_resv_region	= intel_iommu_apply_resv_region,
-	.device_group		= pci_device_group,
+	.device_group		= intel_iommu_pci_device_group,
 	.pgsize_bitmap		= INTEL_IOMMU_PGSIZES,
 };
 
-- 
2.17.1


[-- Attachment #6: 0005-iommu-Add-ops-entry-for-vendor-specific-default-doma.patch --]
[-- Type: application/octet-stream, Size: 2485 bytes --]

From 5210d963c9dde1d6bae95f0d338360d7eb92ce5a Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Thu, 21 Mar 2019 11:31:44 +0000
Subject: [PATCH 5/9] iommu: Add ops entry for vendor specific default domain
 type

This adds an iommu ops entry for iommu vendor driver to specify
the type of the default domain for each device. This is needed
for the vendor driver, which already has its own logic to
determine the use of identity domain for a long time, when it
switches to apply default domain.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>

diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 88d589d56ded..516e4d8995c2 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1102,12 +1102,18 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 	 */
 	if (!group->default_domain) {
 		struct iommu_domain *dom;
+		int domain_type = iommu_def_domain_type;
 
-		dom = __iommu_domain_alloc(dev->bus, iommu_def_domain_type);
-		if (!dom && iommu_def_domain_type != IOMMU_DOMAIN_DMA) {
+		if (ops->is_identity_map)
+			domain_type = ops->is_identity_map(dev) ?
+				      IOMMU_DOMAIN_IDENTITY :
+				      IOMMU_DOMAIN_DMA;
+
+		dom = __iommu_domain_alloc(dev->bus, domain_type);
+		if (!dom && domain_type != IOMMU_DOMAIN_DMA) {
 			dev_warn(dev,
 				 "failed to allocate default IOMMU domain of type %u; falling back to IOMMU_DOMAIN_DMA",
-				 iommu_def_domain_type);
+				 domain_type);
 			dom = __iommu_domain_alloc(dev->bus, IOMMU_DOMAIN_DMA);
 		}
 
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index ffbbc7e39cee..a5007d035218 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -186,6 +186,7 @@ struct iommu_resv_region {
  * @of_xlate: add OF master IDs to iommu grouping
  * @is_attach_deferred: Check if domain attach should be deferred from iommu
  *                      driver init to device driver init (default no)
+ * @is_identity_map: vendor customized identity map adjudicator
  * @pgsize_bitmap: bitmap of all possible supported page sizes
  */
 struct iommu_ops {
@@ -230,6 +231,9 @@ struct iommu_ops {
 	int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
 	bool (*is_attach_deferred)(struct iommu_domain *domain, struct device *dev);
 
+	/* Vendor customized identity map adjudicator */
+	bool (*is_identity_map)(struct device *dev);
+
 	unsigned long pgsize_bitmap;
 };
 
-- 
2.17.1


[-- Attachment #7: 0006-iommu-vt-d-Add-is_identity_map-ops-entry.patch --]
[-- Type: application/octet-stream, Size: 1268 bytes --]

From 55d091d75abc677438feef803fa88b1facdc7cb2 Mon Sep 17 00:00:00 2001
From: Lu Baolu <baolu.lu@linux.intel.com>
Date: Thu, 7 Mar 2019 12:53:12 +0800
Subject: [PATCH 6/9] iommu/vt-d: Add is_identity_map ops entry

This adds the is_identity_map ops entry for Intel IOMMU driver.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 1db0ceb33020..e79df3cf548c 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -5344,6 +5344,11 @@ static void intel_iommu_apply_resv_region(struct device *dev,
 	WARN_ON_ONCE(reserve_iova(&dmar_domain->iovad, start, end) == NULL);
 }
 
+static bool intel_iommu_is_identity_map(struct device *dev)
+{
+	return iommu_should_identity_map(dev, 1);
+}
+
 #ifdef CONFIG_INTEL_IOMMU_SVM
 int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sdev)
 {
@@ -5455,6 +5460,7 @@ const struct iommu_ops intel_iommu_ops = {
 	.put_resv_regions	= intel_iommu_put_resv_regions,
 	.apply_resv_region	= intel_iommu_apply_resv_region,
 	.device_group		= intel_iommu_pci_device_group,
+	.is_identity_map	= intel_iommu_is_identity_map,
 	.pgsize_bitmap		= INTEL_IOMMU_PGSIZES,
 };
 
-- 
2.17.1


[-- Attachment #8: 0007-iommu-vt-d-Enable-DMA-remapping-after-rmrr-mapped.patch --]
[-- Type: application/octet-stream, Size: 1889 bytes --]

From 06cabc10e1728142650e545b0038ffb512b45aff Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Fri, 8 Mar 2019 16:12:34 +0000
Subject: [PATCH 7/9] iommu/vt-d: Enable DMA remapping after rmrr mapped

The rmrr devices require identity map of the rmrr regions before
enabling DMA remapping. Otherwise, there will be a window during
which DMA from/to the rmrr regions will be blocked. In order to
alleviate this, we move enabling DMA remapping after all rmrr
regions get mapped.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index e79df3cf548c..3a06e8804b6e 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3519,11 +3519,6 @@ static int __init init_dmars(void)
 		ret = dmar_set_interrupt(iommu);
 		if (ret)
 			goto free_iommu;
-
-		if (!translation_pre_enabled(iommu))
-			iommu_enable_translation(iommu);
-
-		iommu_disable_protect_mem_regions(iommu);
 	}
 
 	return 0;
@@ -4921,7 +4916,6 @@ int __init intel_iommu_init(void)
 		goto out_free_reserved_range;
 	}
 	up_write(&dmar_global_lock);
-	pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
 
 #if defined(CONFIG_X86) && defined(CONFIG_SWIOTLB)
 	swiotlb = 0;
@@ -4944,6 +4938,16 @@ int __init intel_iommu_init(void)
 		register_memory_notifier(&intel_iommu_memory_nb);
 	cpuhp_setup_state(CPUHP_IOMMU_INTEL_DEAD, "iommu/intel:dead", NULL,
 			  intel_iommu_cpu_dead);
+
+	/* Finally, we enable the DMA remapping hardware. */
+	for_each_iommu(iommu, drhd) {
+		if (!translation_pre_enabled(iommu))
+			iommu_enable_translation(iommu);
+
+		iommu_disable_protect_mem_regions(iommu);
+	}
+	pr_info("Intel(R) Virtualization Technology for Directed I/O\n");
+
 	intel_iommu_enabled = 1;
 	intel_iommu_debugfs_init();
 
-- 
2.17.1


[-- Attachment #9: 0008-iommu-vt-d-Allow-IOMMU_DOMAIN_DMA-to-be-allocated-by.patch --]
[-- Type: application/octet-stream, Size: 6655 bytes --]

From a2b312c445ac6f683167d903d93b374441f1018a Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Mon, 11 Mar 2019 14:53:47 +0000
Subject: [PATCH 8/9] iommu/vt-d: Allow IOMMU_DOMAIN_DMA to be allocated by
 iommu_ops

Allowing IOMMU_DOMAIN_DMA type IOMMU domain to be allocated allows the
default_domain of an iommu_group to be set. This delegates device-domain
relationships to the generic IOMMU code.

Signed-off-by: James Sewart <jamessewart@arista.com>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 3a06e8804b6e..2055c11f5978 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -311,6 +311,18 @@ static int hw_pass_through = 1;
 /* si_domain contains mulitple devices */
 #define DOMAIN_FLAG_STATIC_IDENTITY	(1 << 1)
 
+/*
+ * Domain managed externally, don't cleanup if it isn't attached
+ * to any devices.
+ */
+#define DOMAIN_FLAG_MANAGED_EXTERNALLY	(1 << 2)
+
+/*
+ * Set after domain initialisation. Used when allocating dma domains to
+ * defer domain initialisation until it is attached to a device
+ */
+#define DOMAIN_FLAG_INITIALISED	(1 << 3)
+
 #define for_each_domain_iommu(idx, domain)			\
 	for (idx = 0; idx < g_num_of_iommus; idx++)		\
 		if (domain->iommu_refcnt[idx])
@@ -561,6 +573,16 @@ static inline int domain_type_is_vm_or_si(struct dmar_domain *domain)
 				DOMAIN_FLAG_STATIC_IDENTITY);
 }
 
+static inline int domain_managed_externally(struct dmar_domain *domain)
+{
+	return domain->flags & DOMAIN_FLAG_MANAGED_EXTERNALLY;
+}
+
+static inline int domain_is_initialised(struct dmar_domain *domain)
+{
+	return domain->flags & DOMAIN_FLAG_INITIALISED;
+}
+
 static inline int domain_pfn_supported(struct dmar_domain *domain,
 				       unsigned long pfn)
 {
@@ -1671,7 +1693,7 @@ static void disable_dmar_iommu(struct intel_iommu *iommu)
 
 		__dmar_remove_one_dev_info(info);
 
-		if (!domain_type_is_vm_or_si(domain)) {
+		if (!domain_managed_externally(domain)) {
 			/*
 			 * The domain_exit() function  can't be called under
 			 * device_domain_lock, as it takes this lock itself.
@@ -1904,6 +1926,7 @@ static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
 	domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
 	if (!domain->pgd)
 		return -ENOMEM;
+	domain->flags |= DOMAIN_FLAG_INITIALISED;
 	__iommu_flush_cache(iommu, domain->pgd, PAGE_SIZE);
 	return 0;
 }
@@ -1912,6 +1935,9 @@ static void domain_exit(struct dmar_domain *domain)
 {
 	struct page *freelist;
 
+	if (!domain_is_initialised(domain))
+		goto free_mem;
+
 	/* Remove associated devices and clear attached or cached domains */
 	rcu_read_lock();
 	domain_remove_dev_info(domain);
@@ -1924,6 +1950,7 @@ static void domain_exit(struct dmar_domain *domain)
 
 	dma_free_pagelist(freelist);
 
+free_mem:
 	free_domain_mem(domain);
 }
 
@@ -4589,7 +4616,7 @@ static int device_notifier(struct notifier_block *nb,
 			return 0;
 
 		dmar_remove_one_dev_info(dev);
-		if (!domain_type_is_vm_or_si(domain) &&
+		if (!domain_managed_externally(domain) &&
 		    list_empty(&domain->devices))
 			domain_exit(domain);
 	} else if (action == BUS_NOTIFY_ADD_DEVICE) {
@@ -5047,6 +5074,7 @@ static int md_domain_init(struct dmar_domain *domain, int guest_width)
 	domain->pgd = (struct dma_pte *)alloc_pgtable_page(domain->nid);
 	if (!domain->pgd)
 		return -ENOMEM;
+	domain->flags |= DOMAIN_FLAG_INITIALISED;
 	domain_flush_cache(domain, domain->pgd, PAGE_SIZE);
 	return 0;
 }
@@ -5055,28 +5083,43 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 {
 	struct dmar_domain *dmar_domain;
 	struct iommu_domain *domain;
+	int flags = DOMAIN_FLAG_MANAGED_EXTERNALLY;
 
-	if (type != IOMMU_DOMAIN_UNMANAGED)
-		return NULL;
+	switch (type) {
+	case IOMMU_DOMAIN_UNMANAGED:
+		flags |= DOMAIN_FLAG_VIRTUAL_MACHINE | DOMAIN_FLAG_INITIALISED;
+		dmar_domain = alloc_domain(flags);
+		if (!dmar_domain)
+			return NULL;
 
-	dmar_domain = alloc_domain(DOMAIN_FLAG_VIRTUAL_MACHINE);
-	if (!dmar_domain) {
-		pr_err("Can't allocate dmar_domain\n");
-		return NULL;
-	}
-	if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
-		pr_err("Domain initialization failed\n");
-		domain_exit(dmar_domain);
+		if (md_domain_init(dmar_domain, DEFAULT_DOMAIN_ADDRESS_WIDTH)) {
+			pr_err("Domain initialization failed\n");
+			domain_exit(dmar_domain);
+			return NULL;
+		}
+		domain_update_iommu_cap(dmar_domain);
+		domain = &dmar_domain->domain;
+		domain->geometry.aperture_start = 0;
+		domain->geometry.aperture_end =
+			__DOMAIN_MAX_ADDR(dmar_domain->gaw);
+		domain->geometry.force_aperture = true;
+		break;
+	case IOMMU_DOMAIN_DMA:
+		dmar_domain = alloc_domain(flags);
+		if (!dmar_domain)
+			return NULL;
+		/*
+		 * init domain in device attach when we know IOMMU
+		 * capabilities
+		 */
+		break;
+	case IOMMU_DOMAIN_IDENTITY:
+		return &si_domain->domain;
+	default:
 		return NULL;
 	}
-	domain_update_iommu_cap(dmar_domain);
-
-	domain = &dmar_domain->domain;
-	domain->geometry.aperture_start = 0;
-	domain->geometry.aperture_end   = __DOMAIN_MAX_ADDR(dmar_domain->gaw);
-	domain->geometry.force_aperture = true;
 
-	return domain;
+	return &dmar_domain->domain;
 }
 
 static void intel_iommu_domain_free(struct iommu_domain *domain)
@@ -5107,7 +5150,7 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 			dmar_remove_one_dev_info(dev);
 			rcu_read_unlock();
 
-			if (!domain_type_is_vm_or_si(old_domain) &&
+			if (!domain_managed_externally(old_domain) &&
 			     list_empty(&old_domain->devices))
 				domain_exit(old_domain);
 		}
@@ -5117,6 +5160,16 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 	if (!iommu)
 		return -ENODEV;
 
+	/*
+	 * Initialise domain with IOMMU capabilities if it isn't already
+	 * initialised
+	 */
+	if (!domain_is_initialised(dmar_domain)) {
+		if (domain_init(dmar_domain, iommu,
+				DEFAULT_DOMAIN_ADDRESS_WIDTH))
+			return -ENOMEM;
+	}
+
 	/* check if this iommu agaw is sufficient for max mapped address */
 	addr_width = agaw_to_width(iommu->agaw);
 	if (addr_width > cap_mgaw(iommu->cap))
@@ -5163,6 +5216,10 @@ static int intel_iommu_map(struct iommu_domain *domain,
 	int prot = 0;
 	int ret;
 
+	/* Don't bother if hardware passthrough used. */
+	if (dmar_domain == si_domain && hw_pass_through)
+		return 0;
+
 	if (iommu_prot & IOMMU_READ)
 		prot |= DMA_PTE_READ;
 	if (iommu_prot & IOMMU_WRITE)
-- 
2.17.1


[-- Attachment #10: 0009-iommu-vt-d-Remove-lazy-allocation-of-domains.patch --]
[-- Type: application/octet-stream, Size: 14536 bytes --]

From 44a879dae8c246cd52fa754e99a1d43bc019c757 Mon Sep 17 00:00:00 2001
From: James Sewart <jamessewart@arista.com>
Date: Mon, 11 Mar 2019 14:55:01 +0000
Subject: [PATCH 9/9] iommu/vt-d: Remove lazy allocation of domains

The generic IOMMU code will allocate and attach a default domain to each
device that comes online. This patch removes the lazy domain allocation
and early reserved region mapping that is now redundant.

Signed-off-by: James Sewart <jamessewart@arista.com>

diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 2055c11f5978..4bf719a82b64 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2463,21 +2463,6 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
 	spin_unlock_irqrestore(&device_domain_lock, flags);
 }
 
-/*
- * find_domain
- * Note: we use struct device->archdata.iommu stores the info
- */
-static struct dmar_domain *find_domain(struct device *dev)
-{
-	struct device_domain_info *info;
-
-	/* No lock here, assumes no domain exit in normal case */
-	info = dev->archdata.iommu;
-	if (likely(info))
-		return info->domain;
-	return NULL;
-}
-
 static inline struct device_domain_info *
 dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
 {
@@ -2539,8 +2524,11 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
 	}
 
 	spin_lock_irqsave(&device_domain_lock, flags);
-	if (dev)
-		found = find_domain(dev);
+	if (dev) {
+		struct iommu_domain *io_domain = iommu_get_domain_for_dev(dev);
+		if (io_domain)
+			found = to_dmar_domain(io_domain);
+	}
 
 	if (!found) {
 		struct device_domain_info *info2;
@@ -2608,118 +2596,6 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
 	return domain;
 }
 
-static int get_last_alias(struct pci_dev *pdev, u16 alias, void *opaque)
-{
-	*(u16 *)opaque = alias;
-	return 0;
-}
-
-static struct dmar_domain *find_or_alloc_domain(struct device *dev, int gaw)
-{
-	struct device_domain_info *info;
-	struct dmar_domain *domain = NULL;
-	struct intel_iommu *iommu;
-	u16 dma_alias;
-	unsigned long flags;
-	u8 bus, devfn;
-
-	iommu = device_to_iommu(dev, &bus, &devfn);
-	if (!iommu)
-		return NULL;
-
-	if (dev_is_pci(dev)) {
-		struct pci_dev *pdev = to_pci_dev(dev);
-
-		pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
-
-		spin_lock_irqsave(&device_domain_lock, flags);
-		info = dmar_search_domain_by_dev_info(pci_domain_nr(pdev->bus),
-						      PCI_BUS_NUM(dma_alias),
-						      dma_alias & 0xff);
-		if (info) {
-			iommu = info->iommu;
-			domain = info->domain;
-		}
-		spin_unlock_irqrestore(&device_domain_lock, flags);
-
-		/* DMA alias already has a domain, use it */
-		if (info)
-			goto out;
-	}
-
-	/* Allocate and initialize new domain for the device */
-	domain = alloc_domain(0);
-	if (!domain)
-		return NULL;
-	if (domain_init(domain, iommu, gaw)) {
-		domain_exit(domain);
-		return NULL;
-	}
-
-out:
-
-	return domain;
-}
-
-static struct dmar_domain *set_domain_for_dev(struct device *dev,
-					      struct dmar_domain *domain)
-{
-	struct intel_iommu *iommu;
-	struct dmar_domain *tmp;
-	u16 req_id, dma_alias;
-	u8 bus, devfn;
-
-	iommu = device_to_iommu(dev, &bus, &devfn);
-	if (!iommu)
-		return NULL;
-
-	req_id = ((u16)bus << 8) | devfn;
-
-	if (dev_is_pci(dev)) {
-		struct pci_dev *pdev = to_pci_dev(dev);
-
-		pci_for_each_dma_alias(pdev, get_last_alias, &dma_alias);
-
-		/* register PCI DMA alias device */
-		if (req_id != dma_alias) {
-			tmp = dmar_insert_one_dev_info(iommu, PCI_BUS_NUM(dma_alias),
-					dma_alias & 0xff, NULL, domain);
-
-			if (!tmp || tmp != domain)
-				return tmp;
-		}
-	}
-
-	tmp = dmar_insert_one_dev_info(iommu, bus, devfn, dev, domain);
-	if (!tmp || tmp != domain)
-		return tmp;
-
-	return domain;
-}
-
-static struct dmar_domain *get_domain_for_dev(struct device *dev, int gaw)
-{
-	struct dmar_domain *domain, *tmp;
-
-	domain = find_domain(dev);
-	if (domain)
-		goto out;
-
-	domain = find_or_alloc_domain(dev, gaw);
-	if (!domain)
-		goto out;
-
-	tmp = set_domain_for_dev(dev, domain);
-	if (!tmp || domain != tmp) {
-		domain_exit(domain);
-		domain = tmp;
-	}
-
-out:
-
-	return domain;
-}
-
 static int iommu_domain_identity_map(struct dmar_domain *domain,
 				     unsigned long long start,
 				     unsigned long long end)
@@ -2745,72 +2621,6 @@ static int iommu_domain_identity_map(struct dmar_domain *domain,
 				DMA_PTE_READ|DMA_PTE_WRITE);
 }
 
-static int domain_prepare_identity_map(struct device *dev,
-				       struct dmar_domain *domain,
-				       unsigned long long start,
-				       unsigned long long end)
-{
-	/* For _hardware_ passthrough, don't bother. But for software
-	   passthrough, we do it anyway -- it may indicate a memory
-	   range which is reserved in E820, so which didn't get set
-	   up to start with in si_domain */
-	if (domain == si_domain && hw_pass_through) {
-		dev_warn(dev, "Ignoring identity map for HW passthrough [0x%Lx - 0x%Lx]\n",
-			 start, end);
-		return 0;
-	}
-
-	dev_info(dev, "Setting identity map [0x%Lx - 0x%Lx]\n", start, end);
-
-	if (end < start) {
-		WARN(1, "Your BIOS is broken; RMRR ends before it starts!\n"
-			"BIOS vendor: %s; Ver: %s; Product Version: %s\n",
-			dmi_get_system_info(DMI_BIOS_VENDOR),
-			dmi_get_system_info(DMI_BIOS_VERSION),
-		     dmi_get_system_info(DMI_PRODUCT_VERSION));
-		return -EIO;
-	}
-
-	if (end >> agaw_to_width(domain->agaw)) {
-		WARN(1, "Your BIOS is broken; RMRR exceeds permitted address width (%d bits)\n"
-		     "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
-		     agaw_to_width(domain->agaw),
-		     dmi_get_system_info(DMI_BIOS_VENDOR),
-		     dmi_get_system_info(DMI_BIOS_VERSION),
-		     dmi_get_system_info(DMI_PRODUCT_VERSION));
-		return -EIO;
-	}
-
-	return iommu_domain_identity_map(domain, start, end);
-}
-
-static int iommu_prepare_identity_map(struct device *dev,
-				      unsigned long long start,
-				      unsigned long long end)
-{
-	struct dmar_domain *domain;
-	int ret;
-
-	domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
-	if (!domain)
-		return -ENOMEM;
-
-	ret = domain_prepare_identity_map(dev, domain, start, end);
-	if (ret)
-		domain_exit(domain);
-
-	return ret;
-}
-
-static inline int iommu_prepare_rmrr_dev(struct dmar_rmrr_unit *rmrr,
-					 struct device *dev)
-{
-	if (dev->archdata.iommu == DUMMY_DEVICE_DOMAIN_INFO)
-		return 0;
-	return iommu_prepare_identity_map(dev, rmrr->base_address,
-					  rmrr->end_address);
-}
-
 static inline struct iommu_resv_region *iommu_get_isa_resv_region(void)
 {
 	if (!isa_resv_region)
@@ -2821,29 +2631,6 @@ static inline struct iommu_resv_region *iommu_get_isa_resv_region(void)
 	return isa_resv_region;
 }
 
-#ifdef CONFIG_INTEL_IOMMU_FLOPPY_WA
-static inline void iommu_prepare_isa(struct pci_dev *pdev)
-{
-	int ret;
-	struct iommu_resv_region *reg = iommu_get_isa_resv_region();
-
-	if (!reg)
-		return;
-
-	pr_info("Prepare 0-16MiB unity mapping for LPC\n");
-	ret = iommu_prepare_identity_map(&pdev->dev, reg->start,
-			reg->start + reg->length - 1);
-
-	if (ret)
-		pr_err("Failed to create 0-16MiB identity map - floppy might not work\n");
-}
-#else
-static inline void iommu_prepare_isa(struct pci_dev *pdev)
-{
-	return;
-}
-#endif /* !CONFIG_INTEL_IOMMU_FLPY_WA */
-
 static int md_domain_init(struct dmar_domain *domain, int guest_width);
 
 static int __init si_domain_init(int hw)
@@ -3066,18 +2853,10 @@ static int __init dev_prepare_static_identity_mapping(struct device *dev, int hw
 
 static int __init iommu_prepare_static_identity_mapping(int hw)
 {
-	struct pci_dev *pdev = NULL;
 	struct dmar_drhd_unit *drhd;
 	struct intel_iommu *iommu;
 	struct device *dev;
-	int i;
-	int ret = 0;
-
-	for_each_pci_dev(pdev) {
-		ret = dev_prepare_static_identity_mapping(&pdev->dev, hw);
-		if (ret)
-			return ret;
-	}
+	int i, ret = 0;
 
 	for_each_active_iommu(iommu, drhd)
 		for_each_active_dev_scope(drhd->devices, drhd->devices_cnt, i, dev) {
@@ -3324,12 +3103,9 @@ static int copy_translation_tables(struct intel_iommu *iommu)
 static int __init init_dmars(void)
 {
 	struct dmar_drhd_unit *drhd;
-	struct dmar_rmrr_unit *rmrr;
 	bool copied_tables = false;
-	struct device *dev;
-	struct pci_dev *pdev;
 	struct intel_iommu *iommu;
-	int i, ret;
+	int ret;
 
 	/*
 	 * for each drhd
@@ -3483,36 +3259,6 @@ static int __init init_dmars(void)
 			goto free_iommu;
 		}
 	}
-	/*
-	 * For each rmrr
-	 *   for each dev attached to rmrr
-	 *   do
-	 *     locate drhd for dev, alloc domain for dev
-	 *     allocate free domain
-	 *     allocate page table entries for rmrr
-	 *     if context not allocated for bus
-	 *           allocate and init context
-	 *           set present in root table for this bus
-	 *     init context with domain, translation etc
-	 *    endfor
-	 * endfor
-	 */
-	pr_info("Setting RMRR:\n");
-	for_each_rmrr_units(rmrr) {
-		/* some BIOS lists non-exist devices in DMAR table. */
-		for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
-					  i, dev) {
-			ret = iommu_prepare_rmrr_dev(rmrr, dev);
-			if (ret)
-				pr_err("Mapping reserved region failed\n");
-		}
-	}
-
-	pdev = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
-	if (pdev) {
-		iommu_prepare_isa(pdev);
-		pci_dev_put(pdev);
-	}
 
 domains_done:
 
@@ -3595,53 +3341,6 @@ static unsigned long intel_alloc_iova(struct device *dev,
 	return iova_pfn;
 }
 
-struct dmar_domain *get_valid_domain_for_dev(struct device *dev)
-{
-	struct dmar_domain *domain, *tmp;
-	struct dmar_rmrr_unit *rmrr;
-	struct device *i_dev;
-	int i, ret;
-
-	domain = find_domain(dev);
-	if (domain)
-		goto out;
-
-	domain = find_or_alloc_domain(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH);
-	if (!domain)
-		goto out;
-
-	/* We have a new domain - setup possible RMRRs for the device */
-	rcu_read_lock();
-	for_each_rmrr_units(rmrr) {
-		for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
-					  i, i_dev) {
-			if (i_dev != dev)
-				continue;
-
-			ret = domain_prepare_identity_map(dev, domain,
-							  rmrr->base_address,
-							  rmrr->end_address);
-			if (ret)
-				dev_err(dev, "Mapping reserved region failed\n");
-		}
-	}
-	rcu_read_unlock();
-
-	tmp = set_domain_for_dev(dev, domain);
-	if (!tmp || domain != tmp) {
-		domain_exit(domain);
-		domain = tmp;
-	}
-
-out:
-
-	if (!domain)
-		dev_err(dev, "Allocating domain failed\n");
-
-
-	return domain;
-}
-
 /* Check if the dev needs to go through non-identity map and unmap process.*/
 static int iommu_no_mapping(struct device *dev)
 {
@@ -3688,6 +3387,7 @@ static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
 				     size_t size, int dir, u64 dma_mask)
 {
 	struct dmar_domain *domain;
+	struct iommu_domain *io_domain;
 	phys_addr_t start_paddr;
 	unsigned long iova_pfn;
 	int prot = 0;
@@ -3700,9 +3400,10 @@ static dma_addr_t __intel_map_single(struct device *dev, phys_addr_t paddr,
 	if (iommu_no_mapping(dev))
 		return paddr;
 
-	domain = get_valid_domain_for_dev(dev);
-	if (!domain)
+	io_domain = iommu_get_domain_for_dev(dev);
+	if (!io_domain)
 		return DMA_MAPPING_ERROR;
+	domain = to_dmar_domain(io_domain);
 
 	iommu = domain_get_iommu(domain);
 	size = aligned_nrpages(paddr, size);
@@ -3762,6 +3463,7 @@ static dma_addr_t intel_map_resource(struct device *dev, phys_addr_t phys_addr,
 static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
 {
 	struct dmar_domain *domain;
+	struct iommu_domain *io_domain;
 	unsigned long start_pfn, last_pfn;
 	unsigned long nrpages;
 	unsigned long iova_pfn;
@@ -3771,8 +3473,9 @@ static void intel_unmap(struct device *dev, dma_addr_t dev_addr, size_t size)
 	if (iommu_no_mapping(dev))
 		return;
 
-	domain = find_domain(dev);
-	BUG_ON(!domain);
+	io_domain = iommu_get_domain_for_dev(dev);
+	BUG_ON(!io_domain);
+	domain = to_dmar_domain(io_domain);
 
 	iommu = domain_get_iommu(domain);
 
@@ -3906,6 +3609,7 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
 {
 	int i;
 	struct dmar_domain *domain;
+	struct iommu_domain *io_domain;
 	size_t size = 0;
 	int prot = 0;
 	unsigned long iova_pfn;
@@ -3918,9 +3622,10 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
 	if (iommu_no_mapping(dev))
 		return intel_nontranslate_map_sg(dev, sglist, nelems, dir);
 
-	domain = get_valid_domain_for_dev(dev);
-	if (!domain)
+	io_domain = iommu_get_domain_for_dev(dev);
+	if (!io_domain)
 		return 0;
+	domain = to_dmar_domain(io_domain);
 
 	iommu = domain_get_iommu(domain);
 
@@ -4611,9 +4316,11 @@ static int device_notifier(struct notifier_block *nb,
 		return 0;
 
 	if (action == BUS_NOTIFY_REMOVED_DEVICE) {
-		domain = find_domain(dev);
-		if (!domain)
+		struct iommu_domain *io_domain;
+		io_domain = iommu_get_domain_for_dev(dev);
+		if (!io_domain)
 			return 0;
+		domain = to_dmar_domain(io_domain);
 
 		dmar_remove_one_dev_info(dev);
 		if (!domain_managed_externally(domain) &&
@@ -5143,9 +4850,11 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
 	/* normally dev is not mapped */
 	if (unlikely(domain_context_mapped(dev))) {
 		struct dmar_domain *old_domain;
+		struct iommu_domain *old_io_domain;
 
-		old_domain = find_domain(dev);
-		if (old_domain) {
+		old_io_domain = iommu_get_domain_for_dev(dev);
+		if (old_io_domain) {
+			old_domain = to_dmar_domain(old_io_domain);
 			rcu_read_lock();
 			dmar_remove_one_dev_info(dev);
 			rcu_read_unlock();
@@ -5416,13 +5125,15 @@ int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct intel_svm_dev *sd
 	struct device_domain_info *info;
 	struct context_entry *context;
 	struct dmar_domain *domain;
+	struct iommu_domain *io_domain;
 	unsigned long flags;
 	u64 ctx_lo;
 	int ret;
 
-	domain = get_valid_domain_for_dev(sdev->dev);
-	if (!domain)
+	io_domain = iommu_get_domain_for_dev(sdev->dev);
+	if (!io_domain)
 		return -EINVAL;
+	domain = to_dmar_domain(io_domain);
 
 	spin_lock_irqsave(&device_domain_lock, flags);
 	spin_lock(&iommu->lock);
-- 
2.17.1


  reply	other threads:[~2019-03-29 15:27 UTC|newest]

Thread overview: 77+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-03-04 15:41 [PATCH 0/4] iommu/vt-d: Fix-up device-domain relationship by refactoring to use iommu group default domain James Sewart
2019-03-04 15:45 ` [PATCH 1/4] iommu: Move iommu_group_create_direct_mappings to after device_attach James Sewart
2019-03-04 15:46 ` [PATCH 2/4] iommu/vt-d: Implement apply_resv_region for reserving IOVA ranges James Sewart
2019-03-04 15:46   ` [PATCH 3/4] iommu/vt-d: Allow IOMMU_DOMAIN_DMA and IOMMU_DOMAIN_IDENTITY to be allocated James Sewart
2019-03-04 15:47     ` [PATCH 4/4] iommu/vt-d: Remove lazy allocation of domains James Sewart
2019-03-05  6:59       ` Lu Baolu
2019-03-05 11:46         ` James Sewart
2019-03-06  7:00           ` Lu Baolu
2019-03-06  7:00             ` Lu Baolu
2019-03-06 18:08             ` James Sewart
2019-03-06 18:08               ` James Sewart via iommu
2019-03-07  6:31               ` Lu Baolu
2019-03-07  6:31                 ` Lu Baolu
2019-03-07 10:21                 ` James Sewart
2019-03-08  1:09                   ` Lu Baolu
2019-03-08  3:09                   ` Lu Baolu
2019-03-08  3:09                     ` Lu Baolu
2019-03-08 16:57                     ` James Sewart
2019-03-09  1:53                       ` Lu Baolu
2019-03-09 11:49                         ` James Sewart
2019-03-10  2:51                           ` Lu Baolu
2019-03-10  2:51                             ` Lu Baolu
2019-03-05  6:46     ` [PATCH 3/4] iommu/vt-d: Allow IOMMU_DOMAIN_DMA and IOMMU_DOMAIN_IDENTITY to be allocated Lu Baolu
2019-03-05 11:34       ` James Sewart
2019-03-08  1:20     ` Dmitry Safonov
2019-03-08  1:20       ` Dmitry Safonov via iommu
2019-03-09 11:57       ` James Sewart
2019-03-05  6:05 ` [PATCH 0/4] iommu/vt-d: Fix-up device-domain relationship by refactoring to use iommu group default domain Lu Baolu
2019-03-05 11:14   ` James Sewart
2019-03-06  6:27     ` Lu Baolu
2019-03-14 11:56 ` [PATCH v2 0/7] " James Sewart
2019-03-14 11:57   ` [PATCH v2 1/7] iommu: Move iommu_group_create_direct_mappings to after device_attach James Sewart
2019-03-14 11:57     ` James Sewart via iommu
2019-03-14 11:58   ` [PATCH v2 2/7] iommu/vt-d: Implement apply_resv_region for reserving IOVA ranges James Sewart
2019-03-14 11:58   ` [PATCH v2 3/7] iommu/vt-d: Expose ISA direct mapping region via iommu_get_resv_regions James Sewart
2019-03-14 11:58     ` James Sewart
2019-03-15  2:19     ` Lu Baolu
2019-03-22  9:57       ` James Sewart
2019-03-25  2:03         ` Lu Baolu
2019-03-25  2:03           ` Lu Baolu
2019-03-25 12:57           ` James Sewart
2019-03-26  1:10             ` Lu Baolu
2019-03-26  1:10               ` Lu Baolu
2019-03-26  1:24             ` Lu Baolu
2019-03-28 18:37               ` James Sewart
2019-03-29 15:26                 ` James Sewart [this message]
2019-04-04  6:49                   ` Lu Baolu
2019-04-05 18:02                     ` James Sewart
2019-04-05 18:02                       ` James Sewart via iommu
2019-04-08  2:43                       ` Lu Baolu
2019-04-08  2:43                         ` Lu Baolu
2019-04-08  2:43                         ` Lu Baolu
2019-04-10  5:22                       ` Lu Baolu
2019-04-10  5:22                         ` Lu Baolu
2019-04-15 14:16                         ` James Sewart
2019-04-15 14:16                           ` James Sewart via iommu
2019-04-16  2:18                           ` Lu Baolu
2019-04-16  2:18                             ` Lu Baolu
2019-04-24 23:47                             ` Tom Murphy
2019-04-24 23:47                               ` Tom Murphy via iommu
2019-04-25  1:15                               ` Lu Baolu
2019-04-25  1:15                                 ` Lu Baolu
2019-04-25  1:15                                 ` Lu Baolu
2019-03-14 11:58   ` [PATCH v2 4/7] iommu/vt-d: Ignore domain parameter in attach_device if device requires identity map James Sewart
2019-03-15  2:30     ` Lu Baolu
2019-03-14 11:58   ` [PATCH v2 5/7] iommu/vt-d: Enable DMA remapping after rmrr mapped James Sewart
2019-03-14 11:59   ` [PATCH v2 6/7] iommu/vt-d: Allow IOMMU_DOMAIN_DMA to be allocated by iommu_ops James Sewart
2019-03-14 11:59     ` James Sewart via iommu
2019-03-14 11:59   ` [PATCH v2 7/7] iommu/vt-d: Remove lazy allocation of domains James Sewart
2019-03-14 23:35     ` Jacob Pan
2019-03-14 23:35       ` Jacob Pan
2019-03-22 10:07       ` James Sewart
2019-03-15  3:13   ` [PATCH v2 0/7] iommu/vt-d: Fix-up device-domain relationship by refactoring to use iommu group default domain Lu Baolu
2019-03-19 13:35     ` James Sewart
2019-03-20  1:26       ` Lu Baolu
2019-03-22 10:05         ` James Sewart
     [not found]           ` <0359F732-374F-4EDB-B49C-14B2F1BB637D-nzgTgzXrdUbQT0dZR+AlfA@public.gmane.org>
2019-03-25  2:16             ` Lu Baolu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8B1FC0C7-9BAC-498D-B1F0-0138EACF75C2@arista.com \
    --to=jamessewart@arista.com \
    --cc=baolu.lu@linux.intel.com \
    --cc=dima@arista.com \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jacob.jun.pan@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=tmurphy@arista.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.