lguest: dump hypercall counts on /dev/lguest close

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 drivers/lguest/hypercalls.c  |    3 +++
 drivers/lguest/lg.h          |    2 ++
 drivers/lguest/lguest_user.c |    3 +++
 3 files changed, 8 insertions(+)

diff --git a/drivers/lguest/hypercalls.c b/drivers/lguest/hypercalls.c
--- a/drivers/lguest/hypercalls.c
+++ b/drivers/lguest/hypercalls.c
@@ -24,6 +24,7 @@
 #include <linux/syscalls.h>
 #include <linux/mm.h>
 #include <linux/ktime.h>
+#include <linux/kernel.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include "lg.h"
@@ -232,6 +233,8 @@ void do_hypercalls(struct lg_cpu *cpu)
 	 * NOTIFY to the Launcher, we want to return now.  Otherwise we do
 	 * the hypercall. */
 	if (!cpu->pending_notify) {
+		if (cpu->hcall->arg0 < ARRAY_SIZE(cpu->lg->hcall_stats))
+			cpu->lg->hcall_stats[cpu->hcall->arg0]++;
 		do_hcall(cpu, cpu->hcall);
 		/* Tricky point: we reset the hcall pointer to mark the
 		 * hypercall as "done".  We use the hcall pointer rather than
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -110,6 +110,8 @@ struct lguest
 	unsigned int num_eventfds;
 	struct lg_eventfds *eventfds;
 
+	unsigned long hcall_stats[20];
+
 	/* Dead? */
 	const char *dead;
 };
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -373,6 +373,9 @@ static int close(struct inode *inode, st
 	for (i = 0; i < lg->num_eventfds; i++)
 		fput(lg->eventfds[i].event);
 
+	for (i = 0; i < ARRAY_SIZE(lg->hcall_stats); i++)
+		printk(KERN_DEBUG "hcall %u = %lu\n", i, lg->hcall_stats[i]);
+
 	/* If lg->dead doesn't contain an error code it will be NULL or a
 	 * kmalloc()ed string, either of which is ok to hand to kfree(). */
 	if (!IS_ERR(lg->dead))
