All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Gunthorpe <jgg@ziepe.ca>
To: Vasant Hegde <vasant.hegde@amd.com>
Cc: iommu@lists.linux.dev, joro@8bytes.org,
	suravee.suthikulpanit@amd.com, wei.huang2@amd.com,
	jsnitsel@redhat.com
Subject: Re: [PATCH v2 04/11] iommu/amd: Initial SVA support for AMD IOMMU
Date: Mon, 18 Sep 2023 09:53:28 -0300	[thread overview]
Message-ID: <20230918125328.GD13795@ziepe.ca> (raw)
In-Reply-To: <2d863928-6ffa-4bf7-d4d6-689d779ad701@amd.com>

On Fri, Sep 15, 2023 at 02:20:32PM +0530, Vasant Hegde wrote:

> >> +		dev_data = pasid_data->dev_data;
> >> +
> >> +		if ((start ^ (end - 1)) < PAGE_SIZE) {
> >> +			amd_iommu_flush_page(dev_data->domain,
> >> +					     pasid_data->pasid, start);
> >> +		} else {
> >> +			amd_iommu_flush_tlb(dev_data->domain,
> >> +					    pasid_data->pasid);
> >> +		}
> > 
> > It is baffling why dev_data->domain would be used here, and it isn't
> > locked properly so this is a problem.
> > 
> > Looking into __flush_pasid it doesn't really make sense. The PASID
> > domain definately can't assume that the RID domain has the the same
> > set of iommus. Most likely the SVA domain has a wider set of iommus,
> > at least I didn't notice any logic preventing this in set_dev_pasid.
> 
> Right. SVA protection domain will just add dev/PASID combination without
> worrying device protection domain/iommu.
>
> In invalidation path, I walk the `pasid_list` from SVA protection domain, get
> dev_data/PASID info and use those for invaliation. Since invalidation needs
> device protection domain I have to refer dev_data->domain.

See my other email, this area looks quite troubled.

> > Also, didn't you say you wanted to de-duplicate the IOTLB and ATC
> > invalidations like ARM is doing?
> 
> I don't have the understanding of ARM. But our invalidation
> interfaces needs improvement. Like current code does unncessary
> complete_wait() calls. Those will be fixed along with other
> invalidation cleanup.

Future fix is fine
 
> > 
> >> +static const struct mmu_notifier_ops sva_mn = {
> >> +	.invalidate_range = sva_mn_invalidate_range,
> >> +	.release = sva_mn_release,
> >> +};
> > 
> > Why an empty release function?
> > 
> > That can't be right, when release is called the driver has to stop
> > using iommu_virt_to_phys(domain->mm->pgd)) because it will be freed
> > memory. It should replace it with a global empty pgd and flush caches
> > before release returns.
> 
> In remove_dev_pasid() its already removed PASID from GCR3 table, flushing IOMMU.
> Also if its last device unbind, then it also does mmu_notifier_unregister().
>
> I thought remove_dev_pasid() always gets called before mmu notifier releases.
> Is there any chance of mmu notifier relase() getting called before
> remove_dev_pasid().

Yes it can be called in that order. An empty release function here is buggy.

> >> +	pasid_data->pasid = pasid;
> >> +	pasid_data->dev_data = dev_data;
> >> +
> >> +	/* Setup GCR3 table */
> >> +	ret = amd_iommu_set_gcr3(dev_data, pasid,
> >> +				 iommu_virt_to_phys(domain->mm->pgd));
> >> +	if (ret)
> >> +		goto out_free_pasid_data;
> >> +
> >> +	if (list_empty(&sva_pdom->pasid_list)) {
> >> +		sva_pdom->mn.ops = &sva_mn;
> >> +
> >> +		ret = mmu_notifier_register(&sva_pdom->mn, domain->mm);
> >> +		if (ret)
> >> +			goto out_clear_gcr3;
> >> +	}
> > 
> > Looks to me like mmu_notifier_register() should be done before
> > amd_iommu_set_gcr3() so we don't have a risk of stale iotlb data.
> 
> Actually we need to update GCR3 table with PASID before registering mmu
> notifier. So that hardware is ready to handle the invalidations. Otherwise we
> will have a redudant invalidations.

If you register the mmu and the paslid_list is empty (or locked) then the
invalidation handler does nothing. So this cannot be a concern.

Putting it out of order like this creates an edge case where the HW
could concivable cache a translation and miss a notification. It is
definately wrong.

> >> +void amd_iommu_remove_dev_pasid(struct device *dev, ioasid_t pasid)
> >> +{
> >> +	struct pdom_pasid_data *pasid_data;
> >> +	struct protection_domain *sva_pdom;
> >> +	struct iommu_domain *domain;
> >> +	struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
> >> +	unsigned long flags;
> >> +
> >> +	if (pasid == 0 || pasid >= dev->iommu->max_pasids)
> >> +		return;
> >> +
> >> +	/* Get protection domain */
> >> +	domain = iommu_get_domain_for_dev_pasid(dev, pasid, IOMMU_DOMAIN_SVA);
> >> +	if (!domain)
> >> +		return;
> >> +	sva_pdom = to_pdomain(domain);
> >> +
> >> +	/* Ensure that all queued faults have been processed */
> >> +	iopf_queue_flush_dev(dev);
> >> +
> >> +	spin_lock_irqsave(&sva_pdom->lock, flags);
> >> +
> >> +	pasid_data = get_pdom_pasid_data(sva_pdom, dev, pasid);
> >> +	if (!pasid_data) {
> >> +		spin_unlock_irqrestore(&sva_pdom->lock, flags);
> >> +		return;
> >> +	}
> >> +
> >> +	list_del(&pasid_data->pdom_link);
> >> +	kfree(pasid_data);
> >> +
> >> +	/* make it visible */
> >> +	smp_wmb();
> >> +
> >> +	/* Update GCR3 table and flush IOTLB */
> >> +	amd_iommu_clear_gcr3(dev_data, pasid);
> >> +
> >> +	spin_unlock_irqrestore(&sva_pdom->lock, flags);
> >> +
> >> +	if (list_empty(&sva_pdom->pasid_list))
> >> +		mmu_notifier_unregister(&sva_pdom->mn, domain->mm);
> > 
> > Can't drop the spinlock before doing this, it is racy.
> 
> Yeah. Its racy. But we cannot call mmu_notifier_unregister() with spinlock held.
> May be I will introduce some lock to handle notifier.

If you reoganize things so the notifier is always registered then you
don't need to have the spinlock protecting it anymore. this requires
putting the unregister in the domain deallocation routine.

Jason

  reply	other threads:[~2023-09-18 12:53 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-09-11 12:10 [PATCH v2 00/11] iommu/amd: SVA Support (Part 4) - SVA and IOPF Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 01/11] iommu/amd: Rename amd_iommu_v2_supported() as amd_iommu_sva_supported() Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 02/11] iommu/amd: Do not override PASID entry in GCR3 table Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 03/11] iommu/amd: Add support for enabling/disabling IOMMU features Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 04/11] iommu/amd: Initial SVA support for AMD IOMMU Vasant Hegde
2023-09-12 16:47   ` Jason Gunthorpe
2023-09-15  8:50     ` Vasant Hegde
2023-09-18 12:53       ` Jason Gunthorpe [this message]
2023-10-13 15:52         ` Vasant Hegde
2023-10-13 15:58           ` Jason Gunthorpe
2023-09-11 12:10 ` [PATCH v2 05/11] iommu/amd: Add support to enable/disable PASID feature Vasant Hegde
2023-09-12 16:57   ` Jason Gunthorpe
2023-09-15  8:57     ` Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 06/11] iommu/amd: Move PPR-related functions into ppr.c Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 07/11] iommu/amd: Define per-IOMMU iopf_queue Vasant Hegde
2023-09-12 16:59   ` Jason Gunthorpe
2023-09-15 13:48     ` Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 08/11] iommu/amd: Add support for page response Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 09/11] iommu/amd: Add support for add/remove device for IOPF Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 10/11] iommu/amd: Add IO page fault notifier handler Vasant Hegde
2023-09-12 18:46   ` Jason Gunthorpe
2023-09-13  4:19     ` Baolu Lu
2023-09-15  8:15     ` Vasant Hegde
2023-09-11 12:10 ` [PATCH v2 11/11] iommu/amd: Introduce logic to enable/disable IOPF Vasant Hegde
2023-09-12 16:32   ` Jason Gunthorpe
2023-09-15  8:26     ` Vasant Hegde
2023-09-18 12:45       ` Jason Gunthorpe
2023-10-10 14:53         ` Vasant Hegde
2023-10-10 15:04           ` Jason Gunthorpe
2023-09-12 18:48 ` [PATCH v2 00/11] iommu/amd: SVA Support (Part 4) - SVA and IOPF 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=20230918125328.GD13795@ziepe.ca \
    --to=jgg@ziepe.ca \
    --cc=iommu@lists.linux.dev \
    --cc=joro@8bytes.org \
    --cc=jsnitsel@redhat.com \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=vasant.hegde@amd.com \
    --cc=wei.huang2@amd.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 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.