iommu: iommu-debug: Add support for page table dump

Add support for page table dump for test domain.

eg:
cd /d/iommu/tests/soc:apps_iommu_test_device
echo 1 > attach
echo 0x20000,0x80000000,0x10000,0x1 > map
echo 0x21000,0x1000 > unmap
echo 0x24000,0x1000 > unmap
cat iommu_page_tables

---[ start ]---
0x0000000000020000-0x0000000000021000 4K PTE USR ro x AF NG DEVICE/nGnRnE
0x0000000000022000-0x0000000000024000 8K PTE USR ro x AF NG DEVICE/nGnRnE
0x0000000000025000-0x0000000000030000 44K PTE USR ro x AF NG DEVICE/nGnRnE

Change-Id: I56ac2615c4aa30dd75a2cdc1cf46de042e681cdc
Signed-off-by: Prakash Gupta <guptap@codeaurora.org>
[isaacm@codeaurora.org: Explicitly set final entry in the markers array]
Signed-off-by: Isaac J. Manjarres <isaacm@codeaurora.org>
This commit is contained in:
Prakash Gupta 2019-06-12 14:32:03 +05:30 • committed by Isaac J. Manjarres
commit c1c73311c3
2 changed files with 55 additions and 0 deletions

View file

@ -562,6 +562,7 @@ config IOMMU_DEBUG_TRACKING
config IOMMU_TESTS
bool "Interactive IOMMU performance/functional tests"
select IOMMU_API
select ARM64_PTDUMP_CORE
help
Enables a suite of IOMMU unit tests. The tests are runnable
through debugfs. Unlike the IOMMU_DEBUG_TRACKING option, the

View file

@ -34,6 +34,10 @@
#include <linux/dma-mapping-fast.h>
#include "iommu-debug.h"
#ifdef CONFIG_ARM64_PTDUMP_CORE
#include <asm/ptdump.h>
#endif
#if defined(CONFIG_IOMMU_TESTS)
static const char *iommu_debug_attr_to_string(enum iommu_attr attr)
@ -182,6 +186,9 @@ struct iommu_debug_device {
unsigned int clk_count;
/* Protects domain */
struct mutex state_lock;
#ifdef CONFIG_ARM64_PTDUMP_CORE
struct ptdump_info pt_info;
#endif
};
static int iommu_debug_build_phoney_sg_table(struct device *dev,
@ -2112,6 +2119,44 @@ static const struct file_operations iommu_debug_trigger_fault_fops = {
.write = iommu_debug_trigger_fault_write,
};
#ifdef CONFIG_ARM64_PTDUMP_CORE
static int ptdump_show(struct seq_file *s, void *v)
{
struct iommu_debug_device *ddev = s->private;
struct ptdump_info *info = &(ddev->pt_info);
struct mm_struct mm;
phys_addr_t phys;
info->markers = (struct addr_marker[]){
{ 0, "start" },
{ -1, NULL},
};
info->base_addr = 0;
info->mm = &mm;
if (ddev->domain) {
iommu_domain_get_attr(ddev->domain, DOMAIN_ATTR_PT_BASE_ADDR,
&(phys));
info->mm->pgd = (pgd_t *)phys_to_virt(phys);
ptdump_walk_pgd(s, info);
}
return 0;
}
static int ptdump_open(struct inode *inode, struct file *file)
{
return single_open(file, ptdump_show, inode->i_private);
}
static const struct file_operations ptdump_fops = {
.open = ptdump_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif
/*
* The following will only work for drivers that implement the generic
* device tree bindings described in
@ -2283,6 +2328,15 @@ static int iommu_debug_device_setup(struct device *dev)
goto err_rmdir;
}
#ifdef CONFIG_ARM64_PTDUMP_CORE
if (!debugfs_create_file("iommu_page_tables", 0200, dir, ddev,
&ptdump_fops)) {
pr_err_ratelimited("Couldn't create iommu/devices/%s/iommu_page_tables debugfs file\n",
dev_name(dev));
goto err_rmdir;
}
#endif
list_add(&ddev->list, &iommu_debug_devices);
return 0;