From: James Sewart <jamessewart@arista.com>
To: iommu@lists.linux-foundation.org
Cc: Tom Murphy <tmurphy@arista.com>, Dmitry Safonov <dima@arista.com>,
Jacob Pan <jacob.jun.pan@linux.intel.com>,
linux-kernel@vger.kernel.org, Lu Baolu <baolu.lu@linux.intel.com>
Subject: [PATCH v2 6/7] iommu/vt-d: Allow IOMMU_DOMAIN_DMA to be allocated by iommu_ops
Date: Thu, 14 Mar 2019 11:59:17 +0000 [thread overview]
Message-ID: <C8765B75-BA3F-4DBE-8281-363A586BD8C3@arista.com> (raw)
In-Reply-To: <83B82113-8AE5-4B0C-A079-F389520525BD@arista.com>
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>
---
drivers/iommu/intel-iommu.c | 99 +++++++++++++++++++++++++++++--------
1 file changed, 78 insertions(+), 21 deletions(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 35821df70f78..2c9d793af394 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -309,6 +309,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])
@@ -560,6 +572,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)
{
@@ -1664,7 +1686,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.
@@ -1897,6 +1919,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;
}
@@ -1909,6 +1932,9 @@ static void domain_exit(struct dmar_domain *domain)
if (!domain)
return;
+ 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);
@@ -1921,6 +1947,7 @@ static void domain_exit(struct dmar_domain *domain)
dma_free_pagelist(freelist);
+free_mem:
free_domain_mem(domain);
}
@@ -4585,7 +4612,7 @@ static int device_notifier(struct notifier_block *nb,
return 0;
dmar_remove_one_dev_info(domain, dev);
- if (!domain_type_is_vm_or_si(domain) && list_empty(&domain->devices))
+ if (!domain_managed_externally(domain) && list_empty(&domain->devices))
domain_exit(domain);
return 0;
@@ -5039,6 +5066,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;
}
@@ -5047,28 +5075,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)
@@ -5099,8 +5142,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
dmar_remove_one_dev_info(old_domain, dev);
rcu_read_unlock();
- if (!domain_type_is_vm_or_si(old_domain) &&
- list_empty(&old_domain->devices))
+ if (list_empty(&old_domain->devices) &&
+ !domain_managed_externally(old_domain))
domain_exit(old_domain);
}
}
@@ -5114,6 +5157,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))
@@ -5160,6 +5213,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
next prev parent reply other threads:[~2019-03-14 12:00 UTC|newest]
Thread overview: 55+ 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 18:08 ` James Sewart
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 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-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-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: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-15 2:19 ` Lu Baolu
2019-03-22 9:57 ` James Sewart
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:24 ` Lu Baolu
2019-03-28 18:37 ` James Sewart
2019-03-29 15:26 ` James Sewart
2019-04-04 6:49 ` Lu Baolu
2019-04-05 18:02 ` James Sewart
2019-04-08 2:43 ` Lu Baolu
2019-04-10 5:22 ` Lu Baolu
2019-04-15 14:16 ` James Sewart
2019-04-16 2:18 ` Lu Baolu
2019-04-24 23:47 ` Tom Murphy
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 ` James Sewart [this message]
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-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
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=C8765B75-BA3F-4DBE-8281-363A586BD8C3@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 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).