From: Lu Baolu <baolu.lu@linux.intel.com>
To: Joerg Roedel <joro@8bytes.org>
Cc: kevin.tian@intel.com, ashok.raj@intel.com,
linux-kernel@vger.kernel.org, iommu@lists.linux-foundation.org,
David Woodhouse <dwmw2@infradead.org>
Subject: [PATCH 5/5] iommu/vt-d: Consolidate pasid-based device tlb invalidation
Date: Fri, 22 Nov 2019 11:04:49 +0800 [thread overview]
Message-ID: <20191122030449.28892-6-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <20191122030449.28892-1-baolu.lu@linux.intel.com>
Merge pasid-based device tlb invalidation into iommu->flush.p_dev_tlb_inv.
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/iommu/intel-iommu.c | 41 +++++++++++++++++++++++++++++++++++++
drivers/iommu/intel-svm.c | 33 ++++++-----------------------
2 files changed, 47 insertions(+), 27 deletions(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index fec78cc877c1..dd16d466320f 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3074,6 +3074,46 @@ qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr,
qi_submit_sync(&desc, iommu);
}
+/* PASID-based device TLB invalidation */
+static void
+qi_flush_dev_piotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
+ u32 pasid, u16 qdep, u64 address, unsigned long npages)
+{
+ struct qi_desc desc = {.qw2 = 0, .qw3 = 0};
+
+ desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
+ QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE |
+ QI_DEV_IOTLB_PFSID(pfsid);
+
+ /*
+ * npages == -1 means a PASID-selective invalidation, otherwise,
+ * a positive value for Page-selective-within-PASID invalidation.
+ * 0 is not a valid input.
+ */
+ if (WARN_ON(!npages)) {
+ pr_err("Invalid input npages = %ld\n", npages);
+ return;
+ }
+
+ if (npages == -1) {
+ desc.qw1 = QI_DEV_EIOTLB_ADDR(((u64)-1) >> 1) |
+ QI_DEV_EIOTLB_SIZE;
+ } else if (npages > 1) {
+ /* The least significant zero bit indicates the size. So,
+ * for example, an "address" value of 0x12345f000 will
+ * flush from 0x123440000 to 0x12347ffff (256KiB). */
+ unsigned long last = address + ((unsigned long)(npages - 1) << VTD_PAGE_SHIFT);
+ unsigned long mask = __rounddown_pow_of_two(address ^ last);
+
+ desc.qw1 = QI_DEV_EIOTLB_ADDR((address & ~mask) |
+ (mask - 1)) | QI_DEV_EIOTLB_SIZE;
+ } else {
+ desc.qw1 = QI_DEV_EIOTLB_ADDR(address);
+ }
+
+ qi_submit_sync(&desc, iommu);
+}
+
static void intel_iommu_init_qi(struct intel_iommu *iommu)
{
/*
@@ -3108,6 +3148,7 @@ static void intel_iommu_init_qi(struct intel_iommu *iommu)
iommu->flush.pc_inv = qi_flush_pasid;
iommu->flush.dev_tlb_inv = qi_flush_dev_iotlb;
iommu->flush.p_iotlb_inv = qi_flush_piotlb;
+ iommu->flush.p_dev_tlb_inv = qi_flush_dev_piotlb;
pr_info("%s: Using Queued invalidation\n", iommu->name);
}
}
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 02c6b14f0568..b6b22989eb46 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -114,39 +114,18 @@ void intel_svm_check(struct intel_iommu *iommu)
iommu->flags |= VTD_FLAG_SVM_CAPABLE;
}
-static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev,
- unsigned long address, unsigned long pages, int ih)
+static void
+intel_flush_svm_range_dev(struct intel_svm *svm, struct intel_svm_dev *sdev,
+ unsigned long address, unsigned long pages, int ih)
{
- struct qi_desc desc;
struct intel_iommu *iommu = svm->iommu;
iommu->flush.p_iotlb_inv(iommu, sdev->did,
svm->pasid, address, pages, ih);
- if (sdev->dev_iotlb) {
- desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) |
- QI_DEV_EIOTLB_SID(sdev->sid) |
- QI_DEV_EIOTLB_QDEP(sdev->qdep) |
- QI_DEIOTLB_TYPE;
- if (pages == -1) {
- desc.qw1 = QI_DEV_EIOTLB_ADDR(-1ULL >> 1) |
- QI_DEV_EIOTLB_SIZE;
- } else if (pages > 1) {
- /* The least significant zero bit indicates the size. So,
- * for example, an "address" value of 0x12345f000 will
- * flush from 0x123440000 to 0x12347ffff (256KiB). */
- unsigned long last = address + ((unsigned long)(pages - 1) << VTD_PAGE_SHIFT);
- unsigned long mask = __rounddown_pow_of_two(address ^ last);
-
- desc.qw1 = QI_DEV_EIOTLB_ADDR((address & ~mask) |
- (mask - 1)) | QI_DEV_EIOTLB_SIZE;
- } else {
- desc.qw1 = QI_DEV_EIOTLB_ADDR(address);
- }
- desc.qw2 = 0;
- desc.qw3 = 0;
- qi_submit_sync(&desc, svm->iommu);
- }
+ if (sdev->dev_iotlb)
+ iommu->flush.p_dev_tlb_inv(iommu, sdev->sid, 0, svm->pasid,
+ sdev->qdep, address, pages);
}
static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address,
--
2.17.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: Lu Baolu <baolu.lu@linux.intel.com>
To: Joerg Roedel <joro@8bytes.org>
Cc: David Woodhouse <dwmw2@infradead.org>,
ashok.raj@intel.com, jacob.jun.pan@linux.intel.com,
kevin.tian@intel.com, Eric Auger <eric.auger@redhat.com>,
iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org,
Lu Baolu <baolu.lu@linux.intel.com>
Subject: [PATCH 5/5] iommu/vt-d: Consolidate pasid-based device tlb invalidation
Date: Fri, 22 Nov 2019 11:04:49 +0800 [thread overview]
Message-ID: <20191122030449.28892-6-baolu.lu@linux.intel.com> (raw)
In-Reply-To: <20191122030449.28892-1-baolu.lu@linux.intel.com>
Merge pasid-based device tlb invalidation into iommu->flush.p_dev_tlb_inv.
Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
drivers/iommu/intel-iommu.c | 41 +++++++++++++++++++++++++++++++++++++
drivers/iommu/intel-svm.c | 33 ++++++-----------------------
2 files changed, 47 insertions(+), 27 deletions(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index fec78cc877c1..dd16d466320f 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3074,6 +3074,46 @@ qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr,
qi_submit_sync(&desc, iommu);
}
+/* PASID-based device TLB invalidation */
+static void
+qi_flush_dev_piotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
+ u32 pasid, u16 qdep, u64 address, unsigned long npages)
+{
+ struct qi_desc desc = {.qw2 = 0, .qw3 = 0};
+
+ desc.qw0 = QI_DEV_EIOTLB_PASID(pasid) | QI_DEV_EIOTLB_SID(sid) |
+ QI_DEV_EIOTLB_QDEP(qdep) | QI_DEIOTLB_TYPE |
+ QI_DEV_IOTLB_PFSID(pfsid);
+
+ /*
+ * npages == -1 means a PASID-selective invalidation, otherwise,
+ * a positive value for Page-selective-within-PASID invalidation.
+ * 0 is not a valid input.
+ */
+ if (WARN_ON(!npages)) {
+ pr_err("Invalid input npages = %ld\n", npages);
+ return;
+ }
+
+ if (npages == -1) {
+ desc.qw1 = QI_DEV_EIOTLB_ADDR(((u64)-1) >> 1) |
+ QI_DEV_EIOTLB_SIZE;
+ } else if (npages > 1) {
+ /* The least significant zero bit indicates the size. So,
+ * for example, an "address" value of 0x12345f000 will
+ * flush from 0x123440000 to 0x12347ffff (256KiB). */
+ unsigned long last = address + ((unsigned long)(npages - 1) << VTD_PAGE_SHIFT);
+ unsigned long mask = __rounddown_pow_of_two(address ^ last);
+
+ desc.qw1 = QI_DEV_EIOTLB_ADDR((address & ~mask) |
+ (mask - 1)) | QI_DEV_EIOTLB_SIZE;
+ } else {
+ desc.qw1 = QI_DEV_EIOTLB_ADDR(address);
+ }
+
+ qi_submit_sync(&desc, iommu);
+}
+
static void intel_iommu_init_qi(struct intel_iommu *iommu)
{
/*
@@ -3108,6 +3148,7 @@ static void intel_iommu_init_qi(struct intel_iommu *iommu)
iommu->flush.pc_inv = qi_flush_pasid;
iommu->flush.dev_tlb_inv = qi_flush_dev_iotlb;
iommu->flush.p_iotlb_inv = qi_flush_piotlb;
+ iommu->flush.p_dev_tlb_inv = qi_flush_dev_piotlb;
pr_info("%s: Using Queued invalidation\n", iommu->name);
}
}
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
index 02c6b14f0568..b6b22989eb46 100644
--- a/drivers/iommu/intel-svm.c
+++ b/drivers/iommu/intel-svm.c
@@ -114,39 +114,18 @@ void intel_svm_check(struct intel_iommu *iommu)
iommu->flags |= VTD_FLAG_SVM_CAPABLE;
}
-static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev,
- unsigned long address, unsigned long pages, int ih)
+static void
+intel_flush_svm_range_dev(struct intel_svm *svm, struct intel_svm_dev *sdev,
+ unsigned long address, unsigned long pages, int ih)
{
- struct qi_desc desc;
struct intel_iommu *iommu = svm->iommu;
iommu->flush.p_iotlb_inv(iommu, sdev->did,
svm->pasid, address, pages, ih);
- if (sdev->dev_iotlb) {
- desc.qw0 = QI_DEV_EIOTLB_PASID(svm->pasid) |
- QI_DEV_EIOTLB_SID(sdev->sid) |
- QI_DEV_EIOTLB_QDEP(sdev->qdep) |
- QI_DEIOTLB_TYPE;
- if (pages == -1) {
- desc.qw1 = QI_DEV_EIOTLB_ADDR(-1ULL >> 1) |
- QI_DEV_EIOTLB_SIZE;
- } else if (pages > 1) {
- /* The least significant zero bit indicates the size. So,
- * for example, an "address" value of 0x12345f000 will
- * flush from 0x123440000 to 0x12347ffff (256KiB). */
- unsigned long last = address + ((unsigned long)(pages - 1) << VTD_PAGE_SHIFT);
- unsigned long mask = __rounddown_pow_of_two(address ^ last);
-
- desc.qw1 = QI_DEV_EIOTLB_ADDR((address & ~mask) |
- (mask - 1)) | QI_DEV_EIOTLB_SIZE;
- } else {
- desc.qw1 = QI_DEV_EIOTLB_ADDR(address);
- }
- desc.qw2 = 0;
- desc.qw3 = 0;
- qi_submit_sync(&desc, svm->iommu);
- }
+ if (sdev->dev_iotlb)
+ iommu->flush.p_dev_tlb_inv(iommu, sdev->sid, 0, svm->pasid,
+ sdev->qdep, address, pages);
}
static void intel_flush_svm_range(struct intel_svm *svm, unsigned long address,
--
2.17.1
next prev parent reply other threads:[~2019-11-22 3:08 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-22 3:04 [PATCH 0/5] iommu/vt-d: Consolidate various cache flush ops Lu Baolu
2019-11-22 3:04 ` Lu Baolu
2019-11-22 3:04 ` [PATCH 1/5] iommu/vt-d: Extend iommu_flush for scalable mode Lu Baolu
2019-11-22 3:04 ` Lu Baolu
2019-11-22 3:04 ` [PATCH 2/5] iommu/vt-d: Consolidate pasid cache invalidation Lu Baolu
2019-11-22 3:04 ` Lu Baolu
2019-11-22 3:04 ` [PATCH 3/5] iommu/vt-d: Consolidate device tlb invalidation Lu Baolu
2019-11-22 3:04 ` Lu Baolu
2019-11-22 3:04 ` [PATCH 4/5] iommu/vt-d: Consolidate pasid-based " Lu Baolu
2019-11-22 3:04 ` Lu Baolu
2019-12-03 17:43 ` Jacob Pan
2019-12-03 17:43 ` Jacob Pan
2019-11-22 3:04 ` Lu Baolu [this message]
2019-11-22 3:04 ` [PATCH 5/5] iommu/vt-d: Consolidate pasid-based device " Lu Baolu
2019-12-02 20:02 ` [PATCH 0/5] iommu/vt-d: Consolidate various cache flush ops Jacob Pan
2019-12-02 20:02 ` Jacob Pan
2019-12-03 2:44 ` Lu Baolu
2019-12-03 2:44 ` Lu Baolu
2019-12-03 16:50 ` Jacob Pan
2019-12-03 16:50 ` Jacob Pan
2019-12-04 0:32 ` Lu Baolu
2019-12-04 0:32 ` Lu Baolu
2019-12-04 17:41 ` Jacob Pan
2019-12-04 17:41 ` Jacob Pan
2019-12-03 8:49 ` David Woodhouse
2019-12-03 8:49 ` David Woodhouse
2019-12-04 0:27 ` Lu Baolu
2019-12-04 0:27 ` Lu Baolu
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=20191122030449.28892-6-baolu.lu@linux.intel.com \
--to=baolu.lu@linux.intel.com \
--cc=ashok.raj@intel.com \
--cc=dwmw2@infradead.org \
--cc=iommu@lists.linux-foundation.org \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=linux-kernel@vger.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.