aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndres Lagar-Cavilla <andres@lagarcavilla.org>2012-01-27 18:23:42 +0000
committerAndres Lagar-Cavilla <andres@lagarcavilla.org>2012-01-27 18:23:42 +0000
commit1da3983b7db55f506d0764888aabf8001736f98f (patch)
tree6b87ffd1d85c4b7372a554d7480adbbaafdbfe14
parent0d655213015bd839f63f0d527e39318cf8ee713f (diff)
downloadxen-1da3983b7db55f506d0764888aabf8001736f98f.tar.gz
xen-1da3983b7db55f506d0764888aabf8001736f98f.tar.bz2
xen-1da3983b7db55f506d0764888aabf8001736f98f.zip
tools: memshrtool: tool to test and exercise the sharing subsystem
This is demo code meant to showcase how to perform sharing operations. It is useful for testing. [ Added appropriate lines to .hgignore and .gitignore -iwj ] Signed-off-by: Adin Scannell <adin@scannell.ca> Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org> Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com> Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
-rw-r--r--.gitignore1
-rw-r--r--.hgignore1
-rw-r--r--tools/tests/mem-sharing/Makefile26
-rw-r--r--tools/tests/mem-sharing/memshrtool.c165
4 files changed, 193 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 18f4ce5065..13d3e94b31 100644
--- a/.gitignore
+++ b/.gitignore
@@ -210,6 +210,7 @@ tools/tests/x86_emulate
tools/tests/regression/installed/*
tools/tests/regression/build/*
tools/tests/regression/downloads/*
+tools/tests/mem-sharing/memshrtool
tools/vnet/Make.local
tools/vnet/build/*
tools/vnet/gc
diff --git a/.hgignore b/.hgignore
index 9d9264ad09..fd6cfaade0 100644
--- a/.hgignore
+++ b/.hgignore
@@ -221,6 +221,7 @@
^tools/tests/regression/build/.*$
^tools/tests/regression/downloads/.*$
^tools/tests/xen-access/xen-access$
+^tools/tests/mem-sharing/memshrtool$
^tools/vnet/Make.local$
^tools/vnet/build/.*$
^tools/vnet/gc$
diff --git a/tools/tests/mem-sharing/Makefile b/tools/tests/mem-sharing/Makefile
new file mode 100644
index 0000000000..135450291f
--- /dev/null
+++ b/tools/tests/mem-sharing/Makefile
@@ -0,0 +1,26 @@
+XEN_ROOT=$(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+CFLAGS += -Werror
+
+CFLAGS += $(CFLAGS_libxenctrl)
+CFLAGS += $(CFLAGS_xeninclude)
+
+TARGETS-y :=
+TARGETS-$(CONFIG_X86) += memshrtool
+TARGETS := $(TARGETS-y)
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build: $(TARGETS)
+
+.PHONY: clean
+clean:
+ $(RM) *.o $(TARGETS) *~ $(DEPS)
+
+memshrtool: memshrtool.o
+ $(CC) -o $@ $< $(LDFLAGS) $(LDLIBS_libxenctrl)
+
+-include $(DEPS)
diff --git a/tools/tests/mem-sharing/memshrtool.c b/tools/tests/mem-sharing/memshrtool.c
new file mode 100644
index 0000000000..b876619ac9
--- /dev/null
+++ b/tools/tests/mem-sharing/memshrtool.c
@@ -0,0 +1,165 @@
+/*
+ * memshrtool.c
+ *
+ * Copyright 2011 GridCentric Inc. (Adin Scannell, Andres Lagar-Cavilla)
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "xenctrl.h"
+
+static int usage(const char* prog)
+{
+ printf("usage: %s <command> [args...]\n", prog);
+ printf("where <command> may be:\n");
+ printf(" info - Display total sharing info.\n");
+ printf(" enable - Enable sharing on a domain.\n");
+ printf(" disable - Disable sharing on a domain.\n");
+ printf(" nominate <domid> <gfn> - Nominate a page for sharing.\n");
+ printf(" share <domid> <gfn> <handle> <source> <source-gfn> <source-handle>\n");
+ printf(" - Share two pages.\n");
+ printf(" unshare <domid> <gfn> - Unshare a page by grabbing a writable map.\n");
+ printf(" add-to-physmap <domid> <gfn> <source> <source-gfn> <source-handle>\n");
+ printf(" - Populate a page in a domain with a shared page.\n");
+ printf(" debug-gfn <domid> <gfn> - Debug a particular domain and gfn.\n");
+ return 1;
+}
+
+#define R(f) do { \
+ int rc = f; \
+ if ( rc < 0 ) { \
+ printf("error executing %s: %s\n", #f, \
+ ((errno * -1) == XEN_DOMCTL_MEM_SHARING_C_HANDLE_INVALID) ? \
+ "problem with client handle" :\
+ ((errno * -1) == XEN_DOMCTL_MEM_SHARING_S_HANDLE_INVALID) ? \
+ "problem with source handle" : strerror(errno)); \
+ return rc; \
+ } \
+} while(0)
+
+int main(int argc, const char** argv)
+{
+ const char* cmd = NULL;
+ xc_interface *xch = xc_interface_open(0, 0, 0);
+
+ if( argc < 2 )
+ return usage(argv[0]);
+
+ cmd = argv[1];
+
+ if( !strcasecmp(cmd, "info") )
+ {
+ if( argc != 2 )
+ return usage(argv[0]);
+
+ printf("used = %ld\n", xc_sharing_used_frames(xch));
+ printf("freed = %ld\n", xc_sharing_freed_pages(xch));
+ }
+ else if( !strcasecmp(cmd, "enable") )
+ {
+ domid_t domid;
+
+ if( argc != 3 )
+ return usage(argv[0]);
+
+ domid = strtol(argv[2], NULL, 0);
+ R(xc_memshr_control(xch, domid, 1));
+ }
+ else if( !strcasecmp(cmd, "disable") )
+ {
+ domid_t domid;
+
+ if( argc != 3 )
+ return usage(argv[0]);
+
+ domid = strtol(argv[2], NULL, 0);
+ R(xc_memshr_control(xch, domid, 0));
+ }
+ else if( !strcasecmp(cmd, "nominate") )
+ {
+ domid_t domid;
+ unsigned long gfn;
+ uint64_t handle;
+
+ if( argc != 4 )
+ return usage(argv[0]);
+
+ domid = strtol(argv[2], NULL, 0);
+ gfn = strtol(argv[3], NULL, 0);
+ R(xc_memshr_nominate_gfn(xch, domid, gfn, &handle));
+ printf("handle = 0x%08llx\n", (unsigned long long) handle);
+ }
+ else if( !strcasecmp(cmd, "share") )
+ {
+ domid_t domid;
+ unsigned long gfn;
+ uint64_t handle;
+ domid_t source_domid;
+ unsigned long source_gfn;
+ uint64_t source_handle;
+
+ if( argc != 8 )
+ return usage(argv[0]);
+
+ domid = strtol(argv[2], NULL, 0);
+ gfn = strtol(argv[3], NULL, 0);
+ handle = strtol(argv[4], NULL, 0);
+ source_domid = strtol(argv[5], NULL, 0);
+ source_gfn = strtol(argv[6], NULL, 0);
+ source_handle = strtol(argv[7], NULL, 0);
+ R(xc_memshr_share_gfns(xch, source_domid, source_gfn, source_handle, domid, gfn, handle));
+ }
+ else if( !strcasecmp(cmd, "unshare") )
+ {
+ domid_t domid;
+ unsigned long gfn;
+ void *map;
+
+ if( argc != 4 )
+ return usage(argv[0]);
+
+ domid = strtol(argv[2], NULL, 0);
+ gfn = strtol(argv[3], NULL, 0);
+ map = xc_map_foreign_range(xch, domid, 4096, PROT_WRITE, gfn);
+ if( map )
+ munmap(map, 4096);
+ R((int)!map);
+ }
+ else if( !strcasecmp(cmd, "add-to-physmap") )
+ {
+ domid_t domid;
+ unsigned long gfn;
+ domid_t source_domid;
+ unsigned long source_gfn;
+ uint64_t source_handle;
+
+ if( argc != 7 )
+ return usage(argv[0]);
+
+ domid = strtol(argv[2], NULL, 0);
+ gfn = strtol(argv[3], NULL, 0);
+ source_domid = strtol(argv[4], NULL, 0);
+ source_gfn = strtol(argv[5], NULL, 0);
+ source_handle = strtol(argv[6], NULL, 0);
+ R(xc_memshr_add_to_physmap(xch, source_domid, source_gfn, source_handle, domid, gfn));
+ }
+ else if( !strcasecmp(cmd, "debug-gfn") )
+ {
+ domid_t domid;
+ unsigned long gfn;
+
+ if( argc != 4 )
+ return usage(argv[0]);
+
+ domid = strtol(argv[2], NULL, 0);
+ gfn = strtol(argv[3], NULL, 0);
+ R(xc_memshr_debug_gfn(xch, domid, gfn));
+ }
+
+ return 0;
+}