All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] iommu_ops->domain_alloc_paging() enhancement to support AMD IOMMU driver
@ 2024-06-28  6:43 Vasant Hegde
  2024-06-28 12:23 ` Baolu Lu
  2024-06-28 13:03 ` Jason Gunthorpe
  0 siblings, 2 replies; 30+ messages in thread
From: Vasant Hegde @ 2024-06-28  6:43 UTC (permalink / raw)
  To: Joerg Roedel, Jason Gunthorpe, iommu@lists.linux.dev
  Cc: Suravee Suthikulpanit, Will Deacon, Robin Murphy, Baolu Lu

Hi All,

We are working on adding domain_alloc_paging() support in AMD driver and came
across below issue.

BACKGROUND:
============
- AMD IOMMU HW has two different page tables : V1 (host page table) and V2
(guest page table). Only V2 page table supports PASID and PRI features.

- With V2 page table we have an aliasing issue. Hence we added
per-device-domain-id when domain is configured with v2 page table. See upstream
commit 87a6f1f22c97 ("iommu/amd: Introduce per-device domain ID to fix potential
TLB aliasing issue")



PROBLEM :
=========
With iommu_ops->domain_alloc_paging(dev) API AMD driver will chose best page
table based on device capabilities (V2 for PASID capable device and V1 page
table for rest of the devices).

But we would like to continue enforcing V1 page table for UNMANAGED domain. As
in terms of IOMMU caching, it performs better than V2 page table.

Also while adding SVA in AMD driver Jason mentioned that we should support PASID
with UNMANAGED domain. As I understand currently we don't have this feature in
upstream but we would like to support it in future. Keeping this use case also
in mind, we came up with below two options :

  1 - Pass domain type : domain_alloc_paging(dev, type)
   When we add PASID with UNMANAGED domain we need a way to differentiate the
domain 'type' (See below attach sample code)

  2 - Introduce new flag for domain_alloc_paging()
    Something like :
    #define DOMAIN_FLAG_UNMANAGED	0x01
    #define DOMAIN_FLAG_UNMANAGED_SVA	0x02

    domain_alloc_paging(dev, flag)
    For now we will have 'DOMAIN_PAGING_UNMANAGED'.

Please let us know which one is preferred -OR- is there any other better way to
handle this.

-Vasant


---------------
commit bdf17f429dfb76b5a9a5714045ce3f38a4ee98b3
Author: Vasant Hegde <vasant.hegde@amd.com>
Date:   Fri Jun 28 11:56:18 2024 +0530

    [RFC] iommu: domain_alloc_paging enhancement

    Prototype to show how domain_alloc_paging() looks like. This doesn't even
    compile as I have not modified other driver which has domain_alloc_paging()
    implementation.

    Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>

diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c
index c2703599bb16..e401c2d9ab8e 100644
--- a/drivers/iommu/amd/iommu.c
+++ b/drivers/iommu/amd/iommu.c
@@ -2429,6 +2429,22 @@ static struct iommu_domain
*amd_iommu_domain_alloc(unsigned int type)
 	return domain;
 }

+static struct iommu_domain *amd_iommu_domain_alloc_paging(struct device *dev,
u32 type)
+{
+	struct iommu_dev_data *dev_data = dev_iommu_priv_get(dev);
+	int pgtable = amd_iommu_pgtable;
+
+	/* TODO: Add SNP and other checks */
+
+	/* Force V1 page table for UNMANAGED domain */
+	if (type == IOMMU_DOMAIN_UNMANAGED)
+		pgtable = AMD_IOMMU_V1;
+	else if (dev_is_pci(dev) && pdev_pasid_supported(dev_data))
+		pgtable = AMD_IOMMU_V2;
+
+	return do_iommu_domain_alloc(IOMMU_DOMAIN_DMA, dev, 0, pgtable);
+}
+
 static struct iommu_domain *
 amd_iommu_domain_alloc_user(struct device *dev, u32 flags,
 			    struct iommu_domain *parent,
@@ -2860,6 +2876,7 @@ static int amd_iommu_dev_disable_feature(struct device *dev,
 const struct iommu_ops amd_iommu_ops = {
 	.capable = amd_iommu_capable,
 	.domain_alloc = amd_iommu_domain_alloc,
+	.domain_alloc_paging = amd_iommu_domain_alloc_paging,
 	.domain_alloc_user = amd_iommu_domain_alloc_user,
 	.domain_alloc_sva = amd_iommu_domain_alloc_sva,
 	.probe_device = amd_iommu_probe_device,
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 9df7cc75c1bc..7fb95f90158e 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1952,7 +1952,7 @@ static struct iommu_domain *__iommu_domain_alloc(const
struct iommu_ops *ops,
 	else if (alloc_type == IOMMU_DOMAIN_BLOCKED && ops->blocked_domain)
 		return ops->blocked_domain;
 	else if (type & __IOMMU_DOMAIN_PAGING && ops->domain_alloc_paging)
-		domain = ops->domain_alloc_paging(dev);
+		domain = ops->domain_alloc_paging(dev, type);
 	else if (ops->domain_alloc)
 		domain = ops->domain_alloc(alloc_type);
 	else
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 17b3f36ad843..d408eb70e086 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -192,6 +192,9 @@ struct iommu_domain_geometry {
 #define IOMMU_DOMAIN_BLOCKED	(0U)
 #define IOMMU_DOMAIN_IDENTITY	(__IOMMU_DOMAIN_PT)
 #define IOMMU_DOMAIN_UNMANAGED	(__IOMMU_DOMAIN_PAGING)
+/* XXX: Introduce this type when we add PASID support for UNMANAGED domain */
+#define IOMMU_DOMAIN_UNMANAGED_SVA (__IOMMU_DOMAIN_PAGING |    \
+				    __IOMMU_DOMAIN_SVA)
 #define IOMMU_DOMAIN_DMA	(__IOMMU_DOMAIN_PAGING |	\
 				 __IOMMU_DOMAIN_DMA_API)
 #define IOMMU_DOMAIN_DMA_FQ	(__IOMMU_DOMAIN_PAGING |	\
@@ -557,7 +560,7 @@ struct iommu_ops {
 	struct iommu_domain *(*domain_alloc_user)(
 		struct device *dev, u32 flags, struct iommu_domain *parent,
 		const struct iommu_user_data *user_data);
-	struct iommu_domain *(*domain_alloc_paging)(struct device *dev);
+	struct iommu_domain *(*domain_alloc_paging)(struct device *dev, u32
iommu_domain_type);
 	struct iommu_domain *(*domain_alloc_sva)(struct device *dev,
 						 struct mm_struct *mm);


^ permalink raw reply related	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2024-07-16 13:41 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-06-28  6:43 [RFC] iommu_ops->domain_alloc_paging() enhancement to support AMD IOMMU driver Vasant Hegde
2024-06-28 12:23 ` Baolu Lu
2024-06-28 13:06   ` Robin Murphy
2024-06-28 17:08     ` Vasant Hegde
2024-06-28 17:58       ` Robin Murphy
2024-07-01 10:28         ` Vasant Hegde
2024-06-28 14:50   ` Vasant Hegde
2024-06-28 15:34     ` Jason Gunthorpe
2024-06-28 13:03 ` Jason Gunthorpe
2024-06-28 17:49   ` Vasant Hegde
2024-06-28 18:04     ` Jason Gunthorpe
2024-07-01 10:48       ` Vasant Hegde
2024-07-01 17:26         ` Jason Gunthorpe
2024-07-03  5:42           ` Vasant Hegde
2024-07-03  6:57             ` Yi Liu
2024-07-09 18:23               ` Jason Gunthorpe
2024-07-10  4:17                 ` Yi Liu
2024-07-11 23:49                   ` Jason Gunthorpe
2024-07-12 13:40                     ` Robin Murphy
2024-07-12 13:53                       ` Jason Gunthorpe
2024-07-12 15:12                         ` Robin Murphy
2024-07-12 15:19                           ` Jason Gunthorpe
2024-07-15  8:46                       ` Yi Liu
2024-07-11 10:15               ` Vasant Hegde
2024-07-11 13:56                 ` Yi Liu
2024-07-12  1:39                   ` Baolu Lu
2024-07-12  2:43                     ` Yi Liu
2024-07-15 10:39                   ` Vasant Hegde
2024-07-16  7:43                     ` Yi Liu
2024-07-16 13:41                       ` Jason Gunthorpe

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.