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>
Subject: [PATCH v3 06/12] iommu/amd: Add support to enable/disable PASID feature
Date: Mon, 16 Oct 2023 10:43:45 +0000 [thread overview]
Message-ID: <20231016104351.5749-7-vasant.hegde@amd.com> (raw)
In-Reply-To: <20231016104351.5749-1-vasant.hegde@amd.com>
From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
It seems iommu_dev_enable_feature(SVA) will be deprecated soon. Hence in
this path we just return success.
Instead we add necessary check during pasid bind to device. In this path
it checks whether device GCR3 table is setup or not. If not it will
setup GCR3 table.
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Co-developed-by: Wei Huang <wei.huang2@amd.com>
Signed-off-by: Wei Huang <wei.huang2@amd.com>
Co-developed-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
---
drivers/iommu/amd/amd_iommu.h | 2 +
drivers/iommu/amd/iommu.c | 44 +++++++++++++++++++++
drivers/iommu/amd/pasid.c | 72 +++++++++++++++++++++++++++++++++++
3 files changed, 118 insertions(+)
diff --git a/drivers/iommu/amd/amd_iommu.h b/drivers/iommu/amd/amd_iommu.h
index efcbec84d096..216792006891 100644
--- a/drivers/iommu/amd/amd_iommu.h
+++ b/drivers/iommu/amd/amd_iommu.h
@@ -46,6 +46,8 @@ void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid);
/* SVA/PASID */
bool amd_iommu_pasid_supported(void);
+int amd_iommu_gcr3_init(struct iommu_dev_data *dev_data, ioasid_t pasids);
+void amd_iommu_gcr3_uninit(struct iommu_dev_data *dev_data);
struct amd_iommu *get_amd_iommu(unsigned int idx);
u8 amd_iommu_pc_get_max_banks(unsigned int idx);
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index 0974c88e39ce..a34998bbb779 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -87,6 +87,11 @@ static void clear_dte_entry(struct amd_iommu *iommu, u16 devid);
*
****************************************************************************/
+static inline bool pdom_is_pt_mode(struct protection_domain *pdom)
+{
+ return (pdom->domain.type == IOMMU_DOMAIN_IDENTITY);
+}
+
/*
* For invalidation request without PASID, get the pasid based on
* domain page table mode.
@@ -1977,6 +1982,39 @@ int amd_iommu_clear_gcr3(struct iommu_dev_data *dev_data, ioasid_t pasid)
return ret;
}
+int amd_iommu_gcr3_init(struct iommu_dev_data *dev_data, ioasid_t pasids)
+{
+ struct protection_domain *pdom = dev_data->domain;
+ int ret = 0;
+
+ lockdep_assert_held(&dev_data->lock);
+
+ /*
+ * We cannot support PASID w/ existing v1 page table in the same domain
+ * since it will be nested. However, existing domain w/ v2 page table
+ * can be used for PASID.
+ */
+ if (pdom->pd_mode == PD_MODE_V1)
+ return -EOPNOTSUPP;
+
+ /* Allocate GCR3 table */
+ if (pdom_is_pt_mode(dev_data->domain) &&
+ dev_data->gcr3_info.gcr3_tbl == NULL) {
+ ret = setup_gcr3_table(dev_data, pasids);
+ }
+
+ return ret;
+}
+
+void amd_iommu_gcr3_uninit(struct iommu_dev_data *dev_data)
+{
+ lockdep_assert_held(&dev_data->lock);
+
+ /* Free GCR3 table */
+ if (pdom_is_pt_mode(dev_data->domain))
+ free_gcr3_table(dev_data);
+}
+
static void set_dte_entry(struct amd_iommu *iommu,
struct iommu_dev_data *dev_data)
{
@@ -2778,6 +2816,9 @@ static int amd_iommu_dev_enable_feature(struct device *dev,
int ret;
switch (feat) {
+ case IOMMU_DEV_FEAT_SVA:
+ ret = 0;
+ break;
default:
ret = -EINVAL;
break;
@@ -2791,6 +2832,9 @@ static int amd_iommu_dev_disable_feature(struct device *dev,
int ret;
switch (feat) {
+ case IOMMU_DEV_FEAT_SVA:
+ ret = 0;
+ break;
default:
ret = -EINVAL;
break;
diff --git a/drivers/iommu/amd/pasid.c b/drivers/iommu/amd/pasid.c
index c251b274eda0..f064d0ed1138 100644
--- a/drivers/iommu/amd/pasid.c
+++ b/drivers/iommu/amd/pasid.c
@@ -11,6 +11,66 @@
#include "amd_iommu.h"
+
+static inline bool is_gcr3_table_empty(struct iommu_dev_data *dev_data)
+{
+ return (dev_data->gcr3_info.pasid_cnt == 0);
+}
+
+static inline bool is_pasid_enabled(struct iommu_dev_data *dev_data)
+{
+ if (dev_data->gcr3_info.gcr3_tbl != NULL &&
+ !is_gcr3_table_empty(dev_data)) {
+ return true;
+ }
+
+ return false;
+}
+
+static int iommu_pasid_enable(struct iommu_dev_data *dev_data)
+{
+ struct device *dev = dev_data->dev;
+ int ret = 0;
+
+ spin_lock(&dev_data->lock);
+
+ if (is_pasid_enabled(dev_data))
+ goto out;
+
+ if (!amd_iommu_pasid_supported()) {
+ ret = -ENODEV;
+ goto out;
+ }
+
+ /* attach_device path enables device PASID feature */
+ if (!dev_data->pasid_enabled) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = amd_iommu_gcr3_init(dev_data, dev->iommu->max_pasids);
+
+out:
+ spin_unlock(&dev_data->lock);
+ return ret;
+}
+
+static void iommu_pasid_disable(struct iommu_dev_data *dev_data)
+{
+ spin_lock(&dev_data->lock);
+
+ if (!is_gcr3_table_empty(dev_data))
+ goto out;
+
+ if (dev_data->gcr3_info.gcr3_tbl == NULL)
+ goto out;
+
+ amd_iommu_gcr3_uninit(dev_data);
+
+out:
+ spin_unlock(&dev_data->lock);
+}
+
static void dev_pasid_remove(struct pdom_pasid_data *pasid_data)
{
/* make it visible */
@@ -103,6 +163,13 @@ static int iommu_sva_set_dev_pasid(struct iommu_domain *domain,
/* Use SVA protection domain lock */
spin_lock_irqsave(&sva_pdom->lock, flags);
+ /* Make sure PASID is enabled */
+ if (!is_pasid_enabled(dev_data)) {
+ ret = iommu_pasid_enable(dev_data);
+ if (ret)
+ goto out;
+ }
+
/* Add PASID to protection domain pasid list */
pasid_data = kzalloc(sizeof(*pasid_data), GFP_KERNEL);
if (pasid_data == NULL) {
@@ -150,6 +217,7 @@ void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
struct pdom_pasid_data *pasid_data;
struct protection_domain *sva_pdom;
struct iommu_domain *domain;
+ struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
unsigned long flags;
if (pasid == 0 || pasid >= dev->iommu->max_pasids)
@@ -174,6 +242,10 @@ void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
dev_pasid_remove(pasid_data);
+ /* Remove GCR3 table */
+ if (is_gcr3_table_empty(dev_data))
+ iommu_pasid_disable(dev_data);
+
spin_unlock_irqrestore(&sva_pdom->lock, flags);
}
--
2.31.1
next prev parent reply other threads:[~2023-10-16 10:47 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-16 10:43 [PATCH v3 00/12] iommu/amd: SVA Support (Part 4) - SVA and IOPF Vasant Hegde
2023-10-16 10:43 ` [PATCH v3 01/12] iommu/amd: Rename amd_iommu_v2_supported() as amd_iommu_pasid_supported() Vasant Hegde
2023-11-06 17:50 ` Jason Gunthorpe
2023-10-16 10:43 ` [PATCH v3 02/12] iommu/amd: Do not override PASID entry in GCR3 table Vasant Hegde
2023-11-06 17:51 ` Jason Gunthorpe
2023-11-07 6:26 ` Vasant Hegde
2023-11-07 13:34 ` Jason Gunthorpe
2023-10-16 10:43 ` [PATCH v3 03/12] iommu/amd: Introduce per device DTE update function Vasant Hegde
2023-11-06 17:54 ` Jason Gunthorpe
2023-11-07 6:47 ` Vasant Hegde
2023-11-07 13:36 ` Jason Gunthorpe
2023-10-16 10:43 ` [PATCH v3 04/12] iommu/amd: Add support for enabling/disabling IOMMU features Vasant Hegde
2023-11-06 17:55 ` Jason Gunthorpe
2023-10-16 10:43 ` [PATCH v3 05/12] iommu/amd: Initial SVA support for AMD IOMMU Vasant Hegde
2023-11-06 23:18 ` Jason Gunthorpe
2023-12-20 11:00 ` Vasant Hegde
2023-10-16 10:43 ` Vasant Hegde [this message]
2023-10-16 10:43 ` [PATCH v3 07/12] iommu/amd: Move PPR-related functions into ppr.c Vasant Hegde
2023-10-16 10:43 ` [PATCH v3 08/12] iommu/amd: Define per-IOMMU iopf_queue Vasant Hegde
2023-10-16 10:43 ` [PATCH v3 09/12] iommu/amd: Add support for page response Vasant Hegde
2023-10-16 10:43 ` [PATCH v3 10/12] iommu/amd: Add support for add/remove device for IOPF Vasant Hegde
2023-10-16 10:43 ` [PATCH v3 11/12] iommu/amd: Add IO page fault notifier handler Vasant Hegde
2023-11-06 23:20 ` Jason Gunthorpe
2023-11-07 6:42 ` Vasant Hegde
2023-11-07 13:35 ` Jason Gunthorpe
2023-10-16 10:43 ` [PATCH v3 12/12] iommu/amd: Introduce logic to enable/disable IOPF Vasant Hegde
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=20231016104351.5749-7-vasant.hegde@amd.com \
--to=vasant.hegde@amd.com \
--cc=iommu@lists.linux.dev \
--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