summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiro Sugawara <hsugawara@nvidia.com>2011-08-25 17:00:12 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-09-27 12:01:32 -0700
commit467186f51c815c11b0672225dbda195931e2a01e (patch)
tree3bf784235da8ffd48230b23bd8b8dd9cff40537e
parent951a36e8e22f4bd96bc8aa27a5742e15942a9c68 (diff)
arm: tegra: smmu: Add a sysfs entry for enabling page map signature
For debugging and sanity checking, IOVA and PA are returned in each mapped page if PID matches what is set by the sysfs entry. Reviewed-on: http://git-master/r/49716 (cherry picked from commit 53e7058b8c021ad868beba6d522afd61f8b9315c) Change-Id: Ia289eeb743370366fe37b54678a7c1a657163491 Reviewed-on: http://git-master/r/54515 Tested-by: Hiro Sugawara <hsugawara@nvidia.com> Reviewed-by: Dan Willemsen <dwillemsen@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/iovmm-smmu.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/arch/arm/mach-tegra/iovmm-smmu.c b/arch/arm/mach-tegra/iovmm-smmu.c
index 021906b99bfb..ceb9a5ad803e 100644
--- a/arch/arm/mach-tegra/iovmm-smmu.c
+++ b/arch/arm/mach-tegra/iovmm-smmu.c
@@ -30,6 +30,7 @@
#include <linux/pagemap.h>
#include <linux/sysfs.h>
#include <linux/device.h>
+#include <linux/sched.h>
#include <asm/io.h>
#include <asm/cacheflush.h>
#include <asm/page.h>
@@ -329,6 +330,7 @@ struct smmu_device {
unsigned long lowest_asid; /* Variables for hardware testing */
unsigned long debug_asid;
unsigned long verbose;
+ unsigned long signature_pid; /* For debugging aid */
};
#define VA_PAGE_TO_PA(va, page) \
@@ -583,6 +585,21 @@ static smmu_pte_t *locate_pte(struct smmu_as *as,
return &ptbl[ptn % SMMU_PTBL_COUNT];
}
+static void put_signature(struct smmu_as *as,
+ unsigned long addr, unsigned long pfn)
+{
+ if (as->smmu->signature_pid == current->pid) {
+ struct page *page = pfn_to_page(pfn);
+ unsigned long *vaddr = kmap(page);
+ if (vaddr) {
+ vaddr[0] = addr;
+ vaddr[1] = pfn << PAGE_SHIFT;
+ FLUSH_CPU_DCACHE(vaddr, page, sizeof(vaddr[0]) * 2);
+ kunmap(page);
+ }
+ }
+}
+
static int smmu_map(struct tegra_iovmm_domain *domain,
struct tegra_iovmm_area *iovma)
{
@@ -624,6 +641,7 @@ static int smmu_map(struct tegra_iovmm_domain *domain,
flush_ptc_and_tlb(as->smmu, as, addr, pte, ptpage, 0);
kunmap(ptpage);
up(&as->sem);
+ put_signature(as, addr, pfn);
addr += SMMU_PAGE_SIZE;
}
return 0;
@@ -719,6 +737,7 @@ static void smmu_map_pfn(struct tegra_iovmm_domain *domain,
FLUSH_CPU_DCACHE(pte, ptpage, sizeof *pte);
flush_ptc_and_tlb(smmu, as, addr, pte, ptpage, 0);
kunmap(ptpage);
+ put_signature(as, addr, pfn);
}
up(&as->sem);
}
@@ -1211,11 +1230,10 @@ static ssize_t _sysfs_show_##name(struct device *d, \
return rv; \
}
-#ifdef CONFIG_TEGRA_SMMU_SYSFS
static void (*_sysfs_null_callback)(struct smmu_device *, unsigned long *) =
NULL;
-#define _SYSFS_SET_VALUE(name, field, base, ceil, callback) \
+#define _SYSFS_SET_VALUE_DO(name, field, base, ceil, callback) \
static ssize_t _sysfs_set_##name(struct device *d, \
struct device_attribute *da, const char *buf, size_t count) \
{ \
@@ -1229,6 +1247,8 @@ static ssize_t _sysfs_set_##name(struct device *d, \
} \
return count; \
}
+#ifdef CONFIG_TEGRA_SMMU_SYSFS
+#define _SYSFS_SET_VALUE _SYSFS_SET_VALUE_DO
#else
#define _SYSFS_SET_VALUE(name, field, base, ceil, callback) \
static ssize_t _sysfs_set_##name(struct device *d, \
@@ -1246,6 +1266,9 @@ _SYSFS_SET_VALUE(debug_asid, debug_asid, 10,
MC_SMMU_NUM_ASIDS, _sysfs_null_callback)
_SYSFS_SHOW_VALUE(verbose, verbose, "%lu")
_SYSFS_SET_VALUE(verbose, verbose, 10, 3, _sysfs_null_callback)
+_SYSFS_SHOW_VALUE(signature_pid, signature_pid, "%lu")
+_SYSFS_SET_VALUE_DO(signature_pid, signature_pid, 10, PID_MAX_LIMIT+1,
+ _sysfs_null_callback)
#ifdef CONFIG_TEGRA_SMMU_SYSFS
static void _sysfs_mask_attr(struct smmu_device *smmu, unsigned long *field)
@@ -1291,6 +1314,8 @@ static struct device_attribute _attr_values[] = {
_sysfs_show_debug_asid, _sysfs_set_debug_asid),
__ATTR(verbose, S_IRUGO|S_IWUSR,
_sysfs_show_verbose, _sysfs_set_verbose),
+ __ATTR(signature_pid, S_IRUGO|S_IWUSR,
+ _sysfs_show_signature_pid, _sysfs_set_signature_pid),
__ATTR(pdir_attr, S_IRUGO|S_IWUSR,
_sysfs_show_pdir_attr, _sysfs_set_pdir_attr),