public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/2] io-pgtable-arm + drm/msm: Extend iova fault debugging
@ 2024-05-23 17:52 Rob Clark
  2024-05-23 17:52 ` [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk Rob Clark
  2024-05-23 17:52 ` [PATCH v4 2/2] drm/msm: Extend gpu devcore dumps with pgtbl info Rob Clark
  0 siblings, 2 replies; 11+ messages in thread
From: Rob Clark @ 2024-05-23 17:52 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-arm-msm, freedreno, Will Deacon, Rob Clark, Boris Brezillon,
	open list:IOMMU SUBSYSTEM, Jason Gunthorpe, Joao Martins,
	Kevin Tian, Konrad Dybcio, moderated list:ARM SMMU DRIVERS,
	open list, open list:POWER MANAGEMENT CORE, Lu Baolu,
	Marijn Suijten, Rafael J. Wysocki, Robin Murphy, Sean Paul

From: Rob Clark <robdclark@chromium.org>

This series extends io-pgtable-arm with a method to retrieve the page
table entries traversed in the process of address translation, and then
beefs up drm/msm gpu devcore dump to include this (and additional info)
in the devcore dump.

This is a respin of https://patchwork.freedesktop.org/series/94968/
(minus a patch that was already merged)

v2: Fix an armv7/32b build error in the last patch
v3: Incorperate Will Deacon's suggestion to make the interface
    callback based.
v4: Actually wire up the callback

Rob Clark (2):
  iommu/io-pgtable-arm: Add way to debug pgtable walk
  drm/msm: Extend gpu devcore dumps with pgtbl info

 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 +++++
 drivers/gpu/drm/msm/msm_gpu.c           | 22 +++++++++++
 drivers/gpu/drm/msm/msm_gpu.h           |  8 ++++
 drivers/gpu/drm/msm/msm_iommu.c         | 18 +++++++++
 drivers/gpu/drm/msm/msm_mmu.h           |  5 ++-
 drivers/iommu/io-pgtable-arm.c          | 51 ++++++++++++++++++++-----
 include/linux/io-pgtable.h              |  4 ++
 7 files changed, 108 insertions(+), 10 deletions(-)

-- 
2.45.1


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

* [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-05-23 17:52 [PATCH v4 0/2] io-pgtable-arm + drm/msm: Extend iova fault debugging Rob Clark
@ 2024-05-23 17:52 ` Rob Clark
  2024-06-13  9:10   ` Joerg Roedel
                     ` (2 more replies)
  2024-05-23 17:52 ` [PATCH v4 2/2] drm/msm: Extend gpu devcore dumps with pgtbl info Rob Clark
  1 sibling, 3 replies; 11+ messages in thread
From: Rob Clark @ 2024-05-23 17:52 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-arm-msm, freedreno, Will Deacon, Rob Clark, Robin Murphy,
	Joerg Roedel, Jason Gunthorpe, Boris Brezillon, Kevin Tian,
	Joao Martins, moderated list:ARM SMMU DRIVERS,
	open list:IOMMU SUBSYSTEM, open list

From: Rob Clark <robdclark@chromium.org>

Add an io-pgtable method to walk the pgtable returning the raw PTEs that
would be traversed for a given iova access.

Signed-off-by: Rob Clark <robdclark@chromium.org>
---
 drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
 include/linux/io-pgtable.h     |  4 +++
 2 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
index f7828a7aad41..f47a0e64bb35 100644
--- a/drivers/iommu/io-pgtable-arm.c
+++ b/drivers/iommu/io-pgtable-arm.c
@@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
 				data->start_level, ptep);
 }
 
-static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
-					 unsigned long iova)
+static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
+			int (*cb)(void *cb_data, void *pte, int level),
+			void *cb_data)
 {
 	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
 	arm_lpae_iopte pte, *ptep = data->pgd;
 	int lvl = data->start_level;
+	int ret;
 
 	do {
 		/* Valid IOPTE pointer? */
 		if (!ptep)
-			return 0;
+			return -EFAULT;
 
 		/* Grab the IOPTE we're interested in */
 		ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
@@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
 
 		/* Valid entry? */
 		if (!pte)
-			return 0;
+			return -EFAULT;
+
+		ret = cb(cb_data, &pte, lvl);
+		if (ret)
+			return ret;
 
-		/* Leaf entry? */
+		/* Leaf entry?  If so, we've found the translation */
 		if (iopte_leaf(pte, lvl, data->iop.fmt))
-			goto found_translation;
+			return 0;
 
 		/* Take it to the next level */
 		ptep = iopte_deref(pte, data);
 	} while (++lvl < ARM_LPAE_MAX_LEVELS);
 
 	/* Ran out of page tables to walk */
+	return -EFAULT;
+}
+
+struct iova_to_phys_walk_data {
+	arm_lpae_iopte pte;
+	int level;
+};
+
+static int iova_to_phys_walk_cb(void *cb_data, void *pte, int level)
+{
+	struct iova_to_phys_walk_data *d = cb_data;
+
+	d->pte = *(arm_lpae_iopte *)pte;
+	d->level = level;
+
 	return 0;
+}
+
+static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
+					 unsigned long iova)
+{
+	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
+	struct iova_to_phys_walk_data d;
+	int ret;
+
+	ret = arm_lpae_pgtable_walk(ops, iova, iova_to_phys_walk_cb, &d);
+	if (ret)
+		return 0;
 
-found_translation:
-	iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
-	return iopte_to_paddr(pte, data) | iova;
+	iova &= (ARM_LPAE_BLOCK_SIZE(d.level, data) - 1);
+	return iopte_to_paddr(d.pte, data) | iova;
 }
 
 static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
@@ -807,6 +839,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
 		.map_pages	= arm_lpae_map_pages,
 		.unmap_pages	= arm_lpae_unmap_pages,
 		.iova_to_phys	= arm_lpae_iova_to_phys,
+		.pgtable_walk	= arm_lpae_pgtable_walk,
 	};
 
 	return data;
diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
index 86cf1f7ae389..261b48af068a 100644
--- a/include/linux/io-pgtable.h
+++ b/include/linux/io-pgtable.h
@@ -177,6 +177,7 @@ struct io_pgtable_cfg {
  * @map_pages:    Map a physically contiguous range of pages of the same size.
  * @unmap_pages:  Unmap a range of virtually contiguous pages of the same size.
  * @iova_to_phys: Translate iova to physical address.
+ * @pgtable_walk: (optional) Perform a page table walk for a given iova.
  *
  * These functions map directly onto the iommu_ops member functions with
  * the same names.
@@ -190,6 +191,9 @@ struct io_pgtable_ops {
 			      struct iommu_iotlb_gather *gather);
 	phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
 				    unsigned long iova);
+	int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova,
+			    int (*cb)(void *cb_data, void *pte, int level),
+			    void *cb_data);
 	int (*read_and_clear_dirty)(struct io_pgtable_ops *ops,
 				    unsigned long iova, size_t size,
 				    unsigned long flags,
-- 
2.45.1


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

* [PATCH v4 2/2] drm/msm: Extend gpu devcore dumps with pgtbl info
  2024-05-23 17:52 [PATCH v4 0/2] io-pgtable-arm + drm/msm: Extend iova fault debugging Rob Clark
  2024-05-23 17:52 ` [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk Rob Clark
@ 2024-05-23 17:52 ` Rob Clark
  1 sibling, 0 replies; 11+ messages in thread
From: Rob Clark @ 2024-05-23 17:52 UTC (permalink / raw)
  To: dri-devel
  Cc: linux-arm-msm, freedreno, Will Deacon, Rob Clark, Rob Clark,
	Sean Paul, Konrad Dybcio, Abhinav Kumar, Dmitry Baryshkov,
	Marijn Suijten, David Airlie, Daniel Vetter, open list

From: Rob Clark <robdclark@chromium.org>

In the case of iova fault triggered devcore dumps, include additional
debug information based on what we think is the current page tables,
including the TTBR0 value (which should match what we have in
adreno_smmu_fault_info unless things have gone horribly wrong), and
the pagetable entries traversed in the process of resolving the
faulting iova.

Signed-off-by: Rob Clark <robdclark@chromium.org>
---
 drivers/gpu/drm/msm/adreno/adreno_gpu.c | 10 ++++++++++
 drivers/gpu/drm/msm/msm_gpu.c           | 22 ++++++++++++++++++++++
 drivers/gpu/drm/msm/msm_gpu.h           |  8 ++++++++
 drivers/gpu/drm/msm/msm_iommu.c         | 18 ++++++++++++++++++
 drivers/gpu/drm/msm/msm_mmu.h           |  5 ++++-
 5 files changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
index a00241e3373b..3b4c75df0a5f 100644
--- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c
+++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c
@@ -861,6 +861,16 @@ void adreno_show(struct msm_gpu *gpu, struct msm_gpu_state *state,
 		drm_printf(p, "  - dir=%s\n", info->flags & IOMMU_FAULT_WRITE ? "WRITE" : "READ");
 		drm_printf(p, "  - type=%s\n", info->type);
 		drm_printf(p, "  - source=%s\n", info->block);
+
+		/* Information extracted from what we think are the current
+		 * pgtables.  Hopefully the TTBR0 matches what we've extracted
+		 * from the SMMU registers in smmu_info!
+		 */
+		drm_puts(p, "pgtable-fault-info:\n");
+		drm_printf(p, "  - ttbr0: %.16llx\n", (u64)info->pgtbl_ttbr0);
+		drm_printf(p, "  - asid: %d\n", info->asid);
+		drm_printf(p, "  - ptes: %.16llx %.16llx %.16llx %.16llx\n",
+			   info->ptes[0], info->ptes[1], info->ptes[2], info->ptes[3]);
 	}
 
 	drm_printf(p, "rbbm-status: 0x%08x\n", state->rbbm_status);
diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c
index 43cde0590250..647bddc897f2 100644
--- a/drivers/gpu/drm/msm/msm_gpu.c
+++ b/drivers/gpu/drm/msm/msm_gpu.c
@@ -256,6 +256,18 @@ static void msm_gpu_crashstate_get_bo(struct msm_gpu_state *state,
 	state->nr_bos++;
 }
 
+static int pgtable_walk_cb(void *cb_data, void *pte, int level)
+{
+	struct msm_gpu_fault_info *info = cb_data;
+
+	if (level > ARRAY_SIZE(info->ptes))
+		return -EINVAL;
+
+	info->ptes[level] = *(u64 *)pte;
+
+	return 0;
+}
+
 static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
 		struct msm_gem_submit *submit, char *comm, char *cmd)
 {
@@ -281,6 +293,16 @@ static void msm_gpu_crashstate_capture(struct msm_gpu *gpu,
 	if (submit) {
 		int i;
 
+		if (state->fault_info.ttbr0) {
+			struct msm_gpu_fault_info *info = &state->fault_info;
+			struct msm_mmu *mmu = submit->aspace->mmu;
+
+			msm_iommu_pagetable_params(mmu, &info->pgtbl_ttbr0,
+						   &info->asid);
+			msm_iommu_pagetable_walk(mmu, info->iova,
+						 pgtable_walk_cb, info);
+		}
+
 		state->bos = kcalloc(submit->nr_bos,
 			sizeof(struct msm_gpu_state_bo), GFP_KERNEL);
 
diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h
index 04a696ac4626..82fbb626461a 100644
--- a/drivers/gpu/drm/msm/msm_gpu.h
+++ b/drivers/gpu/drm/msm/msm_gpu.h
@@ -101,6 +101,14 @@ struct msm_gpu_fault_info {
 	int flags;
 	const char *type;
 	const char *block;
+
+	/* Information about what we think/expect is the current SMMU state,
+	 * for example expected_ttbr0 should match smmu_info.ttbr0 which
+	 * was read back from SMMU registers.
+	 */
+	phys_addr_t pgtbl_ttbr0;
+	u64 ptes[4];
+	int asid;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c
index d5512037c38b..f46ed4667475 100644
--- a/drivers/gpu/drm/msm/msm_iommu.c
+++ b/drivers/gpu/drm/msm/msm_iommu.c
@@ -195,6 +195,24 @@ struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu)
 	return &iommu->domain->geometry;
 }
 
+int msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova,
+			     int (*cb)(void *cb_data, void *pte, int level),
+			     void *cb_data)
+{
+	struct msm_iommu_pagetable *pagetable;
+
+	if (mmu->type != MSM_MMU_IOMMU_PAGETABLE)
+		return -EINVAL;
+
+	pagetable = to_pagetable(mmu);
+
+	if (!pagetable->pgtbl_ops->pgtable_walk)
+		return -EINVAL;
+
+	return pagetable->pgtbl_ops->pgtable_walk(pagetable->pgtbl_ops, iova,
+						  cb, cb_data);
+}
+
 static const struct msm_mmu_funcs pagetable_funcs = {
 		.map = msm_iommu_pagetable_map,
 		.unmap = msm_iommu_pagetable_unmap,
diff --git a/drivers/gpu/drm/msm/msm_mmu.h b/drivers/gpu/drm/msm/msm_mmu.h
index 88af4f490881..46b2550b9b7a 100644
--- a/drivers/gpu/drm/msm/msm_mmu.h
+++ b/drivers/gpu/drm/msm/msm_mmu.h
@@ -53,7 +53,10 @@ static inline void msm_mmu_set_fault_handler(struct msm_mmu *mmu, void *arg,
 struct msm_mmu *msm_iommu_pagetable_create(struct msm_mmu *parent);
 
 int msm_iommu_pagetable_params(struct msm_mmu *mmu, phys_addr_t *ttbr,
-		int *asid);
+			       int *asid);
+int msm_iommu_pagetable_walk(struct msm_mmu *mmu, unsigned long iova,
+			     int (*cb)(void *cb_data, void *pte, int level),
+			     void *cb_data);
 struct iommu_domain_geometry *msm_iommu_get_geometry(struct msm_mmu *mmu);
 
 #endif /* __MSM_MMU_H__ */
-- 
2.45.1


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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-05-23 17:52 ` [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk Rob Clark
@ 2024-06-13  9:10   ` Joerg Roedel
  2024-06-17 15:13   ` Robin Murphy
  2024-06-24 15:14   ` Will Deacon
  2 siblings, 0 replies; 11+ messages in thread
From: Joerg Roedel @ 2024-06-13  9:10 UTC (permalink / raw)
  To: Rob Clark
  Cc: dri-devel, linux-arm-msm, freedreno, Will Deacon, Rob Clark,
	Robin Murphy, Jason Gunthorpe, Boris Brezillon, Kevin Tian,
	Joao Martins, moderated list:ARM SMMU DRIVERS,
	open list:IOMMU SUBSYSTEM, open list

On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote:
> From: Rob Clark <robdclark@chromium.org>
> 
> Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> would be traversed for a given iova access.
> 
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
>  drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
>  include/linux/io-pgtable.h     |  4 +++
>  2 files changed, 46 insertions(+), 9 deletions(-)

Acked-by: Joerg Roedel <jroedel@suse.de>


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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-05-23 17:52 ` [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk Rob Clark
  2024-06-13  9:10   ` Joerg Roedel
@ 2024-06-17 15:13   ` Robin Murphy
  2024-06-19 16:33     ` Jason Gunthorpe
  2024-06-24 15:14   ` Will Deacon
  2 siblings, 1 reply; 11+ messages in thread
From: Robin Murphy @ 2024-06-17 15:13 UTC (permalink / raw)
  To: Rob Clark, Will Deacon
  Cc: linux-arm-msm, freedreno, Rob Clark, Joerg Roedel,
	Jason Gunthorpe, Boris Brezillon, Kevin Tian, Joao Martins,
	moderated list:ARM SMMU DRIVERS, open list:IOMMU SUBSYSTEM,
	open list, dri-devel

On 23/05/2024 6:52 pm, Rob Clark wrote:
> From: Rob Clark <robdclark@chromium.org>
> 
> Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> would be traversed for a given iova access.

Have to say I'm a little torn here - with my iommu-dma hat on I'm not 
super enthusiastic about adding any more overhead to iova_to_phys, but 
in terms of maintaining io-pgtable I do like the overall shape of the 
implementation...

Will, how much would you hate a compromise of inlining iova_to_phys as 
the default walk behaviour if cb is NULL? :)

That said, looking at the unmap figures for dma_map_benchmark on a 
Neoverse N1, any difference I think I see is still well within the 
noise, so maybe a handful of extra indirect calls isn't really enough to 
worry about?

Cheers,
Robin.

> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
>   drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
>   include/linux/io-pgtable.h     |  4 +++
>   2 files changed, 46 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index f7828a7aad41..f47a0e64bb35 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
>   				data->start_level, ptep);
>   }
>   
> -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> -					 unsigned long iova)
> +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
> +			int (*cb)(void *cb_data, void *pte, int level),
> +			void *cb_data)
>   {
>   	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
>   	arm_lpae_iopte pte, *ptep = data->pgd;
>   	int lvl = data->start_level;
> +	int ret;
>   
>   	do {
>   		/* Valid IOPTE pointer? */
>   		if (!ptep)
> -			return 0;
> +			return -EFAULT;
>   
>   		/* Grab the IOPTE we're interested in */
>   		ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
>   
>   		/* Valid entry? */
>   		if (!pte)
> -			return 0;
> +			return -EFAULT;
> +
> +		ret = cb(cb_data, &pte, lvl);
> +		if (ret)
> +			return ret;
>   
> -		/* Leaf entry? */
> +		/* Leaf entry?  If so, we've found the translation */
>   		if (iopte_leaf(pte, lvl, data->iop.fmt))
> -			goto found_translation;
> +			return 0;
>   
>   		/* Take it to the next level */
>   		ptep = iopte_deref(pte, data);
>   	} while (++lvl < ARM_LPAE_MAX_LEVELS);
>   
>   	/* Ran out of page tables to walk */
> +	return -EFAULT;
> +}
> +
> +struct iova_to_phys_walk_data {
> +	arm_lpae_iopte pte;
> +	int level;
> +};
> +
> +static int iova_to_phys_walk_cb(void *cb_data, void *pte, int level)
> +{
> +	struct iova_to_phys_walk_data *d = cb_data;
> +
> +	d->pte = *(arm_lpae_iopte *)pte;
> +	d->level = level;
> +
>   	return 0;
> +}
> +
> +static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> +					 unsigned long iova)
> +{
> +	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> +	struct iova_to_phys_walk_data d;
> +	int ret;
> +
> +	ret = arm_lpae_pgtable_walk(ops, iova, iova_to_phys_walk_cb, &d);
> +	if (ret)
> +		return 0;
>   
> -found_translation:
> -	iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1);
> -	return iopte_to_paddr(pte, data) | iova;
> +	iova &= (ARM_LPAE_BLOCK_SIZE(d.level, data) - 1);
> +	return iopte_to_paddr(d.pte, data) | iova;
>   }
>   
>   static void arm_lpae_restrict_pgsizes(struct io_pgtable_cfg *cfg)
> @@ -807,6 +839,7 @@ arm_lpae_alloc_pgtable(struct io_pgtable_cfg *cfg)
>   		.map_pages	= arm_lpae_map_pages,
>   		.unmap_pages	= arm_lpae_unmap_pages,
>   		.iova_to_phys	= arm_lpae_iova_to_phys,
> +		.pgtable_walk	= arm_lpae_pgtable_walk,
>   	};
>   
>   	return data;
> diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h
> index 86cf1f7ae389..261b48af068a 100644
> --- a/include/linux/io-pgtable.h
> +++ b/include/linux/io-pgtable.h
> @@ -177,6 +177,7 @@ struct io_pgtable_cfg {
>    * @map_pages:    Map a physically contiguous range of pages of the same size.
>    * @unmap_pages:  Unmap a range of virtually contiguous pages of the same size.
>    * @iova_to_phys: Translate iova to physical address.
> + * @pgtable_walk: (optional) Perform a page table walk for a given iova.
>    *
>    * These functions map directly onto the iommu_ops member functions with
>    * the same names.
> @@ -190,6 +191,9 @@ struct io_pgtable_ops {
>   			      struct iommu_iotlb_gather *gather);
>   	phys_addr_t (*iova_to_phys)(struct io_pgtable_ops *ops,
>   				    unsigned long iova);
> +	int (*pgtable_walk)(struct io_pgtable_ops *ops, unsigned long iova,
> +			    int (*cb)(void *cb_data, void *pte, int level),
> +			    void *cb_data);
>   	int (*read_and_clear_dirty)(struct io_pgtable_ops *ops,
>   				    unsigned long iova, size_t size,
>   				    unsigned long flags,

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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-06-17 15:13   ` Robin Murphy
@ 2024-06-19 16:33     ` Jason Gunthorpe
  0 siblings, 0 replies; 11+ messages in thread
From: Jason Gunthorpe @ 2024-06-19 16:33 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Rob Clark, Will Deacon, linux-arm-msm, freedreno, Rob Clark,
	Joerg Roedel, Boris Brezillon, Kevin Tian, Joao Martins,
	moderated list:ARM SMMU DRIVERS, open list:IOMMU SUBSYSTEM,
	open list, dri-devel

On Mon, Jun 17, 2024 at 04:13:41PM +0100, Robin Murphy wrote:
> On 23/05/2024 6:52 pm, Rob Clark wrote:
> > From: Rob Clark <robdclark@chromium.org>
> > 
> > Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> > would be traversed for a given iova access.
> 
> Have to say I'm a little torn here - with my iommu-dma hat on I'm not super
> enthusiastic about adding any more overhead to iova_to_phys, but in terms of
> maintaining io-pgtable I do like the overall shape of the implementation...

If you mark arm_lpae_pgtable_walk() and the callbacks as
__always_inline then the compiler should generate the same code as
today for arm_lpae_iova_to_phys().

Jason

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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-05-23 17:52 ` [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk Rob Clark
  2024-06-13  9:10   ` Joerg Roedel
  2024-06-17 15:13   ` Robin Murphy
@ 2024-06-24 15:14   ` Will Deacon
  2024-06-24 15:37     ` Rob Clark
  2024-06-26 18:50     ` Rob Clark
  2 siblings, 2 replies; 11+ messages in thread
From: Will Deacon @ 2024-06-24 15:14 UTC (permalink / raw)
  To: Rob Clark
  Cc: dri-devel, linux-arm-msm, freedreno, Rob Clark, Robin Murphy,
	Joerg Roedel, Jason Gunthorpe, Boris Brezillon, Kevin Tian,
	Joao Martins, moderated list:ARM SMMU DRIVERS,
	open list:IOMMU SUBSYSTEM, open list

On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote:
> From: Rob Clark <robdclark@chromium.org>
> 
> Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> would be traversed for a given iova access.
> 
> Signed-off-by: Rob Clark <robdclark@chromium.org>
> ---
>  drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
>  include/linux/io-pgtable.h     |  4 +++
>  2 files changed, 46 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> index f7828a7aad41..f47a0e64bb35 100644
> --- a/drivers/iommu/io-pgtable-arm.c
> +++ b/drivers/iommu/io-pgtable-arm.c
> @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
>  				data->start_level, ptep);
>  }
>  
> -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> -					 unsigned long iova)
> +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
> +			int (*cb)(void *cb_data, void *pte, int level),
> +			void *cb_data)
>  {
>  	struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
>  	arm_lpae_iopte pte, *ptep = data->pgd;
>  	int lvl = data->start_level;
> +	int ret;
>  
>  	do {
>  		/* Valid IOPTE pointer? */
>  		if (!ptep)
> -			return 0;
> +			return -EFAULT;

nit: -ENOENT might be a little better, as we're only checking against a
NULL entry rather than strictly any faulting entry.

>  		/* Grab the IOPTE we're interested in */
>  		ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
>  
>  		/* Valid entry? */
>  		if (!pte)
> -			return 0;
> +			return -EFAULT;

Same here (and at the end of the function).

> +
> +		ret = cb(cb_data, &pte, lvl);

Since pte is on the stack, rather than pointing into the actual pgtable,
I think it would be clearer to pass it by value to the callback.

> +		if (ret)
> +			return ret;
>  
> -		/* Leaf entry? */
> +		/* Leaf entry?  If so, we've found the translation */
>  		if (iopte_leaf(pte, lvl, data->iop.fmt))
> -			goto found_translation;
> +			return 0;
>  
>  		/* Take it to the next level */
>  		ptep = iopte_deref(pte, data);
>  	} while (++lvl < ARM_LPAE_MAX_LEVELS);
>  
>  	/* Ran out of page tables to walk */
> +	return -EFAULT;
> +}
> +
> +struct iova_to_phys_walk_data {
> +	arm_lpae_iopte pte;
> +	int level;
> +};

Expanding a little on Robin's suggestion, why don't we drop this structure
in favour of something more generic:

	struct arm_lpae_walk_data {
		arm_lpae_iopte ptes[ARM_LPAE_MAX_LEVELS];
	};

and then do something in the walker like:

	if (cb && !cb(pte, lvl))
		walk_data->ptes[lvl] = pte;

which could return the physical address at the end, if it reaches a leaf
entry. That way arm_lpae_iova_to_phys() is just passing a NULL callback
to the walker and your debug callback just needs to return 0 (i.e. the
callback is basically just saying whether or not to continue the walk).

Will

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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-06-24 15:14   ` Will Deacon
@ 2024-06-24 15:37     ` Rob Clark
  2024-06-25 11:27       ` Will Deacon
  2024-06-26 18:50     ` Rob Clark
  1 sibling, 1 reply; 11+ messages in thread
From: Rob Clark @ 2024-06-24 15:37 UTC (permalink / raw)
  To: Will Deacon
  Cc: dri-devel, linux-arm-msm, freedreno, Rob Clark, Robin Murphy,
	Joerg Roedel, Jason Gunthorpe, Boris Brezillon, Kevin Tian,
	Joao Martins, moderated list:ARM SMMU DRIVERS,
	open list:IOMMU SUBSYSTEM, open list

On Mon, Jun 24, 2024 at 8:14 AM Will Deacon <will@kernel.org> wrote:
>
> On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote:
> > From: Rob Clark <robdclark@chromium.org>
> >
> > Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> > would be traversed for a given iova access.
> >
> > Signed-off-by: Rob Clark <robdclark@chromium.org>
> > ---
> >  drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
> >  include/linux/io-pgtable.h     |  4 +++
> >  2 files changed, 46 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> > index f7828a7aad41..f47a0e64bb35 100644
> > --- a/drivers/iommu/io-pgtable-arm.c
> > +++ b/drivers/iommu/io-pgtable-arm.c
> > @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
> >                               data->start_level, ptep);
> >  }
> >
> > -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> > -                                      unsigned long iova)
> > +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
> > +                     int (*cb)(void *cb_data, void *pte, int level),
> > +                     void *cb_data)
> >  {
> >       struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> >       arm_lpae_iopte pte, *ptep = data->pgd;
> >       int lvl = data->start_level;
> > +     int ret;
> >
> >       do {
> >               /* Valid IOPTE pointer? */
> >               if (!ptep)
> > -                     return 0;
> > +                     return -EFAULT;
>
> nit: -ENOENT might be a little better, as we're only checking against a
> NULL entry rather than strictly any faulting entry.
>
> >               /* Grab the IOPTE we're interested in */
> >               ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> > @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> >
> >               /* Valid entry? */
> >               if (!pte)
> > -                     return 0;
> > +                     return -EFAULT;
>
> Same here (and at the end of the function).
>
> > +
> > +             ret = cb(cb_data, &pte, lvl);
>
> Since pte is on the stack, rather than pointing into the actual pgtable,
> I think it would be clearer to pass it by value to the callback.

fwiw, I passed it as a void* to avoid the pte size.. although I guess
it could be a union of all the possible pte types

BR,
-R

>
> > +             if (ret)
> > +                     return ret;
> >
> > -             /* Leaf entry? */
> > +             /* Leaf entry?  If so, we've found the translation */
> >               if (iopte_leaf(pte, lvl, data->iop.fmt))
> > -                     goto found_translation;
> > +                     return 0;
> >
> >               /* Take it to the next level */
> >               ptep = iopte_deref(pte, data);
> >       } while (++lvl < ARM_LPAE_MAX_LEVELS);
> >
> >       /* Ran out of page tables to walk */
> > +     return -EFAULT;
> > +}
> > +
> > +struct iova_to_phys_walk_data {
> > +     arm_lpae_iopte pte;
> > +     int level;
> > +};
>
> Expanding a little on Robin's suggestion, why don't we drop this structure
> in favour of something more generic:
>
>         struct arm_lpae_walk_data {
>                 arm_lpae_iopte ptes[ARM_LPAE_MAX_LEVELS];
>         };
>
> and then do something in the walker like:
>
>         if (cb && !cb(pte, lvl))
>                 walk_data->ptes[lvl] = pte;
>
> which could return the physical address at the end, if it reaches a leaf
> entry. That way arm_lpae_iova_to_phys() is just passing a NULL callback
> to the walker and your debug callback just needs to return 0 (i.e. the
> callback is basically just saying whether or not to continue the walk).
>
> Will

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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-06-24 15:37     ` Rob Clark
@ 2024-06-25 11:27       ` Will Deacon
  2024-06-25 15:36         ` Rob Clark
  0 siblings, 1 reply; 11+ messages in thread
From: Will Deacon @ 2024-06-25 11:27 UTC (permalink / raw)
  To: Rob Clark
  Cc: dri-devel, linux-arm-msm, freedreno, Rob Clark, Robin Murphy,
	Joerg Roedel, Jason Gunthorpe, Boris Brezillon, Kevin Tian,
	Joao Martins, moderated list:ARM SMMU DRIVERS,
	open list:IOMMU SUBSYSTEM, open list

On Mon, Jun 24, 2024 at 08:37:26AM -0700, Rob Clark wrote:
> On Mon, Jun 24, 2024 at 8:14 AM Will Deacon <will@kernel.org> wrote:
> >
> > On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote:
> > > From: Rob Clark <robdclark@chromium.org>
> > >
> > > Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> > > would be traversed for a given iova access.
> > >
> > > Signed-off-by: Rob Clark <robdclark@chromium.org>
> > > ---
> > >  drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
> > >  include/linux/io-pgtable.h     |  4 +++
> > >  2 files changed, 46 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> > > index f7828a7aad41..f47a0e64bb35 100644
> > > --- a/drivers/iommu/io-pgtable-arm.c
> > > +++ b/drivers/iommu/io-pgtable-arm.c
> > > @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
> > >                               data->start_level, ptep);
> > >  }
> > >
> > > -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> > > -                                      unsigned long iova)
> > > +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
> > > +                     int (*cb)(void *cb_data, void *pte, int level),
> > > +                     void *cb_data)
> > >  {
> > >       struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> > >       arm_lpae_iopte pte, *ptep = data->pgd;
> > >       int lvl = data->start_level;
> > > +     int ret;
> > >
> > >       do {
> > >               /* Valid IOPTE pointer? */
> > >               if (!ptep)
> > > -                     return 0;
> > > +                     return -EFAULT;
> >
> > nit: -ENOENT might be a little better, as we're only checking against a
> > NULL entry rather than strictly any faulting entry.
> >
> > >               /* Grab the IOPTE we're interested in */
> > >               ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> > > @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> > >
> > >               /* Valid entry? */
> > >               if (!pte)
> > > -                     return 0;
> > > +                     return -EFAULT;
> >
> > Same here (and at the end of the function).
> >
> > > +
> > > +             ret = cb(cb_data, &pte, lvl);
> >
> > Since pte is on the stack, rather than pointing into the actual pgtable,
> > I think it would be clearer to pass it by value to the callback.
> 
> fwiw, I passed it as a void* to avoid the pte size.. although I guess
> it could be a union of all the possible pte types

Can you just get away with a u64?

Will

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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-06-25 11:27       ` Will Deacon
@ 2024-06-25 15:36         ` Rob Clark
  0 siblings, 0 replies; 11+ messages in thread
From: Rob Clark @ 2024-06-25 15:36 UTC (permalink / raw)
  To: Will Deacon
  Cc: dri-devel, linux-arm-msm, freedreno, Rob Clark, Robin Murphy,
	Joerg Roedel, Jason Gunthorpe, Boris Brezillon, Kevin Tian,
	Joao Martins, moderated list:ARM SMMU DRIVERS,
	open list:IOMMU SUBSYSTEM, open list

On Tue, Jun 25, 2024 at 4:27 AM Will Deacon <will@kernel.org> wrote:
>
> On Mon, Jun 24, 2024 at 08:37:26AM -0700, Rob Clark wrote:
> > On Mon, Jun 24, 2024 at 8:14 AM Will Deacon <will@kernel.org> wrote:
> > >
> > > On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote:
> > > > From: Rob Clark <robdclark@chromium.org>
> > > >
> > > > Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> > > > would be traversed for a given iova access.
> > > >
> > > > Signed-off-by: Rob Clark <robdclark@chromium.org>
> > > > ---
> > > >  drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
> > > >  include/linux/io-pgtable.h     |  4 +++
> > > >  2 files changed, 46 insertions(+), 9 deletions(-)
> > > >
> > > > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> > > > index f7828a7aad41..f47a0e64bb35 100644
> > > > --- a/drivers/iommu/io-pgtable-arm.c
> > > > +++ b/drivers/iommu/io-pgtable-arm.c
> > > > @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
> > > >                               data->start_level, ptep);
> > > >  }
> > > >
> > > > -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> > > > -                                      unsigned long iova)
> > > > +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
> > > > +                     int (*cb)(void *cb_data, void *pte, int level),
> > > > +                     void *cb_data)
> > > >  {
> > > >       struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> > > >       arm_lpae_iopte pte, *ptep = data->pgd;
> > > >       int lvl = data->start_level;
> > > > +     int ret;
> > > >
> > > >       do {
> > > >               /* Valid IOPTE pointer? */
> > > >               if (!ptep)
> > > > -                     return 0;
> > > > +                     return -EFAULT;
> > >
> > > nit: -ENOENT might be a little better, as we're only checking against a
> > > NULL entry rather than strictly any faulting entry.
> > >
> > > >               /* Grab the IOPTE we're interested in */
> > > >               ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> > > > @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> > > >
> > > >               /* Valid entry? */
> > > >               if (!pte)
> > > > -                     return 0;
> > > > +                     return -EFAULT;
> > >
> > > Same here (and at the end of the function).
> > >
> > > > +
> > > > +             ret = cb(cb_data, &pte, lvl);
> > >
> > > Since pte is on the stack, rather than pointing into the actual pgtable,
> > > I think it would be clearer to pass it by value to the callback.
> >
> > fwiw, I passed it as a void* to avoid the pte size.. although I guess
> > it could be a union of all the possible pte types
>
> Can you just get away with a u64?

yeah, that wfm if you're ok with it

BR,
-R

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

* Re: [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk
  2024-06-24 15:14   ` Will Deacon
  2024-06-24 15:37     ` Rob Clark
@ 2024-06-26 18:50     ` Rob Clark
  1 sibling, 0 replies; 11+ messages in thread
From: Rob Clark @ 2024-06-26 18:50 UTC (permalink / raw)
  To: Will Deacon
  Cc: Rob Clark, dri-devel, linux-arm-msm, freedreno, Robin Murphy,
	Joerg Roedel, Jason Gunthorpe, Boris Brezillon, Kevin Tian,
	Joao Martins, moderated list:ARM SMMU DRIVERS,
	open list:IOMMU SUBSYSTEM, open list

On Mon, Jun 24, 2024 at 8:14 AM Will Deacon <will@kernel.org> wrote:
>
> On Thu, May 23, 2024 at 10:52:21AM -0700, Rob Clark wrote:
> > From: Rob Clark <robdclark@chromium.org>
> >
> > Add an io-pgtable method to walk the pgtable returning the raw PTEs that
> > would be traversed for a given iova access.
> >
> > Signed-off-by: Rob Clark <robdclark@chromium.org>
> > ---
> >  drivers/iommu/io-pgtable-arm.c | 51 ++++++++++++++++++++++++++++------
> >  include/linux/io-pgtable.h     |  4 +++
> >  2 files changed, 46 insertions(+), 9 deletions(-)
> >
> > diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c
> > index f7828a7aad41..f47a0e64bb35 100644
> > --- a/drivers/iommu/io-pgtable-arm.c
> > +++ b/drivers/iommu/io-pgtable-arm.c
> > @@ -693,17 +693,19 @@ static size_t arm_lpae_unmap_pages(struct io_pgtable_ops *ops, unsigned long iov
> >                               data->start_level, ptep);
> >  }
> >
> > -static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> > -                                      unsigned long iova)
> > +static int arm_lpae_pgtable_walk(struct io_pgtable_ops *ops, unsigned long iova,
> > +                     int (*cb)(void *cb_data, void *pte, int level),
> > +                     void *cb_data)
> >  {
> >       struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
> >       arm_lpae_iopte pte, *ptep = data->pgd;
> >       int lvl = data->start_level;
> > +     int ret;
> >
> >       do {
> >               /* Valid IOPTE pointer? */
> >               if (!ptep)
> > -                     return 0;
> > +                     return -EFAULT;
>
> nit: -ENOENT might be a little better, as we're only checking against a
> NULL entry rather than strictly any faulting entry.
>
> >               /* Grab the IOPTE we're interested in */
> >               ptep += ARM_LPAE_LVL_IDX(iova, lvl, data);
> > @@ -711,22 +713,52 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops,
> >
> >               /* Valid entry? */
> >               if (!pte)
> > -                     return 0;
> > +                     return -EFAULT;
>
> Same here (and at the end of the function).
>
> > +
> > +             ret = cb(cb_data, &pte, lvl);
>
> Since pte is on the stack, rather than pointing into the actual pgtable,
> I think it would be clearer to pass it by value to the callback.
>
> > +             if (ret)
> > +                     return ret;
> >
> > -             /* Leaf entry? */
> > +             /* Leaf entry?  If so, we've found the translation */
> >               if (iopte_leaf(pte, lvl, data->iop.fmt))
> > -                     goto found_translation;
> > +                     return 0;
> >
> >               /* Take it to the next level */
> >               ptep = iopte_deref(pte, data);
> >       } while (++lvl < ARM_LPAE_MAX_LEVELS);
> >
> >       /* Ran out of page tables to walk */
> > +     return -EFAULT;
> > +}
> > +
> > +struct iova_to_phys_walk_data {
> > +     arm_lpae_iopte pte;
> > +     int level;
> > +};
>
> Expanding a little on Robin's suggestion, why don't we drop this structure
> in favour of something more generic:
>
>         struct arm_lpae_walk_data {
>                 arm_lpae_iopte ptes[ARM_LPAE_MAX_LEVELS];
>         };
>
> and then do something in the walker like:
>
>         if (cb && !cb(pte, lvl))
>                 walk_data->ptes[lvl] = pte;
>

So thinking about this some more... if I use a walk_data struct to
return the PTEs, I can just get rid of the callback entirely.  That
ends up looking more like my first version.   The callback taking
void* was mainly to avoid coding the PTE size in the generic
io_pgtable interface.  But if we just go with u64, because that is the
biggest PTE size we need to deal with, then it all gets simpler.  (The
callback was actually a semi-awkward interface to use from drm/msm.)

BR,
-R

> which could return the physical address at the end, if it reaches a leaf
> entry. That way arm_lpae_iova_to_phys() is just passing a NULL callback
> to the walker and your debug callback just needs to return 0 (i.e. the
> callback is basically just saying whether or not to continue the walk).
>
> Will

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

end of thread, other threads:[~2024-06-26 18:51 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-05-23 17:52 [PATCH v4 0/2] io-pgtable-arm + drm/msm: Extend iova fault debugging Rob Clark
2024-05-23 17:52 ` [PATCH v4 1/2] iommu/io-pgtable-arm: Add way to debug pgtable walk Rob Clark
2024-06-13  9:10   ` Joerg Roedel
2024-06-17 15:13   ` Robin Murphy
2024-06-19 16:33     ` Jason Gunthorpe
2024-06-24 15:14   ` Will Deacon
2024-06-24 15:37     ` Rob Clark
2024-06-25 11:27       ` Will Deacon
2024-06-25 15:36         ` Rob Clark
2024-06-26 18:50     ` Rob Clark
2024-05-23 17:52 ` [PATCH v4 2/2] drm/msm: Extend gpu devcore dumps with pgtbl info Rob Clark

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox