From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: iommu@lists.linux-foundation.org,
LKML <linux-kernel@vger.kernel.org>,
Joerg Roedel <joro@8bytes.org>, Jason Gunthorpe <jgg@nvidia.com>,
"Christoph Hellwig" <hch@infradead.org>
Cc: "Lu Baolu" <baolu.lu@linux.intel.com>,
Raj Ashok <ashok.raj@intel.com>,
"Kumar, Sanjay K" <sanjay.k.kumar@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
Tony Luck <tony.luck@intel.com>,
mike.campin@intel.com, Yi Liu <yi.l.liu@intel.com>,
"Tian, Kevin" <kevin.tian@intel.com>
Subject: [RFC 5/7] iommu/vt-d: Add support for KVA PASID mode
Date: Tue, 21 Sep 2021 13:29:39 -0700 [thread overview]
Message-ID: <1632256181-36071-6-git-send-email-jacob.jun.pan@linux.intel.com> (raw)
In-Reply-To: <1632256181-36071-1-git-send-email-jacob.jun.pan@linux.intel.com>
To support KVA fast mode, the VT-d driver must support domain allocation
of IOMMU_DOMAIN_KVA type. Since all devices in fast KVA mode share the
same kernel mapping, a single KVA domain is sufficient. This global KVA
domain contains the kernel mapping, i.e. init_mm.pgd.
The programming of the KVA domain follows the existing flow of auxiliary
domain attachment.
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
---
drivers/iommu/intel/iommu.c | 59 ++++++++++++++++++++++++++++++++++---
1 file changed, 55 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index cbcfd178c16f..0dabd5f75acf 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -293,6 +293,9 @@ static inline void context_clear_entry(struct context_entry *context)
* 3. Each iommu mapps to this domain if successful.
*/
static struct dmar_domain *si_domain;
+
+/* This domain is used for shared virtual addressing with CPU kernel mapping */
+static struct dmar_domain *kva_domain;
static int hw_pass_through = 1;
#define for_each_domain_iommu(idx, domain) \
@@ -1989,6 +1992,10 @@ static void domain_exit(struct dmar_domain *domain)
/* Remove associated devices and clear attached or cached domains */
domain_remove_dev_info(domain);
+ /* There is no IOMMU page table for KVA */
+ if (domain->pgd == (struct dma_pte *)init_mm.pgd)
+ return;
+
/* destroy iovas */
if (domain->domain.type == IOMMU_DOMAIN_DMA)
iommu_put_dma_cookie(&domain->domain);
@@ -2533,6 +2540,10 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
int agaw, level;
int flags = 0;
+ if (domain->domain.type == IOMMU_DOMAIN_KVA) {
+ flags |= PASID_FLAG_SUPERVISOR_MODE;
+ goto do_setup;
+ }
/*
* Skip top levels of page tables for iommu which has
* less agaw than default. Unnecessary for PT mode.
@@ -2554,7 +2565,7 @@ static int domain_setup_first_level(struct intel_iommu *iommu,
if (domain->domain.type == IOMMU_DOMAIN_UNMANAGED)
flags |= PASID_FLAG_PAGE_SNOOP;
-
+do_setup:
return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid,
domain->iommu_did[iommu->seq_id],
flags);
@@ -2713,7 +2724,28 @@ static int iommu_domain_identity_map(struct dmar_domain *domain,
}
static int md_domain_init(struct dmar_domain *domain, int guest_width);
+#ifdef CONFIG_INTEL_IOMMU_SVM
+static int __init kva_domain_init(void)
+{
+ struct dmar_domain *dmar_domain;
+ struct iommu_domain *domain;
+ kva_domain = alloc_domain(0);
+ if (!kva_domain) {
+ pr_err("Can't allocate KVA domain\n");
+ return -EFAULT;
+ }
+ kva_domain->pgd = (struct dma_pte *)init_mm.pgd;
+ domain = &kva_domain->domain;
+ domain->type = IOMMU_DOMAIN_KVA;
+ /* REVISIT: may not need this other than sanity check */
+ domain->geometry.aperture_start = 0;
+ domain->geometry.aperture_end =
+ __DOMAIN_MAX_ADDR(dmar_domain->gaw);
+ domain->geometry.force_aperture = true;
+ return 0;
+}
+#endif
static int __init si_domain_init(int hw)
{
struct dmar_rmrr_unit *rmrr;
@@ -3363,6 +3395,11 @@ static int __init init_dmars(void)
down_write(&dmar_global_lock);
if (ret)
goto free_iommu;
+ /* For in-kernel DMA with PASID in SVA */
+ ret = kva_domain_init();
+ if (ret)
+ goto free_iommu;
+
}
#endif
ret = dmar_set_interrupt(iommu);
@@ -4558,6 +4595,9 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
domain->geometry.force_aperture = true;
return domain;
+ case IOMMU_DOMAIN_KVA:
+ /* Use a global domain for shared KVA mapping */
+ return &kva_domain->domain;
case IOMMU_DOMAIN_IDENTITY:
return &si_domain->domain;
default:
@@ -4583,7 +4623,8 @@ is_aux_domain(struct device *dev, struct iommu_domain *domain)
struct device_domain_info *info = get_domain_info(dev);
return info && info->auxd_enabled &&
- domain->type == IOMMU_DOMAIN_UNMANAGED;
+ (domain->type == IOMMU_DOMAIN_UNMANAGED ||
+ domain->type == IOMMU_DOMAIN_KVA);
}
static inline struct subdev_domain_info *
@@ -4693,8 +4734,8 @@ static int aux_domain_add_dev(struct dmar_domain *domain,
if (ret)
goto attach_failed;
- /* Setup the PASID entry for mediated devices: */
- if (domain_use_first_level(domain))
+ /* Setup the PASID entry for devices do DMA with the default PASID */
+ if (domain_use_first_level(domain) || domain->domain.type == IOMMU_DOMAIN_KVA)
ret = domain_setup_first_level(iommu, domain, dev,
domain->default_pasid);
else
@@ -4761,6 +4802,10 @@ static int prepare_domain_attach_device(struct iommu_domain *domain,
if (!iommu)
return -ENODEV;
+ if (domain->type == IOMMU_DOMAIN_KVA) {
+ pr_info("TODO: KVA dom check if device can do full 64bit DMA");
+ return 0;
+ }
/* 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))
@@ -5588,6 +5633,12 @@ static int intel_enable_pasid_dma(struct device *dev, u32 pasid, int mode)
ret = domain_setup_first_level(info->iommu, info->domain, dev,
pasid);
break;
+ case IOMMU_DMA_PASID_KVA:
+ /*
+ * KVA mode should be handled in the aux domain attach where the default
+ * PASID of the aux domain is used for setting up PASID FL.
+ */
+ fallthrough;
default:
dev_err(dev, "Invalid PASID DMA mode %d", mode);
ret = -EINVAL;
--
2.25.1
next prev parent reply other threads:[~2021-09-22 5:13 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-21 20:29 [RFC 0/7] Support in-kernel DMA with PASID and SVA Jacob Pan
2021-09-21 20:29 ` [RFC 1/7] ioasid: reserve special PASID for in-kernel DMA Jacob Pan
2021-09-21 20:29 ` [RFC 2/7] dma-iommu: Add API for DMA request with PASID Jacob Pan
2021-09-21 20:29 ` [RFC 3/7] iommu/vt-d: Add DMA w/ PASID support for PA and IOVA Jacob Pan
2021-09-21 20:29 ` [RFC 4/7] dma-iommu: Add support for DMA w/ PASID in KVA Jacob Pan
2021-09-21 20:29 ` Jacob Pan [this message]
2021-09-21 20:29 ` [RFC 6/7] iommu: Add KVA map API Jacob Pan
2021-09-21 20:29 ` [RFC 7/7] dma/idxd: Use dma-iommu PASID API instead of SVA lib Jacob Pan
2021-09-22 17:04 ` [RFC 0/7] Support in-kernel DMA with PASID and SVA Jason Gunthorpe
2021-09-29 19:37 ` Jacob Pan
2021-09-29 19:39 ` Jason Gunthorpe
2021-09-29 22:57 ` Jacob Pan
2021-09-29 23:43 ` Jason Gunthorpe
2021-09-30 14:22 ` Campin, Mike
2021-09-30 15:21 ` Jacob Pan
2021-10-01 12:24 ` Barry Song
2021-10-01 12:36 ` Jason Gunthorpe
2021-10-01 12:45 ` Barry Song
2021-10-04 16:40 ` Jacob Pan
2021-10-04 18:21 ` Jason Gunthorpe
2021-10-07 5:43 ` Barry Song
2021-10-07 11:32 ` Jason Gunthorpe
2021-10-07 11:54 ` Barry Song
2021-10-07 11:59 ` Jason Gunthorpe
2021-10-07 17:50 ` Jacob Pan
2021-10-07 17:48 ` Jason Gunthorpe
2021-10-07 18:08 ` Jacob Pan
2021-10-07 19:11 ` Jacob Pan
2021-10-07 19:10 ` Jason Gunthorpe
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=1632256181-36071-6-git-send-email-jacob.jun.pan@linux.intel.com \
--to=jacob.jun.pan@linux.intel.com \
--cc=ashok.raj@intel.com \
--cc=baolu.lu@linux.intel.com \
--cc=dave.jiang@intel.com \
--cc=hch@infradead.org \
--cc=iommu@lists.linux-foundation.org \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mike.campin@intel.com \
--cc=sanjay.k.kumar@intel.com \
--cc=tony.luck@intel.com \
--cc=yi.l.liu@intel.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