arm: VFP: Report bounce statistics using procfs
Report VFP instruction bounce statistics in procfs to aid
in detecting userspace applications that use deprecated VFP
instructions.
Change-Id: Id32387cc6ced399ef6be9c827a9b9c7d52e83e77
Signed-off-by: Stepan Moskovchenko <stepanm@codeaurora.org>
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 4387287..e62af21 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/uaccess.h>
#include <linux/user.h>
+#include <linux/proc_fs.h>
#include <asm/cp15.h>
#include <asm/cputype.h>
@@ -87,6 +88,11 @@
}
/*
+ * Used for reporting emulation statistics via /proc
+ */
+static atomic64_t vfp_bounce_count = ATOMIC64_INIT(0);
+
+/*
* Per-thread VFP initialization.
*/
static void vfp_thread_flush(struct thread_info *thread)
@@ -337,6 +343,7 @@
u32 fpscr, orig_fpscr, fpsid, exceptions;
pr_debug("VFP: bounce: trigger %08x fpexc %08x\n", trigger, fpexc);
+ atomic64_inc(&vfp_bounce_count);
/*
* At this point, FPEXC can have the following configuration:
@@ -648,6 +655,26 @@
return NOTIFY_OK;
}
+#ifdef CONFIG_PROC_FS
+static int proc_read_status(char *page, char **start, off_t off, int count,
+ int *eof, void *data)
+{
+ char *p = page;
+ int len;
+
+ p += snprintf(p, PAGE_SIZE, "%llu\n", atomic64_read(&vfp_bounce_count));
+
+ len = (p - page) - off;
+ if (len < 0)
+ len = 0;
+
+ *eof = (len <= count) ? 1 : 0;
+ *start = page + off;
+
+ return len;
+}
+#endif
+
/*
* VFP support code initialisation.
*/
@@ -655,7 +682,9 @@
{
unsigned int vfpsid;
unsigned int cpu_arch = cpu_architecture();
-
+#ifdef CONFIG_PROC_FS
+ static struct proc_dir_entry *procfs_entry;
+#endif
if (cpu_arch >= CPU_ARCH_ARMv6)
on_each_cpu(vfp_enable, NULL, 1);
@@ -724,6 +753,16 @@
elf_hwcap |= HWCAP_VFPv4;
}
}
+
+#ifdef CONFIG_PROC_FS
+ procfs_entry = create_proc_entry("cpu/vfp_bounce", S_IRUGO, NULL);
+
+ if (procfs_entry)
+ procfs_entry->read_proc = proc_read_status;
+ else
+ pr_err("Failed to create procfs node for VFP bounce reporting\n");
+#endif
+
return 0;
}