--- linux-2.6.11-rc1/Documentation/vserver/debug.txt	1970-01-01 01:00:00 +0100
+++ linux-2.6.11-rc1-vs1.9.4-rc2/Documentation/vserver/debug.txt	2005-01-15 11:27:51 +0100
@@ -0,0 +1,171 @@
+
+debug_switch:
+
+ 0   1
+
+ 1   2
+
+ 2   4
+
+ 3   8
+
+ 4  16
+
+ 5  32
+
+ 6  64
+
+ 7 128
+
+
+debug_xid:
+
+ 0   1	"alloc_vx_info(%d) = %p\n"
+	"dealloc_vx_info(%p)"
+	"loc_vx_info(%d) = %p (not available)"
+	"loc_vx_info(%d) = %p (found)"
+	"loc_vx_info(%d) = %p (new)"
+
+ 1   2	"alloc_vx_info(%d)*"
+	"loc_vx_info(%d)*"
+	"locate_vx_info(%d)"
+
+ 2   4	"get_vx_info(%p[#%d.%d])"
+	"put_vx_info(%p[#%d.%d])"
+
+ 3   8	"set_vx_info(%p[#%d.%d.%d])"
+	"clr_vx_info(%p[#%d.%d.%d])"
+	"rcu_free_vx_info(%p): uc=%d"
+
+ 4  16	"__hash_vx_info: %p[#%d]"
+	"__unhash_vx_info: %p[#%d]"
+	"__vx_dynamic_id: [#%d]"
+
+ 5  32	"vx_migrate_task(%p,%p[#%d.%d])"
+	"task_get_vx_info(%p)"
+
+ 6  64	"vx_set_init(%p[#%d],%p[#%d,%d,%d])"
+
+ 7 128	"vx_propagate_xid(%p[#%d.%d]): %d"
+
+
+debug_nid:
+
+ 0   1	"alloc_nx_info() = %p"
+	"dealloc_nx_info(%p)"
+	"loc_nx_info(%d) = %p (not available)"
+	"loc_nx_info(%d) = %p (found)"
+	"loc_nx_info(%d) = %p (new)"
+
+ 1   2	"alloc_nx_info(%d)*"
+	"loc_nx_info(%d)*"
+
+ 2   4	"get_nx_info(%p[#%d.%d])"
+	"put_nx_info(%p[#%d.%d])"
+
+ 3   8	"set_nx_info(%p[#%d.%d.%d])"
+	"clr_nx_info(%p[#%d.%d.%d])"
+	"rcu_free_nx_info(%p): uc=%d"
+
+ 4  16	"__hash_nx_info: %p[#%d]"
+	"__unhash_nx_info: %p[#%d]"
+	"__nx_dynamic_id: [#%d]"
+
+ 5  32	"nx_migrate_task(%p,%p[#%d.%d])"
+	"task_get_nx_info(%p)"
+	"create_nx_info()"
+
+ 6  64
+
+ 7 128
+
+
+debug_dlim:
+
+ 0   1	"alloc_dl_info(%p,%d) = %p"
+	"dealloc_dl_info(%p)"
+	"locate_dl_info(%p,#%d) = %p"
+
+ 1   2	"alloc_dl_info(%p,%d)*"
+
+ 2   4	"get_dl_info(%p[#%d.%d])"
+	"put_dl_info(%p[#%d.%d])"
+
+ 3   8	"rcu_free_dl_info(%p)"
+	"__hash_dl_info: %p[#%d]"
+	"__unhash_dl_info: %p[#%d]"
+
+
+ 4  16	"ALLOC (%p,#%d)%c inode (%d)"
+	"FREE  (%p,#%d)%c inode"
+
+ 5  32	"ALLOC (%p,#%d)%c %lld bytes (%d)"
+	"FREE  (%p,#%d)%c %lld bytes"
+
+ 6  64	"ADJUST: %lld,%lld on %d,%d [mult=%d]"
+
+ 7 128	"ext3_has_free_blocks(%p): free=%u, root=%u"
+	"ext3_has_free_blocks(%p): %u<%u+1, %c, %u!=%u r=%d"
+
+
+
+debug_cvirt:
+
+
+ 0   1
+
+ 1   2
+
+ 2   4	"vx_map_tgid: %p/%llx: %d -> %d"
+	"vx_rmap_tgid: %p/%llx: %d -> %d"
+
+ 3   8
+
+ 4  16
+
+ 5  32
+
+ 6  64
+
+ 7 128
+
+
+
+debug_net:
+
+
+ 0   1
+
+ 1   2
+
+ 2   4	"nx_addr_conflict(%p,%p) %d.%d,%d.%d"
+
+ 3   8	"inet_bind(%p)* %p,%p;%lx %d.%d.%d.%d"
+	"inet_bind(%p) %d.%d.%d.%d, %d.%d.%d.%d, %d.%d.%d.%d"
+
+ 4  16	"ip_route_connect(%p) %p,%p;%lx"
+
+ 5  32	"__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx"
+
+ 6  64	"sk: %p [#%d] (from %d)"
+	"sk,req: %p [#%d] (from %d)"
+	"sk,egf: %p [#%d] (from %d)"
+	"sk,egn: %p [#%d] (from %d)"
+	"tw: %p [#%d] (from %d)"
+
+ 7 128	"__sock_sendmsg: %p[%p,%p,%p;%d]:%d/%d"
+	"__sock_recvmsg: %p[%p,%p,%p;%d]:%d/%d"
+
+
+
+
+debug_limit:
+
+ n 2^n	"vx_acc_cres[%5d,%s,%2d]: %5d%s"
+	"vx_cres_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
+
+ m 2^m	"vx_acc_page[%5d,%s,%2d]: %5d%s"
+	"vx_acc_pages[%5d,%s,%2d]: %5d += %5d"
+	"vx_pages_avail[%5d,%s,%2d]: %5ld > %5d + %5d"
+
+
--- linux-2.6.11-rc1/include/linux/vserver/debug.h	1970-01-01 01:00:00 +0100
+++ linux-2.6.11-rc1-vs1.9.4-rc2/include/linux/vserver/debug.h	2005-01-15 16:52:04 +0100
@@ -0,0 +1,309 @@
+#ifndef _VX_DEBUG_H
+#define _VX_DEBUG_H
+
+
+#define VXD_CBIT(n,m)	(vx_debug_ ## n & (1 << (m)))
+#define VXD_CMIN(n,m)	(vx_debug_ ## n > (m))
+#define VXD_MASK(n,m)	(vx_debug_ ## n & (m))
+
+#define VXD_QPOS(v,p)	(((uint32_t)(v) >> ((p)*8)) & 0xFF)
+#define VXD_QUAD(v)	VXD_QPOS(v,0), VXD_QPOS(v,1),		\
+			VXD_QPOS(v,2), VXD_QPOS(v,3)
+
+#define __FUNC__	__func__
+
+
+#ifdef	CONFIG_VSERVER_DEBUG
+
+extern unsigned int vx_debug_switch;
+extern unsigned int vx_debug_xid;
+extern unsigned int vx_debug_nid;
+extern unsigned int vx_debug_net;
+extern unsigned int vx_debug_limit;
+extern unsigned int vx_debug_dlim;
+extern unsigned int vx_debug_cvirt;
+
+
+#define VX_LOGLEVEL	"vxD: "
+#define VX_WARNLEVEL	KERN_WARNING "vxW: "
+
+#define vxdprintk(c,f,x...)					\
+	do {							\
+		if (c)						\
+			printk(VX_LOGLEVEL f "\n" , ##x);	\
+	} while (0)
+
+#define vxlprintk(c,f,x...)					\
+	do {							\
+		if (c)						\
+			printk(VX_LOGLEVEL f " @%s:%d\n", x);	\
+	} while (0)
+
+#define vxfprintk(c,f,x...)					\
+	do {							\
+		if (c)						\
+			printk(VX_LOGLEVEL f " %s@%s:%d\n", x); \
+	} while (0)
+
+
+#define vxwprintk(c,f,x...)					\
+	do {							\
+		if (c)						\
+			printk(VX_WARNLEVEL f "\n" , ##x);	\
+	} while (0)
+
+
+#define vxd_path(d,m)						\
+	({ static char _buffer[PATH_MAX];			\
+	   d_path((d), (m), _buffer, sizeof(_buffer)); })
+
+#else	/* CONFIG_VSERVER_DEBUG */
+
+#define vx_debug_switch 0
+#define vx_debug_xid	0
+#define vx_debug_nid	0
+#define vx_debug_net	0
+#define vx_debug_limit	0
+#define vx_debug_dlim	0
+#define vx_debug_cvirt	0
+
+#define vxdprintk(x...) do { } while (0)
+#define vxlprintk(x...) do { } while (0)
+#define vxfprintk(x...) do { } while (0)
+#define vxwprintk(x...) do { } while (0)
+
+#define vxd_path	"<none>"
+
+#endif	/* CONFIG_VSERVER_DEBUG */
+
+
+/* history stuff */
+
+#ifdef	CONFIG_VSERVER_HISTORY
+
+
+extern unsigned volatile int vxh_active;
+
+struct _vxhe_vxi {
+	struct vx_info *ptr;
+	unsigned xid;
+	unsigned usecnt;
+	unsigned refcnt;
+};
+
+struct _vxhe_set_clr {
+	void *data;
+};
+
+struct _vxhe_loc_lookup {
+	unsigned arg;
+};
+
+enum {
+	VXH_UNUSED=0,
+	VXH_THROW_OOPS=1,
+
+	VXH_GET_VX_INFO,
+	VXH_PUT_VX_INFO,
+	VXH_SET_VX_INFO,
+	VXH_CLR_VX_INFO,
+	VXH_ALLOC_VX_INFO,
+	VXH_DEALLOC_VX_INFO,
+	VXH_HASH_VX_INFO,
+	VXH_UNHASH_VX_INFO,
+	VXH_LOC_VX_INFO,
+	VXH_LOOKUP_VX_INFO,
+};
+
+struct _vx_hist_entry {
+	void *loc;
+	unsigned short seq;
+	unsigned short type;
+	struct _vxhe_vxi vxi;
+	union {
+		struct _vxhe_set_clr sc;
+		struct _vxhe_loc_lookup ll;
+	};
+};
+
+struct _vx_hist_entry *vxh_advance(void *loc);
+
+#define	VXH_HERE()		\
+	({ __label__ here;	\
+		here:;		\
+		&&here; })
+
+
+
+static inline void __vxh_copy_vxi(struct _vx_hist_entry *entry, struct vx_info *vxi)
+{
+	entry->vxi.ptr = vxi;
+	if (vxi) {
+		entry->vxi.usecnt = atomic_read(&vxi->vx_usecnt);
+		entry->vxi.refcnt = atomic_read(&vxi->vx_refcnt);
+		entry->vxi.xid = vxi->vx_id;
+	}
+}
+
+static inline void vxh_throw_oops(void)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	entry->type = VXH_THROW_OOPS;
+	preempt_enable();
+
+	/* prevent further acquisition */
+	vxh_active = 0;
+}
+
+static inline void vxh_get_vx_info(struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->type = VXH_GET_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_put_vx_info(struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->type = VXH_PUT_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_set_vx_info(struct vx_info *vxi, void *data)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->sc.data = data;
+	entry->type = VXH_SET_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_clr_vx_info(struct vx_info *vxi, void *data)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->sc.data = data;
+	entry->type = VXH_CLR_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_alloc_vx_info(struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->type = VXH_ALLOC_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_dealloc_vx_info(struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->type = VXH_DEALLOC_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_hash_vx_info(struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->type = VXH_HASH_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_unhash_vx_info(struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->type = VXH_UNHASH_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_loc_vx_info(unsigned arg, struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->ll.arg = arg;
+	entry->type = VXH_LOC_VX_INFO;
+	preempt_enable();
+}
+
+static inline void vxh_lookup_vx_info(unsigned arg, struct vx_info *vxi)
+{
+	struct _vx_hist_entry *entry;
+
+	preempt_disable();
+	entry = vxh_advance(VXH_HERE());
+	__vxh_copy_vxi(entry, vxi);
+	entry->ll.arg = arg;
+	entry->type = VXH_LOOKUP_VX_INFO;
+	preempt_enable();
+}
+
+extern void vxh_dump_history(void);
+
+#else  /* CONFIG_VSERVER_HISTORY */
+
+#define	vxh_throw_oops()	do { } while (0)
+
+#define vxh_get_vx_info(v)	do { } while (0)
+#define vxh_put_vx_info(v)	do { } while (0)
+
+#define vxh_set_vx_info(v,d)	do { } while (0)
+#define vxh_clr_vx_info(v,d)	do { } while (0)
+
+#define vxh_alloc_vx_info(v)	do { } while (0)
+#define vxh_dealloc_vx_info(v)	do { } while (0)
+
+#define vxh_hash_vx_info(v)	do { } while (0)
+#define vxh_unhash_vx_info(v)	do { } while (0)
+
+#define vxh_loc_vx_info(a,v)	do { } while (0)
+#define vxh_lookup_vx_info(a,v) do { } while (0)
+
+#define vxh_dump_history()	do { } while (0)
+
+
+#endif /* CONFIG_VSERVER_HISTORY */
+
+
+#if	defined(CONFIG_VSERVER_DEBUG) && defined(CONFIG_DEBUG_SPINLOCK)
+#define vxd_assert_lock(l)	BUG_ON(!spin_is_locked(l))
+#else
+#define	vxd_assert_lock(l)	do { } while (0)
+#endif
+
+
+#endif /* _VX_DEBUG_H */
--- linux-2.6.11-rc1/kernel/vserver/sysctl.c	1970-01-01 01:00:00 +0100
+++ linux-2.6.11-rc1-vs1.9.4-rc2/kernel/vserver/sysctl.c	2005-01-15 11:27:52 +0100
@@ -0,0 +1,204 @@
+/*
+ *  linux/kernel/sysctl.c
+ *
+ *  Virtual Context Support
+ *
+ *  Copyright (C) 2004  Herbert Pötzl
+ *
+ *  V0.01  basic structure
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+#include <linux/sysctl.h>
+#include <linux/fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
+
+
+#define CTL_VSERVER	4242    /* unused? */
+
+enum {
+	CTL_DEBUG_SWITCH = 1,
+	CTL_DEBUG_XID,
+	CTL_DEBUG_NID,
+	CTL_DEBUG_NET,
+	CTL_DEBUG_LIMIT,
+	CTL_DEBUG_DLIM,
+	CTL_DEBUG_CVIRT,
+};
+
+
+unsigned int vx_debug_switch = 0;
+unsigned int vx_debug_xid = 0;
+unsigned int vx_debug_nid = 0;
+unsigned int vx_debug_net = 0;
+unsigned int vx_debug_limit = 0;
+unsigned int vx_debug_dlim = 0;
+unsigned int vx_debug_cvirt = 0;
+
+
+static struct ctl_table_header *vserver_table_header;
+static ctl_table vserver_table[];
+
+
+void vserver_register_sysctl(void)
+{
+	if (!vserver_table_header) {
+		vserver_table_header = register_sysctl_table(vserver_table, 1);
+	}
+
+}
+
+void vserver_unregister_sysctl(void)
+{
+	if (vserver_table_header) {
+		unregister_sysctl_table(vserver_table_header);
+		vserver_table_header = NULL;
+	}
+}
+
+
+static int proc_dodebug(ctl_table *table, int write,
+	struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
+{
+	char		tmpbuf[20], *p, c;
+	unsigned int	value;
+	size_t		left, len;
+
+	if ((*ppos && !write) || !*lenp) {
+		*lenp = 0;
+		return 0;
+	}
+
+	left = *lenp;
+
+	if (write) {
+		if (!access_ok(VERIFY_READ, buffer, left))
+			return -EFAULT;
+		p = (char *) buffer;
+		while (left && __get_user(c, p) >= 0 && isspace(c))
+			left--, p++;
+		if (!left)
+			goto done;
+
+		if (left > sizeof(tmpbuf) - 1)
+			return -EINVAL;
+		if (copy_from_user(tmpbuf, p, left))
+			return -EFAULT;
+		tmpbuf[left] = '\0';
+
+		for (p = tmpbuf, value = 0; '0' <= *p && *p <= '9'; p++, left--)
+			value = 10 * value + (*p - '0');
+		if (*p && !isspace(*p))
+			return -EINVAL;
+		while (left && isspace(*p))
+			left--, p++;
+		*(unsigned int *) table->data = value;
+	} else {
+		if (!access_ok(VERIFY_WRITE, buffer, left))
+			return -EFAULT;
+		len = sprintf(tmpbuf, "%d", *(unsigned int *) table->data);
+		if (len > left)
+			len = left;
+		if (__copy_to_user(buffer, tmpbuf, len))
+			return -EFAULT;
+		if ((left -= len) > 0) {
+			if (put_user('\n', (char *)buffer + len))
+				return -EFAULT;
+			left--;
+		}
+	}
+
+done:
+	*lenp -= left;
+	*ppos += *lenp;
+	return 0;
+}
+
+
+
+static ctl_table debug_table[] = {
+	{
+		.ctl_name	= CTL_DEBUG_SWITCH,
+		.procname	= "debug_switch",
+		.data		= &vx_debug_switch,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	},
+	{
+		.ctl_name	= CTL_DEBUG_XID,
+		.procname	= "debug_xid",
+		.data		= &vx_debug_xid,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	},
+	{
+		.ctl_name	= CTL_DEBUG_NID,
+		.procname	= "debug_nid",
+		.data		= &vx_debug_nid,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	},
+	{
+		.ctl_name	= CTL_DEBUG_NET,
+		.procname	= "debug_net",
+		.data		= &vx_debug_net,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	},
+	{
+		.ctl_name	= CTL_DEBUG_LIMIT,
+		.procname	= "debug_limit",
+		.data		= &vx_debug_limit,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	},
+	{
+		.ctl_name	= CTL_DEBUG_DLIM,
+		.procname	= "debug_dlim",
+		.data		= &vx_debug_dlim,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	},
+	{
+		.ctl_name	= CTL_DEBUG_CVIRT,
+		.procname	= "debug_cvirt",
+		.data		= &vx_debug_cvirt,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dodebug
+	},
+	{ .ctl_name = 0 }
+};
+
+static ctl_table vserver_table[] = {
+	{
+		.ctl_name	= CTL_VSERVER,
+		.procname	= "vserver",
+		.mode		= 0555,
+		.child		= debug_table
+	},
+	{ .ctl_name = 0 }
+};
+
+
+EXPORT_SYMBOL_GPL(vx_debug_switch);
+EXPORT_SYMBOL_GPL(vx_debug_xid);
+EXPORT_SYMBOL_GPL(vx_debug_nid);
+EXPORT_SYMBOL_GPL(vx_debug_net);
+EXPORT_SYMBOL_GPL(vx_debug_limit);
+EXPORT_SYMBOL_GPL(vx_debug_dlim);
+EXPORT_SYMBOL_GPL(vx_debug_cvirt);
+
--- linux-2.6.11-rc1/kernel/vserver/history.c	1970-01-01 01:00:00 +0100
+++ linux-2.6.11-rc1-vs1.9.4-rc2/kernel/vserver/history.c	2005-01-15 16:43:49 +0100
@@ -0,0 +1,172 @@
+/*
+ *  kernel/vserver/history.c
+ *
+ *  Virtual Context History Backtrace
+ *
+ *  Copyright (C) 2004-2005  Herbert Pötzl
+ *
+ *  V0.01  basic structure
+ *  V0.02  hash/unhash and trace
+ *  V0.03  preemption fixes
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ctype.h>
+
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <asm/unistd.h>
+
+#include <linux/vserver/debug.h>
+
+
+#ifdef	CONFIG_VSERVER_HISTORY
+#define VXH_SIZE	CONFIG_VSERVER_HISTORY_SIZE
+#else
+#define VXH_SIZE	64
+#endif
+
+struct _vx_history {
+	unsigned int counter;
+
+	struct _vx_hist_entry entry[VXH_SIZE+1];
+};
+
+
+DEFINE_PER_CPU(struct _vx_history, vx_history_buffer);
+
+unsigned volatile int vxh_active = 1;
+
+static atomic_t sequence = ATOMIC_INIT(0);
+
+
+/*	vxh_advance()
+
+	* requires disabled preemption				*/
+
+struct _vx_hist_entry *vxh_advance(void *loc)
+{
+	unsigned int cpu = smp_processor_id();
+	struct _vx_history *hist = &per_cpu(vx_history_buffer, cpu);
+	struct _vx_hist_entry *entry;
+	unsigned int index;
+
+	index = vxh_active ? (hist->counter++ % VXH_SIZE) : VXH_SIZE;
+	entry = &hist->entry[index];
+
+	entry->seq = atomic_inc_return(&sequence);
+	entry->loc = loc;
+	return entry;
+}
+
+
+#define VXH_LOC_FMTS	"(#%04x,*%d):%p"
+
+#define VXH_LOC_ARGS(e)	(e)->seq, cpu, (e)->loc
+
+
+#define VXH_VXI_FMTS	"%p[#%d,%d.%d]"
+
+#define VXH_VXI_ARGS(e)	(e)->vxi.ptr, 			\
+			(e)->vxi.ptr?(e)->vxi.xid:0, 	\
+			(e)->vxi.ptr?(e)->vxi.usecnt:0,	\
+			(e)->vxi.ptr?(e)->vxi.refcnt:0
+
+void	vxh_dump_entry(struct _vx_hist_entry *e, unsigned cpu)
+{
+	switch (e->type) {
+	case VXH_THROW_OOPS:
+		printk( VXH_LOC_FMTS " oops \n", VXH_LOC_ARGS(e));
+		break;
+
+	case VXH_GET_VX_INFO:
+	case VXH_PUT_VX_INFO:
+		printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
+			VXH_LOC_ARGS(e),
+			(e->type==VXH_GET_VX_INFO)?"get":"put",
+			VXH_VXI_ARGS(e));
+		break;
+
+	case VXH_SET_VX_INFO:
+	case VXH_CLR_VX_INFO:
+		printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS " @%p\n",
+			VXH_LOC_ARGS(e),
+			(e->type==VXH_SET_VX_INFO)?"set":"clr",
+			VXH_VXI_ARGS(e), e->sc.data);
+		break;
+
+	case VXH_ALLOC_VX_INFO:
+	case VXH_DEALLOC_VX_INFO:
+		printk( VXH_LOC_FMTS " %s_vx_info " VXH_VXI_FMTS "\n",
+			VXH_LOC_ARGS(e),
+			(e->type==VXH_ALLOC_VX_INFO)?"alloc":"dealloc",
+			VXH_VXI_ARGS(e));
+		break;
+
+	case VXH_HASH_VX_INFO:
+	case VXH_UNHASH_VX_INFO:
+		printk( VXH_LOC_FMTS " __%s_vx_info " VXH_VXI_FMTS "\n",
+			VXH_LOC_ARGS(e),
+			(e->type==VXH_HASH_VX_INFO)?"hash":"unhash",
+			VXH_VXI_ARGS(e));
+		break;
+
+	case VXH_LOC_VX_INFO:
+	case VXH_LOOKUP_VX_INFO:
+		printk( VXH_LOC_FMTS " __%s_vx_info [#%d] -> " VXH_VXI_FMTS "\n",
+			VXH_LOC_ARGS(e),
+			(e->type==VXH_LOC_VX_INFO)?"loc":"lookup",
+			e->ll.arg, VXH_VXI_ARGS(e));
+		break;
+	}
+}
+
+static void __vxh_dump_history(void)
+{
+	unsigned int i,j;
+
+	printk("History:\tSEQ: %8x\tNR_CPUS: %d\n",
+		atomic_read(&sequence), NR_CPUS);
+
+	for (i=0; i < VXH_SIZE; i++) {
+		for (j=0; j < NR_CPUS; j++) {
+			struct _vx_history *hist =
+				&per_cpu(vx_history_buffer, j);
+			unsigned int index = (hist->counter-i) % VXH_SIZE;
+			struct _vx_hist_entry *entry = &hist->entry[index];
+
+			vxh_dump_entry(entry, j);
+		}
+	}
+}
+
+void	vxh_dump_history(void)
+{
+	vxh_active = 0;
+#ifdef CONFIG_SMP
+	local_irq_enable();
+	smp_send_stop();
+	local_irq_disable();
+#endif
+	__vxh_dump_history();
+}
+
+
+/* vserver syscall commands below here */
+
+
+int 	vc_dump_history(uint32_t id)
+{
+	vxh_active = 0;
+	__vxh_dump_history();
+	vxh_active = 1;
+
+	return 0;
+}
+
+EXPORT_SYMBOL_GPL(vxh_advance);
+
