From: Jason Gunthorpe <jgg@nvidia.com>
To: Michael Shavit <mshavit@google.com>
Cc: iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, baolu.lu@linux.intel.com,
will@kernel.org, jean-philippe@linaro.org, robin.murphy@arm.com,
nicolinc@nvidia.com
Subject: Re: [PATCH v5 4/6] iommu/arm-smmu-v3: Implement set_dev_pasid
Date: Thu, 3 Aug 2023 14:52:26 -0300 [thread overview]
Message-ID: <ZMvpWoslIZNiLNQp@nvidia.com> (raw)
In-Reply-To: <20230803181225.v5.4.I4ba46c0f7d599f43094d6ba1113c0b4fe49bd908@changeid>
On Thu, Aug 03, 2023 at 06:12:24PM +0800, Michael Shavit wrote:
> @@ -2448,21 +2476,17 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
> return -EBUSY;
> }
>
> - arm_smmu_detach_dev(master);
> -
> - mutex_lock(&smmu_domain->init_mutex);
> -
> - if (!smmu_domain->smmu) {
> - smmu_domain->smmu = smmu;
> - ret = arm_smmu_domain_finalise(domain, master);
> - if (ret)
> - smmu_domain->smmu = NULL;
> - } else if (smmu_domain->smmu != smmu)
> - ret = -EINVAL;
> + /*
> + * Attaching a bypass or stage 2 domain would break any domains attached
> + * with pasid. Attaching an S1 domain should be feasible but requires
> + * more complicated logic to handle.
> + */
> + if (arm_smmu_master_has_pasid_domains(master)) {
> + dev_err(dev, "cannot attach - domain attached with pasid\n");
> + return -EBUSY;
> + }
Basically don't you just call set_dev_pased(pasid = 0) and it will do
that logic?
> +static int arm_smmu_set_dev_pasid(struct iommu_domain *domain,
> + struct device *dev, ioasid_t pasid)
> +{
> + int ret = 0;
> + unsigned long flags;
> + struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
> + struct arm_smmu_device *smmu;
> + struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
> + struct arm_smmu_attached_domain *attached_domain;
> + struct arm_smmu_master *master;
> +
> + if (!fwspec)
> + return -ENOENT;
fwspec drivers always have fwspecs, they don't need to check this.
> +
> + master = dev_iommu_priv_get(dev);
> + smmu = master->smmu;
> +
> + ret = arm_smmu_prepare_domain_for_smmu(smmu, smmu_domain, master);
> + if (ret)
> + return ret;
> +
> + if (pasid == 0) {
> + dev_err(dev, "pasid 0 is reserved for the device's primary domain\n");
> + return -ENODEV;
> + }
> +
> + if (smmu_domain->stage != ARM_SMMU_DOMAIN_S1) {
> + dev_err(dev, "set_dev_pasid only supports stage 1 domains\n");
don't print messages, iommufd can trigger these paths from userspace.
> @@ -2738,6 +2828,15 @@ static void arm_smmu_release_device(struct device *dev)
>
> if (WARN_ON(arm_smmu_master_sva_enabled(master)))
> iopf_queue_remove_device(master->smmu->evtq.iopf, dev);
> + if (WARN_ON(master->nr_attached_pasid_domains != 0)) {
> + /*
> + * TODO: Do we need to handle this case?
> + * This requires a mechanism to obtain all the pasid domains
> + * that this master is attached to so that we can clean up the
> + * domain's attached_domain list.
> + */
> + }
Unnecessary, the core code should handle this, add a patch that does this:
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 5b5cf74edc7e53..57cac1ffba1cfe 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -438,9 +438,16 @@ static void iommu_deinit_device(struct device *dev)
{
struct iommu_group *group = dev->iommu_group;
const struct iommu_ops *ops = dev_iommu_ops(dev);
+ struct iommu_domain *{pasid_domain;
+ unsigned long pasid;
lockdep_assert_held(&group->mutex);
+ xa_for_each(&group->pasid_array, pasid, pasid_domain) {
+ __iommu_remove_group_pasid(pasid);
+ xa_erase(&group->pasid_array, pasid);
+ }
+
iommu_device_unlink(dev->iommu->iommu_dev, dev);
/*
> @@ -2874,12 +2973,36 @@ static int arm_smmu_def_domain_type(struct device *dev)
> static void arm_smmu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
> {
> struct iommu_domain *domain;
> + struct arm_smmu_master *master = dev_iommu_priv_get(dev);
> + struct arm_smmu_domain *smmu_domain;
> + struct arm_smmu_attached_domain *attached_domain;
> + unsigned long flags;
>
> - domain = iommu_get_domain_for_dev_pasid(dev, pasid, IOMMU_DOMAIN_SVA);
> + if (!master || pasid == 0)
> + return;
> +
> + domain = iommu_get_domain_for_dev_pasid(dev, pasid, 0);
> if (WARN_ON(IS_ERR(domain)) || !domain)
> return;
I feel like we have made a mistake here to not pass in the current
domain from the core code, it already knows what the domain was..
> + if (domain->type == IOMMU_DOMAIN_SVA)
> + return arm_smmu_sva_remove_dev_pasid(domain, dev, pasid);
Yuk.
Jason
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2023-08-03 17:53 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-03 10:12 [PATCH v5 0/6] Add PASID support to SMMUv3 unmanaged domains Michael Shavit
2023-08-03 10:12 ` [PATCH v5 1/6] iommu/arm-smmu-v3: Simplify arm_smmu_enable_ats Michael Shavit
2023-08-03 10:12 ` [PATCH v5 2/6] iommu/arm-smmu-v3: Keep track of attached ssids Michael Shavit
2023-08-03 15:42 ` Jason Gunthorpe
2023-08-03 16:32 ` Michael Shavit
2023-08-03 17:44 ` Jason Gunthorpe
2023-08-03 10:12 ` [PATCH v5 3/6] iommu/arm-smmu-v3: Add helper for atc invalidation Michael Shavit
2023-08-03 10:12 ` [PATCH v5 4/6] iommu/arm-smmu-v3: Implement set_dev_pasid Michael Shavit
2023-08-03 17:52 ` Jason Gunthorpe [this message]
2023-08-03 10:12 ` [PATCH v5 5/6] iommu/arm-smmu-v3: Free pasid domains on iommu release Michael Shavit
2023-08-03 10:17 ` Michael Shavit
2023-08-03 15:20 ` Jason Gunthorpe
2023-08-03 10:12 ` [PATCH v5 6/6] iommu/arm-smmu-v3: Cleanup arm_smmu_domain_finalise Michael Shavit
2023-08-03 10:15 ` Michael Shavit
2023-08-03 15:19 ` Jason Gunthorpe
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=ZMvpWoslIZNiLNQp@nvidia.com \
--to=jgg@nvidia.com \
--cc=baolu.lu@linux.intel.com \
--cc=iommu@lists.linux.dev \
--cc=jean-philippe@linaro.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mshavit@google.com \
--cc=nicolinc@nvidia.com \
--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 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 NNTP newsgroup(s).