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: "Tian, Kevin" <kevin.tian@intel.com>,
Tony Luck <tony.luck@intel.com>,
Dave Jiang <dave.jiang@intel.com>,
Raj Ashok <ashok.raj@intel.com>,
"Kumar, Sanjay K" <sanjay.k.kumar@intel.com>,
mike.campin@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
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu
WARNING: multiple messages have this Message-ID (diff)
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: 58+ 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 ` 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 ` 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 ` 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 ` 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
2021-09-21 20:29 ` Jacob Pan [this message]
2021-09-21 20:29 ` [RFC 5/7] iommu/vt-d: Add support for KVA PASID mode Jacob Pan
2021-09-21 20:29 ` [RFC 6/7] iommu: Add KVA map API Jacob Pan
2021-09-21 20:29 ` 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-21 20:29 ` Jacob Pan
2021-09-22 17:04 ` [RFC 0/7] Support in-kernel DMA with PASID and SVA Jason Gunthorpe via iommu
2021-09-22 17:04 ` Jason Gunthorpe
2021-09-29 19:37 ` Jacob Pan
2021-09-29 19:37 ` Jacob Pan
2021-09-29 19:39 ` Jason Gunthorpe via iommu
2021-09-29 19:39 ` Jason Gunthorpe
2021-09-29 22:57 ` Jacob Pan
2021-09-29 22:57 ` Jacob Pan
2021-09-29 23:43 ` Jason Gunthorpe via iommu
2021-09-29 23:43 ` Jason Gunthorpe
2021-09-30 14:22 ` Campin, Mike
2021-09-30 14:22 ` Campin, Mike
2021-09-30 15:21 ` Jacob Pan
2021-09-30 15:21 ` Jacob Pan
2021-10-01 12:24 ` Barry Song
2021-10-01 12:24 ` Barry Song
2021-10-01 12:36 ` Jason Gunthorpe via iommu
2021-10-01 12:36 ` Jason Gunthorpe
2021-10-01 12:45 ` Barry Song
2021-10-01 12:45 ` Barry Song
2021-10-04 16:40 ` Jacob Pan
2021-10-04 16:40 ` Jacob Pan
2021-10-04 18:21 ` Jason Gunthorpe via iommu
2021-10-04 18:21 ` Jason Gunthorpe
2021-10-07 5:43 ` Barry Song
2021-10-07 5:43 ` Barry Song
2021-10-07 11:32 ` Jason Gunthorpe via iommu
2021-10-07 11:32 ` Jason Gunthorpe
2021-10-07 11:54 ` Barry Song
2021-10-07 11:54 ` Barry Song
2021-10-07 11:59 ` Jason Gunthorpe via iommu
2021-10-07 11:59 ` Jason Gunthorpe
2021-10-07 17:50 ` Jacob Pan
2021-10-07 17:50 ` Jacob Pan
2021-10-07 17:48 ` Jason Gunthorpe via iommu
2021-10-07 17:48 ` Jason Gunthorpe
2021-10-07 18:08 ` Jacob Pan
2021-10-07 18:08 ` Jacob Pan
2021-10-07 19:11 ` Jacob Pan
2021-10-07 19:11 ` Jacob Pan
2021-10-07 19:10 ` Jason Gunthorpe via iommu
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=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 \
/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.