From: Vasant Hegde <vasant.hegde@amd.com>
To: <iommu@lists.linux.dev>, <joro@8bytes.org>
Cc: <suravee.suthikulpanit@amd.com>, <wei.huang2@amd.com>,
<jsnitsel@redhat.com>, <jgg@ziepe.ca>,
Vasant Hegde <vasant.hegde@amd.com>,
Jason Gunthorpe <jgg@nvidia.com>
Subject: [PATCH v7 15/15] iommu/amd: Add SVA domain support
Date: Mon, 11 Mar 2024 09:08:43 +0000 [thread overview]
Message-ID: <20240311090843.133455-16-vasant.hegde@amd.com> (raw)
In-Reply-To: <20240311090843.133455-1-vasant.hegde@amd.com>
- Allocate SVA domain and setup mmu notifier. In free path unregister
mmu notifier and free protection domain.
- Add mmu notifier callback function. It will retrieve SVA protection
domain and invalidates IO/TLB.
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
---
drivers/iommu/amd/amd_iommu.h | 5 ++
drivers/iommu/amd/amd_iommu_types.h | 1 +
drivers/iommu/amd/iommu.c | 10 ++--
drivers/iommu/amd/pasid.c | 80 +++++++++++++++++++++++++++++
4 files changed, 93 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
index 23e7449f16b8..8ca434b8a885 100644
--- a/drivers/iommu/amd/amd_iommu.h
+++ b/drivers/iommu/amd/amd_iommu.h
@@ -45,6 +45,11 @@ extern enum io_pgtable_fmt amd_iommu_pgtable;
extern int amd_iommu_gpt_level;
/* Protection domain ops */
+struct protection_domain *protection_domain_alloc(unsigned int type);
+void protection_domain_free(struct protection_domain *domain);
+struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
+ struct mm_struct *mm);
+void amd_iommu_domain_free(struct iommu_domain *dom);
int iommu_sva_set_dev_pasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid);
void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid);
diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h
index ed9971cd3f0e..2b76b5dedc1d 100644
--- a/drivers/iommu/amd/amd_iommu_types.h
+++ b/drivers/iommu/amd/amd_iommu_types.h
@@ -586,6 +586,7 @@ struct protection_domain {
unsigned dev_cnt; /* devices assigned to this domain */
unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
+ struct mmu_notifier mn; /* mmu notifier for the SVA domain */
struct list_head dev_data_list; /* List of pdom_dev_data */
};
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 82fdfd68cf6d..9df2695a0f46 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2277,7 +2277,7 @@ static void cleanup_domain(struct protection_domain *domain)
WARN_ON(domain->dev_cnt != 0);
}
-static void protection_domain_free(struct protection_domain *domain)
+void protection_domain_free(struct protection_domain *domain)
{
if (!domain)
return;
@@ -2320,7 +2320,7 @@ static int protection_domain_init_v2(struct protection_domain *pdom)
return 0;
}
-static struct protection_domain *protection_domain_alloc(unsigned int type)
+struct protection_domain *protection_domain_alloc(unsigned int type)
{
struct io_pgtable_ops *pgtbl_ops;
struct protection_domain *domain;
@@ -2343,6 +2343,7 @@ static struct protection_domain *protection_domain_alloc(unsigned int type)
switch (type) {
/* No need to allocate io pgtable ops in passthrough mode */
case IOMMU_DOMAIN_IDENTITY:
+ case IOMMU_DOMAIN_SVA:
return domain;
case IOMMU_DOMAIN_DMA:
pgtable = amd_iommu_pgtable;
@@ -2462,7 +2463,7 @@ amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
return do_iommu_domain_alloc(type, dev, flags);
}
-static void amd_iommu_domain_free(struct iommu_domain *dom)
+void amd_iommu_domain_free(struct iommu_domain *dom)
{
struct protection_domain *domain;
unsigned long flags;
@@ -2830,6 +2831,7 @@ static int amd_iommu_dev_enable_feature(struct device *dev,
switch (feat) {
case IOMMU_DEV_FEAT_IOPF:
+ case IOMMU_DEV_FEAT_SVA:
break;
default:
ret = -EINVAL;
@@ -2845,6 +2847,7 @@ static int amd_iommu_dev_disable_feature(struct device *dev,
switch (feat) {
case IOMMU_DEV_FEAT_IOPF:
+ case IOMMU_DEV_FEAT_SVA:
break;
default:
ret = -EINVAL;
@@ -2857,6 +2860,7 @@ const struct iommu_ops amd_iommu_ops = {
.capable = amd_iommu_capable,
.domain_alloc = amd_iommu_domain_alloc,
.domain_alloc_user = amd_iommu_domain_alloc_user,
+ .domain_alloc_sva = amd_iommu_domain_alloc_sva,
.probe_device = amd_iommu_probe_device,
.release_device = amd_iommu_release_device,
.probe_finalize = amd_iommu_probe_finalize,
diff --git a/drivers/iommu/amd/pasid.c b/drivers/iommu/amd/pasid.c
index c96384ae3442..04beb2217d93 100644
--- a/drivers/iommu/amd/pasid.c
+++ b/drivers/iommu/amd/pasid.c
@@ -56,6 +56,49 @@ static void remove_pdom_dev_pasid(struct protection_domain *pdom,
}
}
+static void sva_arch_invalidate_secondary_tlbs(struct mmu_notifier *mn,
+ struct mm_struct *mm,
+ unsigned long start, unsigned long end)
+{
+ struct pdom_dev_data *pdom_dev_data;
+ struct protection_domain *sva_pdom;
+ unsigned long flags;
+
+ sva_pdom = container_of(mn, struct protection_domain, mn);
+
+ spin_lock_irqsave(&sva_pdom->lock, flags);
+
+ for_each_pdom_dev_data(pdom_dev_data, sva_pdom) {
+ amd_iommu_dev_flush_pasid_pages(pdom_dev_data->dev_data,
+ pdom_dev_data->pasid,
+ start, end - start);
+ }
+
+ spin_unlock_irqrestore(&sva_pdom->lock, flags);
+}
+
+static void sva_mn_release(struct mmu_notifier *mn, struct mm_struct *mm)
+{
+ struct pdom_dev_data *pdom_dev_data, *next;
+ struct protection_domain *sva_pdom;
+ unsigned long flags;
+
+ sva_pdom = container_of(mn, struct protection_domain, mn);
+
+ spin_lock_irqsave(&sva_pdom->lock, flags);
+
+ /* Assume dev_data_list contains same PASID with different devices */
+ for_each_pdom_dev_data_safe(pdom_dev_data, next, sva_pdom)
+ remove_dev_pasid(pdom_dev_data);
+
+ spin_unlock_irqrestore(&sva_pdom->lock, flags);
+}
+
+static const struct mmu_notifier_ops sva_mn = {
+ .arch_invalidate_secondary_tlbs = sva_arch_invalidate_secondary_tlbs,
+ .release = sva_mn_release,
+};
+
int iommu_sva_set_dev_pasid(struct iommu_domain *domain,
struct device *dev, ioasid_t pasid)
{
@@ -120,3 +163,40 @@ void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
spin_unlock_irqrestore(&sva_pdom->lock, flags);
}
+
+static void iommu_sva_domain_free(struct iommu_domain *domain)
+{
+ struct protection_domain *sva_pdom = to_pdomain(domain);
+
+ if (sva_pdom->mn.ops)
+ mmu_notifier_unregister(&sva_pdom->mn, domain->mm);
+
+ amd_iommu_domain_free(domain);
+}
+
+static const struct iommu_domain_ops amd_sva_domain_ops = {
+ .set_dev_pasid = iommu_sva_set_dev_pasid,
+ .free = iommu_sva_domain_free
+};
+
+struct iommu_domain *amd_iommu_domain_alloc_sva(struct device *dev,
+ struct mm_struct *mm)
+{
+ struct protection_domain *pdom;
+ int ret;
+
+ pdom = protection_domain_alloc(IOMMU_DOMAIN_SVA);
+ if (!pdom)
+ return ERR_PTR(-ENOMEM);
+
+ pdom->domain.ops = &amd_sva_domain_ops;
+ pdom->mn.ops = &sva_mn;
+
+ ret = mmu_notifier_register(&pdom->mn, mm);
+ if (ret) {
+ protection_domain_free(pdom);
+ return ERR_PTR(ret);
+ }
+
+ return &pdom->domain;
+}
--
2.31.1
prev parent reply other threads:[~2024-03-11 9:13 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-11 9:08 [PATCH v7 00/15] iommu/amd: SVA Support (Part 4) - SVA and IOPF Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 01/15] iommu/amd: Rename amd_iommu_v2_supported() as amd_iommu_pasid_supported() Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 02/15] iommu/amd: Introduce per device DTE update function Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 03/15] iommu/amd: Add support for enabling/disabling IOMMU features Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 04/15] iommu/amd: Move PPR-related functions into ppr.c Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 05/15] iommu/amd: Fix PPR interrupt processing logic Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 06/15] iommu/amd: Introduce iommu_dev_data.max_pasids Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 07/15] iommu/amd: Setup GCR3 table in advance if domain is SVA capable Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 08/15] iommu/amd: Enable PCI features based on attached domain capability Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 09/15] iommu/amd: Define per-IOMMU iopf_queue Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 10/15] iommu/amd: Add support for page response Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 11/15] iommu/amd: Add IO page fault notifier handler Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 12/15] iommu/amd: Add support for enable/disable IOPF Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 13/15] iommu/amd: Initial SVA support for AMD IOMMU Vasant Hegde
2024-03-11 9:08 ` [PATCH v7 14/15] iommu: Add ops->domain_alloc_sva() Vasant Hegde
2024-03-11 9:08 ` Vasant Hegde [this message]
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=20240311090843.133455-16-vasant.hegde@amd.com \
--to=vasant.hegde@amd.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=jgg@ziepe.ca \
--cc=joro@8bytes.org \
--cc=jsnitsel@redhat.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=wei.huang2@amd.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 read-only IMAP folder(s) and NNTP newsgroup(s).