From: Yi Liu <yi.l.liu@intel.com>
To: joro@8bytes.org, jgg@nvidia.com, kevin.tian@intel.com,
baolu.lu@linux.intel.com, will@kernel.org
Cc: alex.williamson@redhat.com, eric.auger@redhat.com,
nicolinc@nvidia.com, kvm@vger.kernel.org,
chao.p.peng@linux.intel.com, yi.l.liu@intel.com,
iommu@lists.linux.dev, zhenzhong.duan@intel.com,
vasant.hegde@amd.com
Subject: [PATCH v3 4/9] iommu/vt-d: Make pasid setup helpers support modifying present pasid entry
Date: Thu, 17 Oct 2024 22:53:57 -0700 [thread overview]
Message-ID: <20241018055402.23277-5-yi.l.liu@intel.com> (raw)
In-Reply-To: <20241018055402.23277-1-yi.l.liu@intel.com>
To handle domain replacement, the set_dev_pasid() op needs to modify a
present pasid entry.
A natural way to implement the set_dev_pasid() op is to reuse the logic
of remove_dev_pasid() in the beginning to remove the old configuration.
Then set up the new pasid entry. Roll back to the old domain if it fails
to set up the new pasid entry. This needs to invoke the set_dev_pasid op
of the old domain. While this breaks the iommu layering a bit.
An alternative is implementing the set_dev_pasid() without rollback to the
old domain. This requires putting all the pasid entry modifications in
the pasid setup helpers. While the set_dev_pasid() op calls the helpers when
all the preparation work such as memory allocation, and sanity check has been
done.
To support modifying present pasid entry, the setup helpers needs to call
intel_pasid_tear_down_entry() to destroy the old configuration, which also
includes the necessary cache flushing and PRQ draining.
Signed-off-by: Yi Liu <yi.l.liu@intel.com>
---
drivers/iommu/intel/pasid.c | 61 +++++++++++++------------------------
1 file changed, 21 insertions(+), 40 deletions(-)
diff --git a/drivers/iommu/intel/pasid.c b/drivers/iommu/intel/pasid.c
index 336f9425214c..ce0a3bf701df 100644
--- a/drivers/iommu/intel/pasid.c
+++ b/drivers/iommu/intel/pasid.c
@@ -321,18 +321,13 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
return -EINVAL;
}
- spin_lock(&iommu->lock);
- pte = intel_pasid_get_entry(dev, pasid);
- if (!pte) {
- spin_unlock(&iommu->lock);
+ /* Destroy the old configuration if it already exists */
+ pte = intel_pasid_tear_down_entry(iommu, dev, pasid,
+ INTEL_PASID_TEARDOWN_DRAIN_PRQ);
+ if (!pte)
return -ENODEV;
- }
-
- if (pasid_pte_is_present(pte)) {
- spin_unlock(&iommu->lock);
- return -EBUSY;
- }
+ spin_lock(&iommu->lock);
pasid_clear_entry(pte);
/* Setup the first level page table pointer: */
@@ -407,21 +402,16 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
return -EINVAL;
}
+ /* Destroy the old configuration if it already exists */
+ pte = intel_pasid_tear_down_entry(iommu, dev, pasid,
+ INTEL_PASID_TEARDOWN_DRAIN_PRQ);
+ if (!pte)
+ return -ENODEV;
+
pgd_val = virt_to_phys(pgd);
did = domain_id_iommu(domain, iommu);
spin_lock(&iommu->lock);
- pte = intel_pasid_get_entry(dev, pasid);
- if (!pte) {
- spin_unlock(&iommu->lock);
- return -ENODEV;
- }
-
- if (pasid_pte_is_present(pte)) {
- spin_unlock(&iommu->lock);
- return -EBUSY;
- }
-
pasid_clear_entry(pte);
pasid_set_domain_id(pte, did);
pasid_set_slptr(pte, pgd_val);
@@ -518,18 +508,13 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
u16 did = FLPT_DEFAULT_DID;
struct pasid_entry *pte;
- spin_lock(&iommu->lock);
- pte = intel_pasid_get_entry(dev, pasid);
- if (!pte) {
- spin_unlock(&iommu->lock);
+ /* Destroy the old configuration if it already exists */
+ pte = intel_pasid_tear_down_entry(iommu, dev, pasid,
+ INTEL_PASID_TEARDOWN_DRAIN_PRQ);
+ if (!pte)
return -ENODEV;
- }
-
- if (pasid_pte_is_present(pte)) {
- spin_unlock(&iommu->lock);
- return -EBUSY;
- }
+ spin_lock(&iommu->lock);
pasid_clear_entry(pte);
pasid_set_domain_id(pte, did);
pasid_set_address_width(pte, iommu->agaw);
@@ -634,17 +619,13 @@ int intel_pasid_setup_nested(struct intel_iommu *iommu, struct device *dev,
return -EINVAL;
}
- spin_lock(&iommu->lock);
- pte = intel_pasid_get_entry(dev, pasid);
- if (!pte) {
- spin_unlock(&iommu->lock);
+ /* Destroy the old configuration if it already exists */
+ pte = intel_pasid_tear_down_entry(iommu, dev, pasid,
+ INTEL_PASID_TEARDOWN_DRAIN_PRQ);
+ if (!pte)
return -ENODEV;
- }
- if (pasid_pte_is_present(pte)) {
- spin_unlock(&iommu->lock);
- return -EBUSY;
- }
+ spin_lock(&iommu->lock);
pasid_clear_entry(pte);
if (s1_cfg->addr_width == ADDR_WIDTH_5LEVEL)
--
2.34.1
next prev parent reply other threads:[~2024-10-18 5:54 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-18 5:53 [PATCH v3 0/9] Make set_dev_pasid op supporting domain replacement Yi Liu
2024-10-18 5:53 ` [PATCH v3 1/9] iommu: Pass old domain to set_dev_pasid op Yi Liu
2024-10-21 5:55 ` Baolu Lu
2024-10-22 5:12 ` Nicolin Chen
2024-10-18 5:53 ` [PATCH v3 2/9] iommu/vt-d: Move intel_drain_pasid_prq() into intel_pasid_tear_down_entry() Yi Liu
2024-10-21 5:58 ` Baolu Lu
2024-10-18 5:53 ` [PATCH v3 3/9] iommu/vt-d: Let intel_pasid_tear_down_entry() return pasid entry Yi Liu
2024-10-21 6:13 ` Baolu Lu
2024-10-21 6:35 ` Yi Liu
2024-10-21 6:59 ` Baolu Lu
2024-10-21 7:24 ` Yi Liu
2024-10-22 9:23 ` Baolu Lu
2024-10-22 9:38 ` Yi Liu
2024-10-22 11:23 ` Baolu Lu
2024-10-22 13:25 ` Yi Liu
2024-10-23 1:10 ` Baolu Lu
2024-10-18 5:53 ` Yi Liu [this message]
2024-10-18 5:53 ` [PATCH v3 5/9] iommu/vt-d: Rename prepare_domain_attach_device() Yi Liu
2024-10-21 6:18 ` Baolu Lu
2024-10-21 6:36 ` Yi Liu
2024-10-18 5:53 ` [PATCH v3 6/9] iommu/vt-d: Make intel_iommu_set_dev_pasid() to handle domain replacement Yi Liu
2024-10-18 5:54 ` [PATCH v3 7/9] iommu/vt-d: Add set_dev_pasid callback for nested domain Yi Liu
2024-10-18 5:54 ` [PATCH v3 8/9] iommu/arm-smmu-v3: Make set_dev_pasid() op support replace Yi Liu
2024-10-22 5:25 ` Nicolin Chen
2024-10-22 6:07 ` Yi Liu
2024-10-18 5:54 ` [PATCH v3 9/9] iommu: Make set_dev_pasid op support domain replacement Yi Liu
2024-10-21 6:27 ` Baolu Lu
2024-10-21 6:40 ` Yi Liu
2024-10-21 10:50 ` 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=20241018055402.23277-5-yi.l.liu@intel.com \
--to=yi.l.liu@intel.com \
--cc=alex.williamson@redhat.com \
--cc=baolu.lu@linux.intel.com \
--cc=chao.p.peng@linux.intel.com \
--cc=eric.auger@redhat.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=joro@8bytes.org \
--cc=kevin.tian@intel.com \
--cc=kvm@vger.kernel.org \
--cc=nicolinc@nvidia.com \
--cc=vasant.hegde@amd.com \
--cc=will@kernel.org \
--cc=zhenzhong.duan@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox