Re: [PATCH v6 2/4] iommu: Move global PASID allocation from SVA to core

From: Baolu Lu
Date: Sun May 21 2023 - 02:22:37 EST


On 5/20/23 4:32 AM, Jacob Pan wrote:
Global PASID can be used beyond SVA. For example, drivers that use
Intel ENQCMD to submit work must use global PASIDs in that PASID
is stored in a per CPU MSR. When such device need to submit work
for in-kernel DMA with PASID, it must allocate PASIDs from the same
global number space to avoid conflict.

This patch moves global PASID allocation APIs from SVA to IOMMU APIs.
Reserved PASIDs, currently only RID_PASID, are excluded from the global
PASID allocation.

It is expected that device drivers will use the allocated PASIDs to
attach to appropriate IOMMU domains for use.

Signed-off-by: Jacob Pan<jacob.jun.pan@xxxxxxxxxxxxxxx>
---
v6: explicitly exclude reserved a range from SVA PASID allocation
check mm PASID compatibility with device
v5: move PASID range check inside API so that device drivers only pass
in struct device* (Kevin)
v4: move dummy functions outside ifdef CONFIG_IOMMU_SVA (Baolu)
---
drivers/iommu/iommu-sva.c | 33 ++++++++++++++-------------------
drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++
include/linux/iommu.h | 10 ++++++++++
3 files changed, 48 insertions(+), 19 deletions(-)

diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c
index 9821bc44f5ac..7fe8e977d8eb 100644
--- a/drivers/iommu/iommu-sva.c
+++ b/drivers/iommu/iommu-sva.c
@@ -10,33 +10,33 @@
#include "iommu-sva.h"
static DEFINE_MUTEX(iommu_sva_lock);
-static DEFINE_IDA(iommu_global_pasid_ida);
/* Allocate a PASID for the mm within range (inclusive) */
-static int iommu_sva_alloc_pasid(struct mm_struct *mm, ioasid_t min, ioasid_t max)
+static int iommu_sva_alloc_pasid(struct mm_struct *mm, struct device *dev)
{
+ ioasid_t pasid;
int ret = 0;
- if (min == IOMMU_PASID_INVALID ||
- max == IOMMU_PASID_INVALID ||
- min == 0 || max < min)
- return -EINVAL;
-
if (!arch_pgtable_dma_compat(mm))
return -EBUSY;
mutex_lock(&iommu_sva_lock);
/* Is a PASID already associated with this mm? */
if (mm_valid_pasid(mm)) {
- if (mm->pasid < min || mm->pasid > max)
- ret = -EOVERFLOW;
+ if (mm->pasid <= dev->iommu->max_pasids)
+ goto out;
+ dev_err(dev, "current mm PASID %d exceeds device range %d!",
+ mm->pasid, dev->iommu->max_pasids);
+ ret = -ERANGE;
goto out;
}

Nit: Above is just refactoring, so it's better to keep the code behavior
consistent. For example, no need to change the error# from -EOVERFLOW to
-ERANGE, and no need to leave a new kernel message.

Anyway, if you think these changes are helpful, it's better to have them
in separated patches.

In the end, perhaps we can simply have code like this:

if (mm_valid_pasid(mm)) {
if (mm->pasid > dev->iommu->max_pasids)
ret = -EOVERFLOW;
goto out;
}

Others look good to me, with above addressed,

Reviewed-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx>

Best regards,
baolu