From: Jason Gunthorpe <jgg@nvidia.com>
To: Will Deacon <will@kernel.org>
Cc: Michael Shavit <mshavit@google.com>,
iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, robin.murphy@arm.com,
nicolinc@nvidia.com, jean-philippe@linaro.org
Subject: Re: [PATCH v5 5/9] iommu/arm-smmu-v3: Refactor write_ctx_desc
Date: Thu, 10 Aug 2023 12:39:36 -0300 [thread overview]
Message-ID: <ZNUEuIlPmrckwMyn@nvidia.com> (raw)
In-Reply-To: <20230810144051.GD5795@willie-the-truck>
On Thu, Aug 10, 2023 at 03:40:52PM +0100, Will Deacon wrote:
> On Thu, Aug 10, 2023 at 05:15:50PM +0800, Michael Shavit wrote:
> > On Wed, Aug 9, 2023 at 9:50 PM Will Deacon <will@kernel.org> wrote:
> > >
> > > > - ret = arm_smmu_write_ctx_desc(smmu_domain, mm->pasid, cd);
> > > > - if (ret)
> > > > + ret = arm_smmu_write_ctx_desc_devices(smmu_domain, mm->pasid, cd);
> > > > + if (ret) {
> > > > + arm_smmu_write_ctx_desc_devices(smmu_domain, mm->pasid, NULL);
> > >
> > > Why is it safe to drop the lock between these two calls?
> >
> > Hmmm this is a tricky question.
> > Tracing through the SVA flow, it seems like there's a scenario where
> > multiple masters (with the same upstream SMMU device) can be attached
> > to the same primary/non-sva domain, in which case calling
> > iommu_attach_device_pasid on one device will write the CD entry for
> > both masters. This is still the case even with this patch series, and
> > changing this behavior will be the subject of a separate follow-up.
> > This is weird, especially since the second master need not even have
> > the sva_enabled bit set. This also means that the list of attached
> > masters can indeed change between these two calls if that second
> > master (not the one used on the iommu_attach_device_pasid call leading
> > to this code) is detached/attached at the same time. It's hard for me
> > to reason about whether this is safe or not, since this is already
> > weird behavior...
>
> I really think the writing of the context descriptors should look atomic;
> dropping the lock half way through a failed update and then coming back
> to NULL them out definitely isn't correct. So I think you've probably pushed
> the locking too far down the stack.
Urk, the issue is that progressive refactorings have left this kind of
wrong.
Basically we always have a singular master we are supposed to be
installing the SVA domain into a PASID for, we just need to load the
CD table entry into that master's existing CD table.
Actually, I don't think this even works as nothing on the PASID path
adds to the list that arm_smmu_write_ctx_desc_devices() iterates over ??
Then the remaining two calls:
arm_smmu_share_asid(struct mm_struct *mm, u16 asid)
arm_smmu_write_ctx_desc_devices(smmu_domain, 0, cd);
This is OK only if the sketchy assumption that the CD
we extracted for a conflicting ASID is not asigned to a PASID.
static void arm_smmu_mm_release(struct mmu_notifier *mn, struct mm_struct *mm)
arm_smmu_write_ctx_desc_devices(smmu_domain, mm->pasid, &quiet_cd);
This doesn't work because we didn't add the master to the list
during __arm_smmu_sva_bind and this path is expressly working
on the PASID binds, not the RID binds.
This is all far too complicated. We really need to get this series:
https://lore.kernel.org/linux-iommu/20230808074944.7825-1-tina.zhang@intel.com/
And rip out all this crazy code in the drivers trying to de-duplicate
the SVA domains. The core code will do it, the driver can assume it
has exactly one SVA domain per mm and do sane and simple things. :(
Maybe for now we just accept that quiet_cd doesn't work, it is a minor
issue and your next series fixes it, right?
Anyhow, something like this will fix what Will pointed to, probably as
an additional prep patch:
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
index e3992a0c163779..8e751ba91e810a 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-sva.c
@@ -297,12 +297,6 @@ arm_smmu_mmu_notifier_get(struct arm_smmu_domain *smmu_domain,
goto err_free_cd;
}
- ret = arm_smmu_write_ctx_desc_devices(smmu_domain, mm->pasid, cd);
- if (ret) {
- arm_smmu_write_ctx_desc_devices(smmu_domain, mm->pasid, NULL);
- goto err_put_notifier;
- }
-
list_add(&smmu_mn->list, &smmu_domain->mmu_notifiers);
return smmu_mn;
@@ -325,8 +319,6 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
list_del(&smmu_mn->list);
- arm_smmu_write_ctx_desc_devices(smmu_domain, mm->pasid, NULL);
-
/*
* If we went through clear(), we've already invalidated, and no
* new TLB entry can have been formed.
@@ -342,7 +334,7 @@ static void arm_smmu_mmu_notifier_put(struct arm_smmu_mmu_notifier *smmu_mn)
}
static struct iommu_sva *
-__arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
+__arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm, ioasid_t ssid)
{
int ret;
struct arm_smmu_bond *bond;
@@ -375,9 +367,15 @@ __arm_smmu_sva_bind(struct device *dev, struct mm_struct *mm)
goto err_free_bond;
}
+ ret = arm_smmu_write_ctx_desc(master, ssid, bond->smmu_mn->cd);
+ if (ret)
+ goto err_put_notifier;
+
list_add(&bond->list, &master->bonds);
return &bond->sva;
+err_put_notifier:
+ arm_smmu_mmu_notifier_put(bond->smmu_mn);
err_free_bond:
kfree(bond);
return ERR_PTR(ret);
@@ -548,6 +546,7 @@ void arm_smmu_sva_remove_dev_pasid(struct iommu_domain *domain,
if (!WARN_ON(!bond) && refcount_dec_and_test(&bond->refs)) {
list_del(&bond->list);
+ arm_smmu_write_ctx_desc(master, id, NULL);
arm_smmu_mmu_notifier_put(bond->smmu_mn);
kfree(bond);
}
@@ -562,7 +561,7 @@ static int arm_smmu_sva_set_dev_pasid(struct iommu_domain *domain,
struct mm_struct *mm = domain->mm;
mutex_lock(&sva_lock);
- handle = __arm_smmu_sva_bind(dev, mm);
+ handle = __arm_smmu_sva_bind(dev, mm, id);
if (IS_ERR(handle))
ret = PTR_ERR(handle);
mutex_unlock(&sva_lock);
next prev parent reply other threads:[~2023-08-10 15:39 UTC|newest]
Thread overview: 45+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-08 17:11 [PATCH v5 0/9] Refactor the SMMU's CD table ownership Michael Shavit
2023-08-08 17:11 ` [PATCH v5 1/9] iommu/arm-smmu-v3: Move ctx_desc out of s1_cfg Michael Shavit
2023-08-08 17:11 ` [PATCH v5 2/9] iommu/arm-smmu-v3: Replace s1_cfg with cdtab_cfg Michael Shavit
2023-08-09 13:49 ` Will Deacon
2023-08-09 13:59 ` Jason Gunthorpe
2023-08-09 14:55 ` Will Deacon
2023-08-09 15:08 ` Jason Gunthorpe
2023-08-09 16:22 ` Will Deacon
2023-08-09 16:26 ` Jason Gunthorpe
2023-08-09 16:27 ` Will Deacon
2023-08-10 9:33 ` Michael Shavit
2023-08-10 9:43 ` Will Deacon
2023-08-10 12:04 ` Jason Gunthorpe
2023-08-10 17:15 ` Michael Shavit
2023-08-10 17:32 ` Jason Gunthorpe
2023-08-08 17:11 ` [PATCH v5 3/9] iommu/arm-smmu-v3: Encapsulate ctx_desc_cfg init in alloc_cd_tables Michael Shavit
2023-08-08 17:12 ` [PATCH v5 4/9] iommu/arm-smmu-v3: move stall_enabled to the cd table Michael Shavit
2023-08-08 17:12 ` [PATCH v5 5/9] iommu/arm-smmu-v3: Refactor write_ctx_desc Michael Shavit
2023-08-09 13:50 ` Will Deacon
2023-08-10 9:15 ` Michael Shavit
2023-08-10 14:40 ` Will Deacon
2023-08-10 15:39 ` Jason Gunthorpe [this message]
2023-08-15 5:20 ` Michael Shavit
2023-08-15 11:22 ` Jason Gunthorpe
2023-08-15 12:03 ` Michael Shavit
2023-08-15 12:30 ` Jason Gunthorpe
2023-08-15 12:36 ` Michael Shavit
2023-08-15 12:56 ` Jason Gunthorpe
2023-08-15 5:04 ` Michael Shavit
2023-08-15 10:19 ` Will Deacon
2023-08-15 11:40 ` Michael Shavit
2023-08-08 17:12 ` [PATCH v5 6/9] iommu/arm-smmu-v3: Move CD table to arm_smmu_master Michael Shavit
2023-08-09 13:50 ` Will Deacon
2023-08-10 9:23 ` Michael Shavit
2023-08-10 14:38 ` Will Deacon
2023-08-10 9:45 ` Michael Shavit
2023-08-10 14:34 ` Will Deacon
2023-08-10 14:56 ` Jason Gunthorpe
2023-08-15 12:10 ` Michael Shavit
2023-08-08 17:12 ` [PATCH v5 7/9] iommu/arm-smmu-v3: Cleanup arm_smmu_domain_finalise Michael Shavit
2023-08-08 17:12 ` [PATCH v5 8/9] iommu/arm-smmu-v3: Skip cd sync if CD table isn't active Michael Shavit
2023-08-09 13:50 ` Will Deacon
2023-08-10 8:34 ` Michael Shavit
2023-08-10 16:27 ` Will Deacon
2023-08-08 17:12 ` [PATCH v5 9/9] iommu/arm-smmu-v3: Rename cdcfg to cd_table Michael Shavit
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=ZNUEuIlPmrckwMyn@nvidia.com \
--to=jgg@nvidia.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