From: Lu Baolu <baolu.lu@linux.intel.com>
To: Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>,
Robin Murphy <robin.murphy@arm.com>,
Jason Gunthorpe <jgg@ziepe.ca>, Kevin Tian <kevin.tian@intel.com>
Cc: iommu@lists.linux.dev, linux-kernel@vger.kernel.org,
Lu Baolu <baolu.lu@linux.intel.com>
Subject: [PATCH v2 2/2] iommu/vt-d: Refactor PCI PRI enabling/disabling callbacks
Date: Thu, 27 Jun 2024 10:31:21 +0800 [thread overview]
Message-ID: <20240627023121.50166-3-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <20240627023121.50166-1-baolu.lu@linux.intel.com>
Commit 0095bf83554f8 ("iommu: Improve iopf_queue_remove_device()")
specified the flow for disabling the PRI on a device. Refactor the
PRI callbacks in the intel iommu driver to better manage PRI
enabling and disabling and align it with the device queue interfaces
in the iommu core.
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/iommu/intel/iommu.h | 9 ++++++
drivers/iommu/intel/iommu.c | 57 +++++++++++++++++++++++++++++++++----
drivers/iommu/intel/pasid.c | 2 --
3 files changed, 61 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/intel/iommu.h b/drivers/iommu/intel/iommu.h
index 63eb3306c025..b67c14da1240 100644
--- a/drivers/iommu/intel/iommu.h
+++ b/drivers/iommu/intel/iommu.h
@@ -1045,6 +1045,15 @@ static inline void context_set_sm_pre(struct context_entry *context)
context->lo |= BIT_ULL(4);
}
+/*
+ * Clear the PRE(Page Request Enable) field of a scalable mode context
+ * entry.
+ */
+static inline void context_clear_sm_pre(struct context_entry *context)
+{
+ context->lo &= ~BIT_ULL(4);
+}
+
/* Returns a number of VTD pages, but aligned to MM page size */
static inline unsigned long aligned_nrpages(unsigned long host_addr, size_t size)
{
diff --git a/drivers/iommu/intel/iommu.c b/drivers/iommu/intel/iommu.c
index 89f489372138..d51f840715e5 100644
--- a/drivers/iommu/intel/iommu.c
+++ b/drivers/iommu/intel/iommu.c
@@ -4241,6 +4241,37 @@ static int intel_iommu_enable_sva(struct device *dev)
return 0;
}
+static int context_flip_pri(struct device_domain_info *info, bool enable)
+{
+ struct intel_iommu *iommu = info->iommu;
+ u8 bus = info->bus, devfn = info->devfn;
+ struct context_entry *context;
+
+ spin_lock(&iommu->lock);
+ if (context_copied(iommu, bus, devfn)) {
+ spin_unlock(&iommu->lock);
+ return -EINVAL;
+ }
+
+ context = iommu_context_addr(iommu, bus, devfn, false);
+ if (!context || !context_present(context)) {
+ spin_unlock(&iommu->lock);
+ return -ENODEV;
+ }
+
+ if (enable)
+ context_set_sm_pre(context);
+ else
+ context_clear_sm_pre(context);
+
+ if (!ecap_coherent(iommu->ecap))
+ clflush_cache_range(context, sizeof(*context));
+ intel_context_flush_present(info, context, true);
+ spin_unlock(&iommu->lock);
+
+ return 0;
+}
+
static int intel_iommu_enable_iopf(struct device *dev)
{
struct pci_dev *pdev = dev_is_pci(dev) ? to_pci_dev(dev) : NULL;
@@ -4270,15 +4301,23 @@ static int intel_iommu_enable_iopf(struct device *dev)
if (ret)
return ret;
+ ret = context_flip_pri(info, true);
+ if (ret)
+ goto err_remove_device;
+
ret = pci_enable_pri(pdev, PRQ_DEPTH);
- if (ret) {
- iopf_queue_remove_device(iommu->iopf_queue, dev);
- return ret;
- }
+ if (ret)
+ goto err_clear_pri;
info->pri_enabled = 1;
return 0;
+err_clear_pri:
+ context_flip_pri(info, false);
+err_remove_device:
+ iopf_queue_remove_device(iommu->iopf_queue, dev);
+
+ return ret;
}
static int intel_iommu_disable_iopf(struct device *dev)
@@ -4289,6 +4328,15 @@ static int intel_iommu_disable_iopf(struct device *dev)
if (!info->pri_enabled)
return -EINVAL;
+ /* Disable new PRI reception: */
+ context_flip_pri(info, false);
+
+ /*
+ * Remove device from fault queue and acknowledge all outstanding
+ * PRQs to the device:
+ */
+ iopf_queue_remove_device(iommu->iopf_queue, dev);
+
/*
* PCIe spec states that by clearing PRI enable bit, the Page
* Request Interface will not issue new page requests, but has
@@ -4299,7 +4347,6 @@ static int intel_iommu_disable_iopf(struct device *dev)
*/
pci_disable_pri(to_pci_dev(dev));
info->pri_enabled = 0;
- iopf_queue_remove_device(iommu->iopf_queue, dev);
return 0;
}
diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index aef4b4afb873..b1ec9660bc11 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -749,8 +749,6 @@ static int context_entry_set_pasid_table(struct context_entry *context,
if (info->ats_supported)
context_set_sm_dte(context);
- if (info->pri_supported)
- context_set_sm_pre(context);
if (info->pasid_supported)
context_set_pasid(context);
--
2.34.1
prev parent reply other threads:[~2024-06-27 2:34 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-27 2:31 [PATCH v2 0/2] iommu/vt-d: Refactor PRI enable/disable steps Lu Baolu
2024-06-27 2:31 ` [PATCH v2 1/2] iommu/vt-d: Add helper to flush caches for context change Lu Baolu
2024-06-27 6:08 ` Tian, Kevin
2024-06-27 8:21 ` Baolu Lu
2024-06-28 7:43 ` Tian, Kevin
2024-06-28 11:24 ` Baolu Lu
2024-07-01 6:39 ` Tian, Kevin
2024-07-02 0:23 ` Jacob Pan
2024-07-02 2:54 ` Baolu Lu
2024-06-27 2:31 ` Lu Baolu [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=20240627023121.50166-3-baolu.lu@linux.intel.com \
--to=baolu.lu@linux.intel.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@ziepe.ca \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=robin.murphy@arm.com \
--cc=will@kernel.org \
/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.