Linux IOMMU Development
 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 v3 06/13] iommu/amd: Introduce per-device domain ID to workaround potential TLB aliasing issue
Date: Sun, 5 Nov 2023 14:16:04 -0400	[thread overview]
Message-ID: <20231105181604.GH4634@ziepe.ca> (raw)
In-Reply-To: <20231013151652.6008-7-vasant.hegde@amd.com>

On Fri, Oct 13, 2023 at 03:16:45PM +0000, Vasant Hegde wrote:
> With v1 page table (stage-2), the AMD IOMMU spec states that the hardware
> must use the domain ID to tag its internal translation caches. I/O devices
> with different v1 page tables must be given different domain IDs. I/O
> devices that share the same v1 page table __may__ be given the same domain
> ID. This domain ID management policy is currently implemented by the AMD
> IOMMU driver. In this case, only the domain ID is needed when issuing the
> INVALIDATE_IOMMU_PAGES command to invalidate the IOMMU translation cache
> (TLB).
> 
> With v2 page table (stage-1), the hardware uses domain ID and PASID as
> parameters to tag and issue the INVALIDATE_IOMMU_PAGES command. Since the
> GCR3 table is setup per-device, and there is no guarantee for PASID to be
> unique across multiple devices, the same PASID for different devices could
> have different v2 page tables. In such case, if multiple devices share the
> same domain ID, IOMMU translation cache for these devices would be polluted
> due to TLB aliasing.
> 
> Hence, avoid the TLB aliasing issue by allocating unique domain ID for each
> device even when multiple devices are sharing the same v1 page table.
> Please note that this workaround would result in multiple
> INVALIDATE_IOMMU_PAGES commands (one per domain id) when unmapping a
> translation on the shared v1 page table.

It is worth pointing out that this is a shortcut to implementing a
more complete solution where the domain ID can be shared right up until a
PASID is used.


> @@ -1418,6 +1426,19 @@ static int device_flush_iotlb_range(struct iommu_dev_data *dev_data,
>  	return iommu_queue_command(iommu, &cmd);
>  }
>  
> +/* Flush IOMMU TLB for the given device */
> +static int device_flush_tlb_range(struct iommu_dev_data *dev_data,
> +				  ioasid_t pasid, u64 address, size_t size)
> +{
> +	struct iommu_cmd cmd;
> +	struct amd_iommu *iommu = get_amd_iommu_from_dev(dev_data->dev);
> +	bool gn = is_pasid_valid(pasid);

Again it seems obfuscating to ecode the table type in the
pasid.

> @@ -1523,11 +1544,25 @@ static int domain_flush_tlb_range(struct protection_domain *pdom,
>  static void __domain_flush_pages(struct protection_domain *pdom,
>  				 ioasid_t pasid, u64 address, size_t size)
>  {
> -	int ret;
> +	struct iommu_dev_data *dev_data;
> +	int ret = 0;
>  
> -	ret = domain_flush_tlb_range(pdom, pasid, address, size);
> +	if (domain_id_is_per_dev(pdom)) {
> +		list_for_each_entry(dev_data, &pdom->dev_list, list) {
> +			ret |= device_flush_tlb_range(dev_data,
> +						      pasid, address, size);
>  
> -	ret |= domain_flush_dev_iotlb_range(pdom, pasid, address, size);
> +			if (!dev_data->ats_enabled)
> +				continue;
> +
> +			ret |= device_flush_iotlb_range(dev_data,
> +							pasid, address, size);
> +		}
> +	} else {
> +		ret = domain_flush_tlb_range(pdom, pasid, address, size);
> +
> +		ret |= domain_flush_dev_iotlb_range(pdom, pasid, address, size);
> +	}
>  
>  	WARN_ON(ret);
>  }

I feel like this has become pretty complicated.

I think this driver really suffers from not having the right
data structures to handle everything cleanly.

In smmuv3 I added a 'master_domain' structure that linked the PCI
device to the iommu_domain. ie when attach is done you'd create a new
master_domain that essentially stores the parameters required to do
invalidation.

For what is going on here I would say to do that an then put the
"domain id" inside the "master_domain". Decide when the domain is
attached if the domain id should by taken from the iommu_domain
(device does not support PASID) or from the device (device does
support PASID)

Then you don't need all this logic to try to figure out what the cache
tag is later on. And you can get build up to removing the
protection_domain->iommu madness and more properly integrate the pci
alias stuff too.

Doing this datastructure change was a big step that made all the rest
of the PASID/SVA/etc stuff I did in smmuv3 flow nicely and logically

Jason

  reply	other threads:[~2023-11-05 18:16 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-13 15:16 [PATCH v3 00/13] iommu/amd: SVA Support (part 3) - refactor support for GCR3 table Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 01/13] iommu/amd: Pass struct iommu_dev_data to set_dte_entry() Vasant Hegde
2023-11-05 18:00   ` Jason Gunthorpe
2023-10-13 15:16 ` [PATCH v3 02/13] iommu/amd: Introduce get_amd_iommu_from_dev() Vasant Hegde
2023-11-05 18:05   ` Jason Gunthorpe
2023-11-06 11:54     ` Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 03/13] iommu/amd: Introduce struct protection_domain.pd_mode Vasant Hegde
2023-11-05 18:07   ` Jason Gunthorpe
2023-10-13 15:16 ` [PATCH v3 04/13] iommu/amd: Introduce per-device GCR3 table Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 05/13] iommu/amd: Use protection_domain.flags to check page table mode Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 06/13] iommu/amd: Introduce per-device domain ID to workaround potential TLB aliasing issue Vasant Hegde
2023-11-05 18:16   ` Jason Gunthorpe [this message]
2023-11-06 12:39     ` Vasant Hegde
2023-11-06 13:36       ` Jason Gunthorpe
2023-11-07  5:30         ` Vasant Hegde
2023-11-07 13:21           ` Jason Gunthorpe
2023-12-12  5:53             ` Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 07/13] iommu/amd: Add support for device based flush TLB Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 08/13] iommu/amd: Rearrange GCR3 table setup code Vasant Hegde
2023-11-05 18:16   ` Jason Gunthorpe
2023-10-13 15:16 ` [PATCH v3 09/13] iommu/amd: Refactor helper function for setting / clearing GCR3 Vasant Hegde
2023-11-06 16:51   ` Jason Gunthorpe
2023-11-07  6:16     ` Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 10/13] iommu/amd: Refactor helper function for attaching / detaching device Vasant Hegde
2023-11-06 17:29   ` Jason Gunthorpe
2023-11-07  5:55     ` Vasant Hegde
2023-11-07 13:28       ` Jason Gunthorpe
2023-11-23 17:39         ` Vasant Hegde
2023-11-30 17:55           ` Jason Gunthorpe
2023-12-12  5:41             ` Vasant Hegde
2023-12-12 14:59               ` Jason Gunthorpe
2023-12-18  5:17                 ` Vasant Hegde
2023-10-13 15:16 ` [PATCH v3 11/13] iommu/amd: Refactor protection_domain helper functions Vasant Hegde
2023-11-06 17:30   ` Jason Gunthorpe
2023-10-13 15:16 ` [PATCH v3 12/13] iommu/amd: Refactor GCR3 table " Vasant Hegde
2023-11-06 17:40   ` Jason Gunthorpe
2023-11-07  6:13     ` Vasant Hegde
2023-11-07 13:31       ` Jason Gunthorpe
2023-11-23 17:23         ` Vasant Hegde
2023-11-23 17:24           ` Jason Gunthorpe
2023-10-13 15:16 ` [PATCH v3 13/13] iommu/amd: Remove unused GCR3 table parameters from struct protection_domain Vasant Hegde
2023-11-06 17:33   ` 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=20231105181604.GH4634@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox