]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/xen.git/commitdiff
tools: Refactor hypercall calling wrappers into libxencall.
authorIan Campbell <ian.campbell@citrix.com>
Mon, 1 Jun 2015 15:20:09 +0000 (16:20 +0100)
committerIan Campbell <ian.campbell@citrix.com>
Fri, 22 Jan 2016 12:23:30 +0000 (12:23 +0000)
libxencall will provide a stable API and ABI for calling hypercalls
(although those hypercalls themselves may not have a stable API). As
well as the hypercall buffer infrastructure needed in order to safely
provide pointer arguments to hypercalls.

libxenctrl encapsulates a instance of this interface, so users of that
library are not currently subjected to any actual changes. However all
hypercalls made internally by libxc now use the correct interface. It
is expected that most users of this library will be other libraries
providing a higher level interface, rather than applications directly.

Only the basic functionality to allocate hypercall safe memory is
moved, the type safe stuff and bounce buffers remain in libxc.

Note that the functionality to map foreign pages using privcmd is not
yet moved, meaning that an xc_interface will now contain two open
privcmd file descriptors. Foreign memory mapping is logically separate
functionality and will be moved into its own library.

The new library uses a version script to ensure that only expected
symbols are exported and to version them such that ABI guarantees can
be kept in the future.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Wei Liu <wei.liu2@citrix.com>
[ ijc -- updated MINIOS_UPSTREAM_REVISION and QEMU_TRADITIONAL_REVISION ]

37 files changed:
.gitignore
Config.mk
stubdom/Makefile
tools/Makefile
tools/Rules.mk
tools/libs/Makefile
tools/libs/call/Makefile [new file with mode: 0644]
tools/libs/call/buffer.c [new file with mode: 0644]
tools/libs/call/core.c [new file with mode: 0644]
tools/libs/call/freebsd.c [new file with mode: 0644]
tools/libs/call/include/xencall.h [new file with mode: 0644]
tools/libs/call/libxencall.map [new file with mode: 0644]
tools/libs/call/linux.c [new file with mode: 0644]
tools/libs/call/minios.c [new file with mode: 0644]
tools/libs/call/netbsd.c [new file with mode: 0644]
tools/libs/call/private.h [new file with mode: 0644]
tools/libs/call/solaris.c [new file with mode: 0644]
tools/libxc/Makefile
tools/libxc/xc_altp2m.c
tools/libxc/xc_domain.c
tools/libxc/xc_evtchn.c
tools/libxc/xc_flask.c
tools/libxc/xc_freebsd_osdep.c
tools/libxc/xc_gnttab.c
tools/libxc/xc_hcall_buf.c
tools/libxc/xc_kexec.c
tools/libxc/xc_linux_osdep.c
tools/libxc/xc_minios.c
tools/libxc/xc_misc.c
tools/libxc/xc_netbsd.c
tools/libxc/xc_private.c
tools/libxc/xc_private.h
tools/libxc/xc_solaris.c
tools/libxc/xc_tmem.c
tools/misc/Makefile
tools/xcutils/Makefile
tools/xenpaging/Makefile

index ea75fdae81be1c5245c7867cd954ede9e5d48745..6272f6b4b2bda505dd9c6832b63120219a29e7ce 100644 (file)
@@ -62,6 +62,7 @@ stubdom/ioemu
 stubdom/ioemu/
 stubdom/libs-*
 stubdom/libxc-*
+stubdom/libxencall-*
 stubdom/libxenevtchn-*
 stubdom/libxengnttab-*
 stubdom/libxentoollog-*
@@ -91,6 +92,7 @@ config/Docs.mk
 tools/libs/toollog/headers.chk
 tools/libs/evtchn/headers.chk
 tools/libs/gnttab/headers.chk
+tools/libs/call/headers.chk
 tools/blktap2/daemon/blktapctrl
 tools/blktap2/drivers/img2qcow
 tools/blktap2/drivers/lock-util
index d2f22a32df8c789c6290b32fd95cf64bfe7a6e5b..174c192c9bfb1325786688a7f6e39b459005fc50 100644 (file)
--- a/Config.mk
+++ b/Config.mk
@@ -251,9 +251,9 @@ MINIOS_UPSTREAM_URL ?= git://xenbits.xen.org/mini-os.git
 endif
 OVMF_UPSTREAM_REVISION ?= 52a99493cce88a9d4ec8a02d7f1bd1a1001ce60d
 QEMU_UPSTREAM_REVISION ?= master
-MINIOS_UPSTREAM_REVISION ?= 9faa4c3b862291315912b81fe1d4ccca800f530d
-# Fri Jan 15 13:24:01 2016 +0000
-# mini-os: Include libxengnttab with libxc
+MINIOS_UPSTREAM_REVISION ?= c7d4f84e52d901068f9c7d5cd2cc05ced93c0157
+# Fri Jan 15 13:24:02 2016 +0000
+# mini-os: Include libxencall with libxc
 
 SEABIOS_UPSTREAM_REVISION ?= 3403ac4313812752be6e6aac35239ca6888a8cab
 # Mon Dec 28 13:50:41 2015 +0100
@@ -262,9 +262,9 @@ SEABIOS_UPSTREAM_REVISION ?= 3403ac4313812752be6e6aac35239ca6888a8cab
 ETHERBOOT_NICS ?= rtl8139 8086100e
 
 
-QEMU_TRADITIONAL_REVISION ?= d8b5666074fdbc4ddba5283d70898a2edd785028
-# Fri Jan 15 13:23:54 2016 +0000
-# qemu-xen-traditional: Use libxengnttab
+QEMU_TRADITIONAL_REVISION ?= 79ed2c5733742a7b00f9c774bece30a620150a30
+# Fri Jan 15 13:23:55 2016 +0000
+# qemu-xen-traditional: Add libxencall to rpath-link
 
 # Specify which qemu-dm to use. This may be `ioemu' to use the old
 # Mercurial in-tree version, or a local directory, or a git URL.
index 2dbf4a86882f20bb6031c1968f8e2640baad2883..5bf4ed6a544ab423e84bb9122632fbc9afbeea82 100644 (file)
@@ -331,6 +331,12 @@ mk-headers-$(XEN_TARGET_ARCH): $(IOEMU_LINKFARM_TARGET)
          ln -sf $(XEN_ROOT)/tools/libs/gnttab/include/*.h include/ && \
          ln -sf $(XEN_ROOT)/tools/libs/gnttab/*.c . && \
          ln -sf $(XEN_ROOT)/tools/libs/gnttab/Makefile . )
+       mkdir -p libs-$(XEN_TARGET_ARCH)/call/include
+       [ -h libs-$(XEN_TARGET_ARCH)/call/Makefile ] || ( cd libs-$(XEN_TARGET_ARCH)/call && \
+         ln -sf $(XEN_ROOT)/tools/libs/call/*.h . && \
+         ln -sf $(XEN_ROOT)/tools/libs/call/include/*.h include/ && \
+         ln -sf $(XEN_ROOT)/tools/libs/call/*.c . && \
+         ln -sf $(XEN_ROOT)/tools/libs/call/Makefile . )
        mkdir -p libxc-$(XEN_TARGET_ARCH)
        [ -h libxc-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxc-$(XEN_TARGET_ARCH) && \
          ln -sf $(XEN_ROOT)/tools/libxc/*.h . && \
@@ -380,13 +386,22 @@ libxengnttab: libs-$(XEN_TARGET_ARCH)/gnttab/libxengnttab.a
 libs-$(XEN_TARGET_ARCH)/gnttab/libxengnttab.a: mk-headers-$(XEN_TARGET_ARCH) $(NEWLIB_STAMPFILE)
        CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libs-$(XEN_TARGET_ARCH)/gnttab
 
+#######
+# libxencall
+#######
+
+.PHONY: libxencall
+libxencall: libs-$(XEN_TARGET_ARCH)/call/libxencall.a
+libs-$(XEN_TARGET_ARCH)/call/libxencall.a: mk-headers-$(XEN_TARGET_ARCH) $(NEWLIB_STAMPFILE)
+       CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libs-$(XEN_TARGET_ARCH)/call
+
 #######
 # libxc
 #######
 
 .PHONY: libxc
 libxc: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a libxc-$(XEN_TARGET_ARCH)/libxenguest.a
-libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: mk-headers-$(XEN_TARGET_ARCH) libxentoollog libxenevtchn libxengnttab cross-zlib
+libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: mk-headers-$(XEN_TARGET_ARCH) libxentoollog libxenevtchn libxengnttab libxencall cross-zlib
        CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= CONFIG_LIBXC_MINIOS=y -C libxc-$(XEN_TARGET_ARCH)
 
  libxc-$(XEN_TARGET_ARCH)/libxenguest.a: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a
index 50ccc758fb11b902aa8d15fbc273ec696d6893d3..05d8bdb26472eb8277e863e31ed1a5ea5a8dd48e 100644 (file)
@@ -264,6 +264,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find
                -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/toollog \
                -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/evtchn \
                -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/gnttab \
+               -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/call \
                $(QEMU_UPSTREAM_RPATH)" \
                --bindir=$(LIBEXEC_BIN) \
                --datadir=$(SHAREDIR)/qemu-xen \
index 379990f5dc6087804d86671a31d19ce4185c1f04..18e3688f932b69f6728273475015e4b3b897fd59 100644 (file)
@@ -13,6 +13,7 @@ XEN_INCLUDE        = $(XEN_ROOT)/tools/include
 XEN_LIBXENTOOLLOG  = $(XEN_ROOT)/tools/libs/toollog
 XEN_LIBXENEVTCHN   = $(XEN_ROOT)/tools/libs/evtchn
 XEN_LIBXENGNTTAB   = $(XEN_ROOT)/tools/libs/gnttab
+XEN_LIBXENCALL     = $(XEN_ROOT)/tools/libs/call
 XEN_LIBXC          = $(XEN_ROOT)/tools/libxc
 XEN_XENLIGHT       = $(XEN_ROOT)/tools/libxl
 XEN_XENSTORE       = $(XEN_ROOT)/tools/xenstore
@@ -98,8 +99,12 @@ CFLAGS_libxengntshr = -I$(XEN_LIBXENGNTTAB)/include $(CFLAGS_xeninclude)
 LDLIBS_libxengntshr = $(XEN_LIBXENGNTTAB)/libxengnttab$(libextension)
 SHLIB_libxengntshr  = -Wl,-rpath-link=$(XEN_LIBXENGNTTAB)
 
+CFLAGS_libxencall = -I$(XEN_LIBXENCALL)/include $(CFLAGS_xeninclude)
+LDLIBS_libxencall = $(XEN_LIBXENCALL)/libxencall$(libextension)
+SHLIB_libxencall  = -Wl,-rpath-link=$(XEN_LIBXENCALL)
+
 CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_xeninclude)
-SHDEPS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) $(SHLIB_libxengnttab) $(SHLIB_libxengntshr)
+SHDEPS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) $(SHLIB_libxengnttab) $(SHLIB_libxengntshr) $(SHLIB_libxencall)
 LDLIBS_libxenctrl = $(SHDEPS_libxenctrl) $(XEN_LIBXC)/libxenctrl$(libextension)
 SHLIB_libxenctrl  = $(SHDEPS_libxenctrl) -Wl,-rpath-link=$(XEN_LIBXC)
 
index 00156ae1a0019d28915203ab35602382beef3bef..f4f5d57035a9d848c9efff3ed427892de8ba474b 100644 (file)
@@ -5,5 +5,6 @@ SUBDIRS-y :=
 SUBDIRS-y += toollog
 SUBDIRS-y += evtchn
 SUBDIRS-y += gnttab
+SUBDIRS-y += call
 
 all clean install distclean: %: subdirs-%
diff --git a/tools/libs/call/Makefile b/tools/libs/call/Makefile
new file mode 100644 (file)
index 0000000..9402ea5
--- /dev/null
@@ -0,0 +1,71 @@
+XEN_ROOT = $(CURDIR)/../../..
+include $(XEN_ROOT)/tools/Rules.mk
+
+MAJOR    = 1
+MINOR    = 0
+SHLIB_LDFLAGS += -Wl,--version-script=libxencall.map
+
+CFLAGS   += -Werror -Wmissing-prototypes
+CFLAGS   += -I./include $(CFLAGS_xeninclude)
+CFLAGS   += $(CFLAGS_libxentoollog)
+
+SRCS-y                 += core.c buffer.c
+SRCS-$(CONFIG_Linux)   += linux.c
+SRCS-$(CONFIG_FreeBSD) += freebsd.c
+SRCS-$(CONFIG_SunOS)   += solaris.c
+SRCS-$(CONFIG_NetBSD)  += netbsd.c
+SRCS-$(CONFIG_MiniOS)  += minios.c
+
+LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y))
+PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y))
+
+LIB := libxencall.a
+ifneq ($(nosharedlibs),y)
+LIB += libxencall.so
+endif
+
+.PHONY: all
+all: build
+
+.PHONY: build
+build:
+       $(MAKE) libs
+
+.PHONY: libs
+libs: headers.chk $(LIB)
+
+headers.chk: $(wildcard include/*.h)
+
+libxencall.a: $(LIB_OBJS)
+       $(AR) rc $@ $^
+
+libxencall.so: libxencall.so.$(MAJOR)
+       $(SYMLINK_SHLIB) $< $@
+libxencall.so.$(MAJOR): libxencall.so.$(MAJOR).$(MINOR)
+       $(SYMLINK_SHLIB) $< $@
+
+libxencall.so.$(MAJOR).$(MINOR): $(PIC_OBJS) libxencall.map
+       $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxencall.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $(PIC_OBJS) $(LDLIBS_libxentoollog) $(APPEND_LDFLAGS)
+
+.PHONY: install
+install: build
+       $(INSTALL_DIR) $(DESTDIR)$(libdir)
+       $(INSTALL_DIR) $(DESTDIR)$(includedir)
+       $(INSTALL_SHLIB) libxencall.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)
+       $(INSTALL_DATA) libxencall.a $(DESTDIR)$(libdir)
+       $(SYMLINK_SHLIB) libxencall.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxencall.so.$(MAJOR)
+       $(SYMLINK_SHLIB) libxencall.so.$(MAJOR) $(DESTDIR)$(libdir)/libxencall.so
+       $(INSTALL_DATA) include/xencall.h $(DESTDIR)$(includedir)
+
+.PHONY: TAGS
+TAGS:
+       etags -t *.c *.h
+
+.PHONY: clean
+clean:
+       rm -rf *.rpm $(LIB) *~ $(DEPS) $(LIB_OBJS) $(PIC_OBJS)
+       rm -f libxencall.so.$(MAJOR).$(MINOR) libxencall.so.$(MAJOR)
+       rm -f headers.chk
+
+.PHONY: distclean
+distclean: clean
diff --git a/tools/libs/call/buffer.c b/tools/libs/call/buffer.c
new file mode 100644 (file)
index 0000000..1a1b27a
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <pthread.h>
+
+#include "private.h"
+
+#define DBGPRINTF(_m...) \
+       xtl_log(xcall->logger, XTL_DEBUG, -1, "xencall:buffer", _m)
+
+#define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1))
+
+pthread_mutex_t cache_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static void cache_lock(xencall_handle *xcall)
+{
+    int saved_errno = errno;
+    if ( xcall->flags & XENCALL_OPENFLAG_NON_REENTRANT )
+        return;
+    pthread_mutex_lock(&cache_mutex);
+    /* Ignore pthread errors. */
+    errno = saved_errno;
+}
+
+static void cache_unlock(xencall_handle *xcall)
+{
+    int saved_errno = errno;
+    if ( xcall->flags & XENCALL_OPENFLAG_NON_REENTRANT )
+        return;
+    pthread_mutex_unlock(&cache_mutex);
+    /* Ignore pthread errors. */
+    errno = saved_errno;
+}
+
+static void *cache_alloc(xencall_handle *xcall, size_t nr_pages)
+{
+    void *p = NULL;
+
+    cache_lock(xcall);
+
+    xcall->buffer_total_allocations++;
+    xcall->buffer_current_allocations++;
+    if ( xcall->buffer_current_allocations > xcall->buffer_maximum_allocations )
+        xcall->buffer_maximum_allocations = xcall->buffer_current_allocations;
+
+    if ( nr_pages > 1 )
+    {
+        xcall->buffer_cache_toobig++;
+    }
+    else if ( xcall->buffer_cache_nr > 0 )
+    {
+        p = xcall->buffer_cache[--xcall->buffer_cache_nr];
+        xcall->buffer_cache_hits++;
+    }
+    else
+    {
+        xcall->buffer_cache_misses++;
+    }
+
+    cache_unlock(xcall);
+
+    return p;
+}
+
+static int cache_free(xencall_handle *xcall, void *p, size_t nr_pages)
+{
+    int rc = 0;
+
+    cache_lock(xcall);
+
+    xcall->buffer_total_releases++;
+    xcall->buffer_current_allocations--;
+
+    if ( nr_pages == 1 &&
+        xcall->buffer_cache_nr < BUFFER_CACHE_SIZE )
+    {
+        xcall->buffer_cache[xcall->buffer_cache_nr++] = p;
+        rc = 1;
+    }
+
+    cache_unlock(xcall);
+
+    return rc;
+}
+
+void buffer_release_cache(xencall_handle *xcall)
+{
+    void *p;
+
+    cache_lock(xcall);
+
+    DBGPRINTF("total allocations:%d total releases:%d",
+              xcall->buffer_total_allocations,
+              xcall->buffer_total_releases);
+    DBGPRINTF("current allocations:%d maximum allocations:%d",
+              xcall->buffer_current_allocations,
+              xcall->buffer_maximum_allocations);
+    DBGPRINTF("cache current size:%d",
+              xcall->buffer_cache_nr);
+    DBGPRINTF("cache hits:%d misses:%d toobig:%d",
+              xcall->buffer_cache_hits,
+              xcall->buffer_cache_misses,
+              xcall->buffer_cache_toobig);
+
+    while ( xcall->buffer_cache_nr > 0 )
+    {
+        p = xcall->buffer_cache[--xcall->buffer_cache_nr];
+        osdep_free_pages(xcall, p, 1);
+    }
+
+    cache_unlock(xcall);
+}
+
+void *xencall_alloc_buffer_pages(xencall_handle *xcall, size_t nr_pages)
+{
+    void *p = cache_alloc(xcall, nr_pages);
+
+    if ( !p )
+        p = osdep_alloc_pages(xcall, nr_pages);
+
+    if (!p)
+        return NULL;
+
+    memset(p, 0, nr_pages * PAGE_SIZE);
+
+    return p;
+}
+
+void xencall_free_buffer_pages(xencall_handle *xcall, void *p, size_t nr_pages)
+{
+    if ( p == NULL )
+        return;
+
+    if ( !cache_free(xcall, p, nr_pages) )
+        osdep_free_pages(xcall, p, nr_pages);
+}
+
+struct allocation_header {
+    int nr_pages;
+};
+
+void *xencall_alloc_buffer(xencall_handle *xcall, size_t size)
+{
+    size_t actual_size = ROUNDUP(size + sizeof(struct allocation_header), PAGE_SHIFT);
+    int nr_pages = actual_size >> PAGE_SHIFT;
+    struct allocation_header *hdr;
+
+    hdr = xencall_alloc_buffer_pages(xcall, nr_pages);
+    if ( hdr == NULL )
+        return NULL;
+
+    hdr->nr_pages = nr_pages;
+
+    return (void *)(hdr+1);
+}
+
+void xencall_free_buffer(xencall_handle *xcall, void *p)
+{
+    struct allocation_header *hdr;
+
+    if (p == NULL)
+        return;
+
+    hdr = p;
+    --hdr;
+
+    xencall_free_buffer_pages(xcall, hdr, hdr->nr_pages);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/core.c b/tools/libs/call/core.c
new file mode 100644 (file)
index 0000000..a342871
--- /dev/null
@@ -0,0 +1,147 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+
+#include "private.h"
+
+xencall_handle *xencall_open(xentoollog_logger *logger, unsigned open_flags)
+{
+       xencall_handle *xcall = malloc(sizeof(*xcall));
+    int rc;
+
+    if (!xcall) return NULL;
+
+    xcall->flags = open_flags;
+    xcall->buffer_cache_nr = 0;
+
+    xcall->buffer_total_allocations = 0;
+    xcall->buffer_total_releases = 0;
+    xcall->buffer_current_allocations = 0;
+    xcall->buffer_maximum_allocations = 0;
+    xcall->buffer_cache_hits = 0;
+    xcall->buffer_cache_misses = 0;
+    xcall->buffer_cache_toobig = 0;
+    xcall->logger = logger;
+    xcall->logger_tofree = NULL;
+
+    if (!xcall->logger) {
+        xcall->logger = xcall->logger_tofree =
+            (xentoollog_logger*)
+            xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
+        if (!xcall->logger) goto err;
+    }
+
+    rc = osdep_xencall_open(xcall);
+    if ( rc  < 0 ) goto err;
+
+    return xcall;
+
+err:
+    osdep_xencall_close(xcall);
+    xtl_logger_destroy(xcall->logger_tofree);
+    free(xcall);
+    return NULL;
+}
+
+int xencall_close(xencall_handle *xcall)
+{
+    int rc;
+
+    if ( !xcall )
+        return 0;
+
+    rc = osdep_xencall_close(xcall);
+    buffer_release_cache(xcall);
+    xtl_logger_destroy(xcall->logger_tofree);
+    free(xcall);
+    return rc;
+}
+
+int xencall0(xencall_handle *xcall, unsigned int op)
+{
+    privcmd_hypercall_t call = {
+        .op = op,
+    };
+
+    return osdep_hypercall(xcall, &call);
+}
+
+int xencall1(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1)
+{
+    privcmd_hypercall_t call = {
+        .op = op,
+        .arg = { arg1 },
+    };
+
+    return osdep_hypercall(xcall, &call);
+}
+
+int xencall2(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2)
+{
+    privcmd_hypercall_t call = {
+        .op = op,
+        .arg = { arg1, arg2 },
+    };
+
+    return osdep_hypercall(xcall, &call);
+}
+
+int xencall3(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2, uint64_t arg3)
+{
+    privcmd_hypercall_t call = {
+        .op = op,
+        .arg = { arg1, arg2, arg3},
+    };
+
+    return osdep_hypercall(xcall, &call);
+}
+
+int xencall4(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2, uint64_t arg3,
+             uint64_t arg4)
+{
+    privcmd_hypercall_t call = {
+        .op = op,
+        .arg = { arg1, arg2, arg3, arg4 },
+    };
+
+    return osdep_hypercall(xcall, &call);
+}
+
+int xencall5(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2, uint64_t arg3,
+             uint64_t arg4, uint64_t arg5)
+{
+    privcmd_hypercall_t call = {
+        .op = op,
+        .arg = { arg1, arg2, arg3, arg4, arg5 },
+    };
+
+    return osdep_hypercall(xcall, &call);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/freebsd.c b/tools/libs/call/freebsd.c
new file mode 100644 (file)
index 0000000..2413966
--- /dev/null
@@ -0,0 +1,140 @@
+ /******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Split from xc_freebsd_osdep.c
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+#include "private.h"
+
+#define PRIVCMD_DEV     "/dev/xen/privcmd"
+
+int osdep_xencall_open(xencall_handle *xcall)
+{
+    int flags, saved_errno;
+    int fd = open(PRIVCMD_DEV, O_RDWR);
+
+    if ( fd == -1 )
+    {
+        PERROR("Could not obtain handle on privileged command interface "
+               PRIVCMD_DEV);
+        return -1;
+    }
+
+    /*
+     * Although we return the file handle as the 'xc handle' the API
+     * does not specify / guarentee that this integer is in fact
+     * a file handle. Thus we must take responsiblity to ensure
+     * it doesn't propagate (ie leak) outside the process.
+     */
+    if ( (flags = fcntl(fd, F_GETFD)) < 0 )
+    {
+        PERROR("Could not get file handle flags");
+        goto error;
+    }
+
+    flags |= FD_CLOEXEC;
+
+    if ( fcntl(fd, F_SETFD, flags) < 0 )
+    {
+        PERROR("Could not set file handle flags");
+        goto error;
+    }
+
+    xcall->fd = fd;
+    return 0;
+
+ error:
+    saved_errno = errno;
+    close(fd);
+    errno = saved_errno;
+
+    return -1;
+}
+
+int osdep_xencall_close(xencall_handle *xcall)
+{
+    int fd = xcall->fd;
+    if ( fd == -1 )
+        return 0;
+    return close(fd);
+}
+
+int osdep_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall)
+{
+    int fd = xcall->fd;
+    int ret;
+
+    ret = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
+
+    return (ret == 0) ? hypercall->retval : ret;
+}
+
+void *osdep_alloc_pages(xencall_handle *xcall, size_t npages)
+{
+    size_t size = npages * PAGE_SIZE;
+    void *p;
+
+    /* Address returned by mmap is page aligned. */
+    p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
+             -1, 0);
+    if (p == NULL)
+        return NULL;
+
+    /*
+     * Since FreeBSD doesn't have the MAP_LOCKED flag,
+     * lock memory using mlock.
+     */
+    if ( mlock(p, size) < 0 )
+    {
+        munmap(p, size);
+        return NULL;
+    }
+
+    return p;
+}
+
+void osdep_free_pages(xencall_handle *xcall, void *ptr, size_t npages)
+{
+    int saved_errno = errno;
+    /* Unlock pages */
+    munlock(ptr, npages * PAGE_SIZE);
+
+    munmap(ptr, npages * PAGE_SIZE);
+    /* We MUST propagate the hypercall errno, not unmap call's. */
+    errno = saved_errno;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/include/xencall.h b/tools/libs/call/include/xencall.h
new file mode 100644 (file)
index 0000000..0d91aa8
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef XENCALL_H
+#define XENCALL_H
+
+/*
+ * This library allows you to make arbitrary hypercalls (subject to
+ * sufficient permission for the process and the domain itself). Note
+ * that while the library interface is stable the hypercalls are
+ * subject to their own rules.
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+/* Callers who don't care don't need to #include <xentoollog.h> */
+typedef struct xentoollog_logger xentoollog_logger;
+
+typedef struct xencall_handle xencall_handle;
+
+/*
+ */
+#define XENCALL_OPENFLAG_NON_REENTRANT (1U<<0)
+
+/*
+ * Return a handle onto the hypercall driver.  Logs errors.
+ */
+xencall_handle *xencall_open(xentoollog_logger *logger, unsigned open_flags);
+
+/*
+ * Close a handle previously allocated with xencall_open().
+ */
+int xencall_close(xencall_handle *xcall);
+
+/*
+ * Call hypercalls with varying numbers of arguments.
+ */
+int xencall0(xencall_handle *xcall, unsigned int op);
+int xencall1(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1);
+int xencall2(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2);
+int xencall3(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2, uint64_t arg3);
+int xencall4(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2, uint64_t arg3,
+             uint64_t arg4);
+int xencall5(xencall_handle *xcall, unsigned int op,
+             uint64_t arg1, uint64_t arg2, uint64_t arg3,
+             uint64_t arg4, uint64_t arg5);
+
+/*
+ * Allocate and free memory which is suitable for use as a pointer
+ * argument to a hypercall.
+ */
+void *xencall_alloc_buffer_pages(xencall_handle *xcall, size_t nr_pages);
+void xencall_free_buffer_pages(xencall_handle *xcall, void *p, size_t nr_pages);
+
+void *xencall_alloc_buffer(xencall_handle *xcall, size_t size);
+void xencall_free_buffer(xencall_handle *xcall, void *p);
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/libxencall.map b/tools/libs/call/libxencall.map
new file mode 100644 (file)
index 0000000..2f96144
--- /dev/null
@@ -0,0 +1,19 @@
+VERS_1.0 {
+       global:
+               xencall_open;
+               xencall_close;
+
+               xencall0;
+               xencall1;
+               xencall2;
+               xencall3;
+               xencall4;
+               xencall5;
+               xencall6;
+
+               xencall_alloc_buffer;
+               xencall_free_buffer;
+               xencall_alloc_buffer_pages;
+               xencall_free_buffer_pages;
+       local: *; /* Do not expose anything by default */
+};
diff --git a/tools/libs/call/linux.c b/tools/libs/call/linux.c
new file mode 100644 (file)
index 0000000..55e1e83
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Split out from xc_linus_osdep.c:
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+#include "private.h"
+
+int osdep_xencall_open(xencall_handle *xcall)
+{
+    int flags, saved_errno;
+    int fd = open("/dev/xen/privcmd", O_RDWR); /* prefer this newer interface */
+
+    if ( fd == -1 && ( errno == ENOENT || errno == ENXIO || errno == ENODEV ))
+    {
+        /* Fallback to /proc/xen/privcmd */
+        fd = open("/proc/xen/privcmd", O_RDWR);
+    }
+
+    if ( fd == -1 )
+    {
+        PERROR("Could not obtain handle on privileged command interface");
+        return -1;
+    }
+
+    /* Although we return the file handle as the 'xc handle' the API
+       does not specify / guarentee that this integer is in fact
+       a file handle. Thus we must take responsiblity to ensure
+       it doesn't propagate (ie leak) outside the process */
+    if ( (flags = fcntl(fd, F_GETFD)) < 0 )
+    {
+        PERROR("Could not get file handle flags");
+        goto error;
+    }
+
+    flags |= FD_CLOEXEC;
+
+    if ( fcntl(fd, F_SETFD, flags) < 0 )
+    {
+        PERROR("Could not set file handle flags");
+        goto error;
+    }
+
+    xcall->fd = fd;
+    return 0;
+
+ error:
+    saved_errno = errno;
+    close(fd);
+    errno = saved_errno;
+    return -1;
+}
+
+int osdep_xencall_close(xencall_handle *xcall)
+{
+    int fd = xcall->fd;
+    if (fd == -1)
+        return 0;
+    return close(fd);
+}
+
+int osdep_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall)
+{
+    return ioctl(xcall->fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
+}
+
+void *osdep_alloc_pages(xencall_handle *xcall, size_t npages)
+{
+    size_t size = npages * PAGE_SIZE;
+    void *p;
+    int rc, saved_errno;
+
+    /* Address returned by mmap is page aligned. */
+    p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, -1, 0);
+    if ( p == MAP_FAILED )
+    {
+        PERROR("xc_alloc_hypercall_buffer: mmap failed");
+        return NULL;
+    }
+
+    /* Do not copy the VMA to child process on fork. Avoid the page being COW
+        on hypercall. */
+    rc = madvise(p, npages * PAGE_SIZE, MADV_DONTFORK);
+    if ( rc < 0 )
+    {
+        PERROR("xc_alloc_hypercall_buffer: madvise failed");
+        goto out;
+    }
+
+    return p;
+
+out:
+    saved_errno = errno;
+    (void)munmap(p, size);
+    errno = saved_errno;
+    return NULL;
+}
+
+void osdep_free_pages(xencall_handle *xcall, void *ptr, size_t npages)
+{
+    int saved_errno = errno;
+    /* Recover the VMA flags. Maybe it's not necessary */
+    madvise(ptr, npages * PAGE_SIZE, MADV_DOFORK);
+
+    munmap(ptr, npages * PAGE_SIZE);
+    /* We MUST propagate the hypercall errno, not unmap call's. */
+    errno = saved_errno;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/minios.c b/tools/libs/call/minios.c
new file mode 100644 (file)
index 0000000..3bee7be
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Split out from xc_minios.c
+ *
+ * Copyright 2007-2008 Samuel Thibault <samuel.thibault@eu.citrix.com>.
+ */
+
+#include <mini-os/types.h>
+#include <mini-os/os.h>
+#include <mini-os/mm.h>
+#include <mini-os/lib.h>
+
+#include <errno.h>
+#include <malloc.h>
+
+#include "private.h"
+
+int osdep_xencall_open(xencall_handle *xcall)
+{
+    /* No fd required */
+    return 0;
+}
+
+int osdep_xencall_close(xencall_handle *xcall)
+{
+    return 0;
+}
+
+int osdep_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall)
+{
+    multicall_entry_t call;
+    int i, ret;
+
+    call.op = hypercall->op;
+    for (i = 0; i < 5; i++)
+        call.args[i] = hypercall->arg[i];
+
+    ret = HYPERVISOR_multicall(&call, 1);
+
+    if (ret < 0) {
+       errno = -ret;
+       return -1;
+    }
+    if ((long) call.result < 0) {
+        errno = - (long) call.result;
+        return -1;
+    }
+    return call.result;
+}
+
+void *osdep_alloc_pages(xencall_handle *xcall, size_t npages)
+{
+    return memalign(PAGE_SIZE, npages * PAGE_SIZE);
+}
+
+void osdep_free_pages(xencall_handle *xcall, void *ptr, size_t npages)
+{
+    free(ptr);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/netbsd.c b/tools/libs/call/netbsd.c
new file mode 100644 (file)
index 0000000..2aa02f1
--- /dev/null
@@ -0,0 +1,121 @@
+/******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Split from xc_netbsd.c
+ */
+
+#include "xc_private.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <malloc.h>
+#include <sys/mman.h>
+
+int osdep_xencall_open(xencall_handle *xcall)
+{
+    int flags, saved_errno;
+    int fd = open("/kern/xen/privcmd", O_RDWR);
+
+    if ( fd == -1 )
+    {
+        PERROR("Could not obtain handle on privileged command interface");
+        return -1;
+    }
+
+    /* Although we return the file handle as the 'xc handle' the API
+       does not specify / guarentee that this integer is in fact
+       a file handle. Thus we must take responsiblity to ensure
+       it doesn't propagate (ie leak) outside the process */
+    if ( (flags = fcntl(fd, F_GETFD)) < 0 )
+    {
+        PERROR("Could not get file handle flags");
+        goto error;
+    }
+    flags |= FD_CLOEXEC;
+    if ( fcntl(fd, F_SETFD, flags) < 0 )
+    {
+        PERROR("Could not set file handle flags");
+        goto error;
+    }
+
+    xcall->fd = fd;
+    return 0;
+
+ error:
+    saved_errno = errno;
+    close(fd);
+    errno = saved_errno;
+    return -1;
+}
+
+int osdep_xencall_close(xencall_handle *xcall)
+{
+    int fd = xcall->fd;
+    return close(fd);
+}
+
+void *osdep_alloc_hypercall_buffer(xencall_handle *xcall, size_t npages)
+{
+    size_t size = npages * XC_PAGE_SIZE;
+    void *p;
+
+    p = xc_memalign(xcall, XC_PAGE_SIZE, size);
+    if (!p)
+        return NULL;
+
+    if ( mlock(p, size) < 0 )
+    {
+        free(p);
+        return NULL;
+    }
+    return p;
+}
+
+void osdep_free_hypercall_buffer(xencall_handle *xcall, void *ptr,
+                                 size_t npages)
+{
+    (void) munlock(ptr, npages * XC_PAGE_SIZE);
+    free(ptr);
+}
+
+int do_xen_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall)
+{
+    int fd = xcall->fd;
+    int error = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
+
+    /*
+     * Since NetBSD ioctl can only return 0 on success or < 0 on
+     * error, if we want to return a value from ioctl we should
+     * do so by setting hypercall->retval, to mimic Linux ioctl
+     * implementation.
+     */
+    if (error < 0)
+        return error;
+    else
+        return hypercall->retval;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/private.h b/tools/libs/call/private.h
new file mode 100644 (file)
index 0000000..37dd15f
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef XENCALL_PRIVATE_H
+#define XENCALL_PRIVATE_H
+
+#include <xentoollog.h>
+
+#include <xencall.h>
+
+#include <xen/xen.h>
+#include <xen/sys/privcmd.h>
+
+#ifndef PAGE_SHIFT /* Mini-os, Yukk */
+#define PAGE_SHIFT           12
+#endif
+#ifndef __MINIOS__ /* Yukk */
+#define PAGE_SIZE            (1UL << PAGE_SHIFT)
+#define PAGE_MASK            (~(PAGE_SIZE-1))
+#endif
+
+struct xencall_handle {
+    xentoollog_logger *logger, *logger_tofree;
+    unsigned flags;
+    int fd;
+
+    /*
+     * A simple cache of unused, single page, hypercall buffers
+     *
+     * Protected by a global lock.
+     */
+#define BUFFER_CACHE_SIZE 4
+    int buffer_cache_nr;
+    void *buffer_cache[BUFFER_CACHE_SIZE];
+
+    /*
+     * Hypercall buffer statistics. All protected by the global
+     * buffer_cache lock.
+     */
+    int buffer_total_allocations;
+    int buffer_total_releases;
+    int buffer_current_allocations;
+    int buffer_maximum_allocations;
+    int buffer_cache_hits;
+    int buffer_cache_misses;
+    int buffer_cache_toobig;
+};
+
+int osdep_xencall_open(xencall_handle *xcall);
+int osdep_xencall_close(xencall_handle *xcall);
+
+int osdep_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall);
+
+void *osdep_alloc_pages(xencall_handle *xcall, size_t nr_pages);
+void osdep_free_pages(xencall_handle *xcall, void *p, size_t nr_pages);
+
+void buffer_release_cache(xencall_handle *xcall);
+
+#define PERROR(_f...) xtl_log(xcall->logger, XTL_ERROR, errno, "xencall", _f)
+
+#endif
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libs/call/solaris.c b/tools/libs/call/solaris.c
new file mode 100644 (file)
index 0000000..945d867
--- /dev/null
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Split from xc_solaris.c
+ */
+
+#include "xc_private.h"
+
+#include <xen/memory.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <malloc.h>
+
+int osdep_xencall_open(xencall_handle *xcall)
+{
+    int flags, saved_errno;
+    int fd = open("/dev/xen/privcmd", O_RDWR);
+
+    if ( fd == -1 )
+    {
+        PERROR("Could not obtain handle on privileged command interface");
+        return -1;
+    }
+
+    /* Although we return the file handle as the 'xc handle' the API
+       does not specify / guarentee that this integer is in fact
+       a file handle. Thus we must take responsiblity to ensure
+       it doesn't propagate (ie leak) outside the process */
+    if ( (flags = fcntl(fd, F_GETFD)) < 0 )
+    {
+        PERROR("Could not get file handle flags");
+        goto error;
+    }
+    flags |= FD_CLOEXEC;
+    if ( fcntl(fd, F_SETFD, flags) < 0 )
+    {
+        PERROR("Could not set file handle flags");
+        goto error;
+    }
+
+    xcall->fd = fd;
+    return 0;
+
+ error:
+    saved_errno = errno;
+    close(fd);
+    errno = saved_errno;
+    return -1;
+}
+
+int osdep_xencall_close(xencall_handle *xcall)
+{
+    int fd = xcall->fd;
+    return close(fd);
+}
+
+void *osdep_alloc_hypercall_buffer(xencall_handle *xcall, size_t npages)
+{
+    return xc_memalign(xcall, XC_PAGE_SIZE, npages * XC_PAGE_SIZE);
+}
+
+void osdep_free_hypercall_buffer(xencall_handle *xcall, void *ptr,
+                                 size_t npages)
+{
+    free(ptr);
+}
+
+int do_xen_hypercall(xencall_handle *xcall, privcmd_hypercall_t *hypercall)
+{
+    int fd = xcall->fd;
+    return ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
index 3305fdd8826ed29a9d75662d946c506453b8ff9b..a122f73ede72684166e1e8786437233cacff97d6 100644 (file)
@@ -122,6 +122,11 @@ GUEST_PIC_OBJS := $(patsubst %.c,%.opic,$(GUEST_SRCS-y))
 $(CTRL_LIB_OBJS) $(GUEST_LIB_OBJS) \
 $(CTRL_PIC_OBJS) $(GUEST_PIC_OBJS): CFLAGS += -include $(XEN_ROOT)/tools/config.h
 
+# libxenguest includes xc_private.h, so needs this despite not using
+# this functionality directly.
+$(CTRL_LIB_OBJS) $(GUEST_LIB_OBJS) \
+$(CTRL_PIC_OBJS) $(GUEST_PIC_OBJS): CFLAGS += $(CFLAGS_libxencall)
+
 $(CTRL_LIB_OBJS) $(CTRL_PIC_OBJS): CFLAGS += $(CFLAGS_libxengnttab) $(CFLAGS_libxengntshr)
 
 LIB := libxenctrl.a
@@ -202,7 +207,7 @@ libxenctrl.so.$(MAJOR): libxenctrl.so.$(MAJOR).$(MINOR)
        $(SYMLINK_SHLIB) $< $@
 
 libxenctrl.so.$(MAJOR).$(MINOR): $(CTRL_PIC_OBJS)
-       $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxengnttab) $(LDLIBS_libxengntshr) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
+       $(CC) $(LDFLAGS) $(PTHREAD_LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxenctrl.so.$(MAJOR) $(SHLIB_LDFLAGS) -o $@ $^ $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxengnttab) $(LDLIBS_libxengntshr) $(LDLIBS_libxencall) $(PTHREAD_LIBS) $(APPEND_LDFLAGS)
 
 # libxenguest
 
index 87a0fdf79209ef441b5c44c56b3362aa98c40edb..0639632477b17d2af0212c38f28f896e8a743355 100644 (file)
 int xc_altp2m_get_domain_state(xc_interface *handle, domid_t dom, bool *state)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_get_domain_state;
     arg->domain = dom;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     if ( !rc )
         *state = arg->u.domain_state.state;
@@ -54,23 +50,19 @@ int xc_altp2m_get_domain_state(xc_interface *handle, domid_t dom, bool *state)
 int xc_altp2m_set_domain_state(xc_interface *handle, domid_t dom, bool state)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_set_domain_state;
     arg->domain = dom;
     arg->u.domain_state.state = state;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(handle, arg);
     return rc;
@@ -81,24 +73,20 @@ int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, domid_t domid,
                                      uint32_t vcpuid, xen_pfn_t gfn)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_vcpu_enable_notify;
     arg->domain = domid;
     arg->u.enable_notify.vcpu_id = vcpuid;
     arg->u.enable_notify.gfn = gfn;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(handle, arg);
     return rc;
@@ -108,24 +96,20 @@ int xc_altp2m_create_view(xc_interface *handle, domid_t domid,
                           xenmem_access_t default_access, uint16_t *view_id)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_create_p2m;
     arg->domain = domid;
     arg->u.view.view = -1;
     arg->u.view.hvmmem_default_access = default_access;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     if ( !rc )
         *view_id = arg->u.view.view;
@@ -138,23 +122,19 @@ int xc_altp2m_destroy_view(xc_interface *handle, domid_t domid,
                            uint16_t view_id)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_destroy_p2m;
     arg->domain = domid;
     arg->u.view.view = view_id;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(handle, arg);
     return rc;
@@ -165,23 +145,19 @@ int xc_altp2m_switch_to_view(xc_interface *handle, domid_t domid,
                              uint16_t view_id)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_switch_p2m;
     arg->domain = domid;
     arg->u.view.view = view_id;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(handle, arg);
     return rc;
@@ -192,17 +168,12 @@ int xc_altp2m_set_mem_access(xc_interface *handle, domid_t domid,
                              xenmem_access_t access)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_set_mem_access;
     arg->domain = domid;
@@ -210,7 +181,8 @@ int xc_altp2m_set_mem_access(xc_interface *handle, domid_t domid,
     arg->u.set_mem_access.hvmmem_access = access;
     arg->u.set_mem_access.gfn = gfn;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(handle, arg);
     return rc;
@@ -221,17 +193,12 @@ int xc_altp2m_change_gfn(xc_interface *handle, domid_t domid,
                          xen_pfn_t new_gfn)
 {
     int rc;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
 
     arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_altp2m;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
     arg->cmd = HVMOP_altp2m_change_gfn;
     arg->domain = domid;
@@ -239,7 +206,8 @@ int xc_altp2m_change_gfn(xc_interface *handle, domid_t domid,
     arg->u.change_gfn.old_gfn = old_gfn;
     arg->u.change_gfn.new_gfn = new_gfn;
 
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+                 HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(handle, arg);
     return rc;
index 99e0d480fbec1a9931dff3140435075882320c0e..921113d8edb959f16a3fb5bcc4f49af19c06087d 100644 (file)
@@ -122,7 +122,6 @@ int xc_domain_shutdown(xc_interface *xch,
                        int reason)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(sched_remote_shutdown_t, arg);
 
     arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
@@ -132,13 +131,11 @@ int xc_domain_shutdown(xc_interface *xch,
         goto out1;
     }
 
-    hypercall.op     = __HYPERVISOR_sched_op;
-    hypercall.arg[0] = (unsigned long)SCHEDOP_remote_shutdown;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
     arg->domain_id = domid;
     arg->reason = reason;
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall2(xch->xcall, __HYPERVISOR_sched_op,
+                   SCHEDOP_remote_shutdown,
+                   HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -562,7 +559,6 @@ int xc_watchdog(xc_interface *xch,
                 uint32_t timeout)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(sched_watchdog_t, arg);
 
     arg = xc_hypercall_buffer_alloc(xch, arg, sizeof(*arg));
@@ -572,13 +568,12 @@ int xc_watchdog(xc_interface *xch,
         goto out1;
     }
 
-    hypercall.op     = __HYPERVISOR_sched_op;
-    hypercall.arg[0] = (unsigned long)SCHEDOP_watchdog;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
     arg->id = id;
     arg->timeout = timeout;
 
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall2(xch->xcall, __HYPERVISOR_sched_op,
+                   SCHEDOP_watchdog,
+                   HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -1357,7 +1352,6 @@ static inline int xc_hvm_param_deprecated_check(uint32_t param)
 
 int xc_hvm_param_set(xc_interface *handle, domid_t dom, uint32_t param, uint64_t value)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_param_t, arg);
     int rc = xc_hvm_param_deprecated_check(param);
 
@@ -1368,20 +1362,18 @@ int xc_hvm_param_set(xc_interface *handle, domid_t dom, uint32_t param, uint64_t
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_set_param;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
     arg->domid = dom;
     arg->index = param;
     arg->value = value;
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_set_param,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
     xc_hypercall_buffer_free(handle, arg);
     return rc;
 }
 
 int xc_hvm_param_get(xc_interface *handle, domid_t dom, uint32_t param, uint64_t *value)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_param_t, arg);
     int rc = xc_hvm_param_deprecated_check(param);
 
@@ -1392,12 +1384,11 @@ int xc_hvm_param_get(xc_interface *handle, domid_t dom, uint32_t param, uint64_t
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_get_param;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
     arg->domid = dom;
     arg->index = param;
-    rc = do_xen_hypercall(handle, &hypercall);
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_get_param,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
     *value = arg->value;
     xc_hypercall_buffer_free(handle, arg);
     return rc;
@@ -1425,7 +1416,6 @@ int xc_hvm_create_ioreq_server(xc_interface *xch,
                                int handle_bufioreq,
                                ioservid_t *id)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_create_ioreq_server_t, arg);
     int rc;
 
@@ -1433,14 +1423,12 @@ int xc_hvm_create_ioreq_server(xc_interface *xch,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_create_ioreq_server;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->handle_bufioreq = handle_bufioreq;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_create_ioreq_server,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     *id = arg->id;
 
@@ -1455,7 +1443,6 @@ int xc_hvm_get_ioreq_server_info(xc_interface *xch,
                                  xen_pfn_t *bufioreq_pfn,
                                  evtchn_port_t *bufioreq_port)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_get_ioreq_server_info_t, arg);
     int rc;
 
@@ -1463,14 +1450,12 @@ int xc_hvm_get_ioreq_server_info(xc_interface *xch,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_get_ioreq_server_info;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->id = id;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_get_ioreq_server_info,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
     if ( rc != 0 )
         goto done;
 
@@ -1492,7 +1477,6 @@ int xc_hvm_map_io_range_to_ioreq_server(xc_interface *xch, domid_t domid,
                                         ioservid_t id, int is_mmio,
                                         uint64_t start, uint64_t end)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_io_range_t, arg);
     int rc;
 
@@ -1500,17 +1484,15 @@ int xc_hvm_map_io_range_to_ioreq_server(xc_interface *xch, domid_t domid,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_map_io_range_to_ioreq_server;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->id = id;
     arg->type = is_mmio ? HVMOP_IO_RANGE_MEMORY : HVMOP_IO_RANGE_PORT;
     arg->start = start;
     arg->end = end;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_map_io_range_to_ioreq_server,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
     return rc;
@@ -1520,7 +1502,6 @@ int xc_hvm_unmap_io_range_from_ioreq_server(xc_interface *xch, domid_t domid,
                                             ioservid_t id, int is_mmio,
                                             uint64_t start, uint64_t end)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_io_range_t, arg);
     int rc;
 
@@ -1528,17 +1509,15 @@ int xc_hvm_unmap_io_range_from_ioreq_server(xc_interface *xch, domid_t domid,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_unmap_io_range_from_ioreq_server;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->id = id;
     arg->type = is_mmio ? HVMOP_IO_RANGE_MEMORY : HVMOP_IO_RANGE_PORT;
     arg->start = start;
     arg->end = end;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_unmap_io_range_from_ioreq_server,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
     return rc;
@@ -1549,7 +1528,6 @@ int xc_hvm_map_pcidev_to_ioreq_server(xc_interface *xch, domid_t domid,
                                       uint8_t bus, uint8_t device,
                                       uint8_t function)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_io_range_t, arg);
     int rc;
 
@@ -1562,10 +1540,6 @@ int xc_hvm_map_pcidev_to_ioreq_server(xc_interface *xch, domid_t domid,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_map_io_range_to_ioreq_server;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->id = id;
     arg->type = HVMOP_IO_RANGE_PCI;
@@ -1579,7 +1553,9 @@ int xc_hvm_map_pcidev_to_ioreq_server(xc_interface *xch, domid_t domid,
                                            (uint64_t)device,
                                            (uint64_t)function);
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_map_io_range_to_ioreq_server,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
     return rc;
@@ -1590,7 +1566,6 @@ int xc_hvm_unmap_pcidev_from_ioreq_server(xc_interface *xch, domid_t domid,
                                           uint8_t bus, uint8_t device,
                                           uint8_t function)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_io_range_t, arg);
     int rc;
 
@@ -1603,10 +1578,6 @@ int xc_hvm_unmap_pcidev_from_ioreq_server(xc_interface *xch, domid_t domid,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_unmap_io_range_from_ioreq_server;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->id = id;
     arg->type = HVMOP_IO_RANGE_PCI;
@@ -1615,7 +1586,9 @@ int xc_hvm_unmap_pcidev_from_ioreq_server(xc_interface *xch, domid_t domid,
                                            (uint64_t)device,
                                            (uint64_t)function);
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_unmap_io_range_from_ioreq_server,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
     return rc;
@@ -1625,7 +1598,6 @@ int xc_hvm_destroy_ioreq_server(xc_interface *xch,
                                 domid_t domid,
                                 ioservid_t id)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_destroy_ioreq_server_t, arg);
     int rc;
 
@@ -1633,14 +1605,12 @@ int xc_hvm_destroy_ioreq_server(xc_interface *xch,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_destroy_ioreq_server;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->id = id;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_destroy_ioreq_server,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
     return rc;
@@ -1651,7 +1621,6 @@ int xc_hvm_set_ioreq_server_state(xc_interface *xch,
                                   ioservid_t id,
                                   int enabled)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_hvm_set_ioreq_server_state_t, arg);
     int rc;
 
@@ -1659,15 +1628,13 @@ int xc_hvm_set_ioreq_server_state(xc_interface *xch,
     if ( arg == NULL )
         return -1;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_set_ioreq_server_state;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = domid;
     arg->id = id;
     arg->enabled = !!enabled;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_set_ioreq_server_state,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
     return rc;
index ae2fe1a21b855e0fc08f967c93dd388352c2e682..53f7605367851fe12311a2b2c233cbfaaaf9e6bb 100644 (file)
@@ -25,7 +25,6 @@ static int do_evtchn_op(xc_interface *xch, int cmd, void *arg,
                         size_t arg_size, int silently_fail)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(arg, arg_size, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     if ( xc_hypercall_bounce_pre(xch, arg) )
@@ -34,11 +33,9 @@ static int do_evtchn_op(xc_interface *xch, int cmd, void *arg,
         goto out;
     }
 
-    hypercall.op     = __HYPERVISOR_event_channel_op;
-    hypercall.arg[0] = cmd;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
-    if ((ret = do_xen_hypercall(xch, &hypercall)) < 0 && !silently_fail)
+    ret = xencall2(xch->xcall, __HYPERVISOR_event_channel_op,
+                   cmd, HYPERCALL_BUFFER_AS_ARG(arg));
+    if ( ret < 0 && !silently_fail )
         ERROR("do_evtchn_op: HYPERVISOR_event_channel_op failed: %d", ret);
 
     xc_hypercall_bounce_post(xch, arg);
index b53365665fe4885cada6fc41c059464d439c33f5..ec52b0f85211932485863efc0b1ea4b1789fddca 100644 (file)
@@ -37,7 +37,6 @@
 int xc_flask_op(xc_interface *xch, xen_flask_op_t *op)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(op, sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     op->interface_version = XEN_FLASK_INTERFACE_VERSION;
@@ -48,10 +47,9 @@ int xc_flask_op(xc_interface *xch, xen_flask_op_t *op)
         goto out;
     }
 
-    hypercall.op     = __HYPERVISOR_xsm_op;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(op);
-
-    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
+    ret = xencall1(xch->xcall, __HYPERVISOR_xsm_op,
+                   HYPERCALL_BUFFER_AS_ARG(op));
+    if ( ret < 0 )
     {
         if ( errno == EACCES )
             fprintf(stderr, "XSM operation failed!\n");
index f6a2ccd4a5b04631ba8c546e900c37d778266688..6b440ee065bc83ae200fe10d699bb4fdce0ca5b7 100644 (file)
@@ -88,53 +88,6 @@ int osdep_privcmd_close(xc_interface *xch)
     return close(fd);
 }
 
-/*------------------------ Privcmd hypercall interface -----------------------*/
-void *osdep_alloc_hypercall_buffer(xc_interface *xch, int npages)
-{
-    size_t size = npages * XC_PAGE_SIZE;
-    void *p;
-
-    /* Address returned by mmap is page aligned. */
-    p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS,
-             -1, 0);
-    if (p == NULL)
-        return NULL;
-
-    /*
-     * Since FreeBSD doesn't have the MAP_LOCKED flag,
-     * lock memory using mlock.
-     */
-    if ( mlock(p, size) < 0 )
-    {
-        munmap(p, size);
-        return NULL;
-    }
-
-    return p;
-}
-
-void osdep_free_hypercall_buffer(xc_interface *xch, void *ptr, int npages)
-{
-
-    int saved_errno = errno;
-    /* Unlock pages */
-    munlock(ptr, npages * XC_PAGE_SIZE);
-
-    munmap(ptr, npages * XC_PAGE_SIZE);
-    /* We MUST propagate the hypercall errno, not unmap call's. */
-    errno = saved_errno;
-}
-
-int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
-{
-    int fd = xch->privcmdfd;
-    int ret;
-
-    ret = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
-
-    return (ret == 0) ? hypercall->retval : ret;
-}
-
 /*----------------------- Privcmd foreign map interface ----------------------*/
 void *xc_map_foreign_bulk(xc_interface *xch,
                           uint32_t dom, int prot,
index dd32aa2142c237286cec4563d0fc1b305f1d5b0e..af53facd9a32c75745600f6aa59919d9af002d7d 100644 (file)
@@ -21,7 +21,6 @@
 int xc_gnttab_op(xc_interface *xch, int cmd, void * op, int op_size, int count)
 {
     int ret = 0;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(op, count * op_size, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     if ( xc_hypercall_bounce_pre(xch, op) )
@@ -30,12 +29,8 @@ int xc_gnttab_op(xc_interface *xch, int cmd, void * op, int op_size, int count)
         goto out1;
     }
 
-    hypercall.op = __HYPERVISOR_grant_table_op;
-    hypercall.arg[0] = cmd;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(op);
-    hypercall.arg[2] = count;
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall3(xch->xcall,  __HYPERVISOR_grant_table_op,
+                   cmd, HYPERCALL_BUFFER_AS_ARG(op), count);
 
     xc_hypercall_bounce_post(xch, op);
 
index 517b5b48e3d47b7d91d0187210f78c38bf22eaef..c1230a1e2bdff58efa7da07cd92fea401d6ba327 100644 (file)
@@ -17,7 +17,6 @@
 
 #include <stdlib.h>
 #include <string.h>
-#include <pthread.h>
 
 #include "xc_private.h"
 #include "xg_private.h"
@@ -28,163 +27,38 @@ xc_hypercall_buffer_t XC__HYPERCALL_BUFFER_NAME(HYPERCALL_BUFFER_NULL) = {
     HYPERCALL_BUFFER_INIT_NO_BOUNCE
 };
 
-pthread_mutex_t hypercall_buffer_cache_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static void hypercall_buffer_cache_lock(xc_interface *xch)
-{
-    int saved_errno = errno;
-    if ( xch->flags & XC_OPENFLAG_NON_REENTRANT )
-        return;
-    pthread_mutex_lock(&hypercall_buffer_cache_mutex);
-    /* Ignore pthread errors. */
-    errno = saved_errno;
-}
-
-static void hypercall_buffer_cache_unlock(xc_interface *xch)
-{
-    int saved_errno = errno;
-    if ( xch->flags & XC_OPENFLAG_NON_REENTRANT )
-        return;
-    pthread_mutex_unlock(&hypercall_buffer_cache_mutex);
-    /* Ignore pthread errors. */
-    errno = saved_errno;
-}
-
-static void *hypercall_buffer_cache_alloc(xc_interface *xch, int nr_pages)
-{
-    void *p = NULL;
-
-    hypercall_buffer_cache_lock(xch);
-
-    xch->hypercall_buffer_total_allocations++;
-    xch->hypercall_buffer_current_allocations++;
-    if ( xch->hypercall_buffer_current_allocations > xch->hypercall_buffer_maximum_allocations )
-        xch->hypercall_buffer_maximum_allocations = xch->hypercall_buffer_current_allocations;
-
-    if ( nr_pages > 1 )
-    {
-        xch->hypercall_buffer_cache_toobig++;
-    }
-    else if ( xch->hypercall_buffer_cache_nr > 0 )
-    {
-        p = xch->hypercall_buffer_cache[--xch->hypercall_buffer_cache_nr];
-        xch->hypercall_buffer_cache_hits++;
-    }
-    else
-    {
-        xch->hypercall_buffer_cache_misses++;
-    }
-
-    hypercall_buffer_cache_unlock(xch);
-
-    return p;
-}
-
-static int hypercall_buffer_cache_free(xc_interface *xch, void *p, int nr_pages)
-{
-    int rc = 0;
-
-    hypercall_buffer_cache_lock(xch);
-
-    xch->hypercall_buffer_total_releases++;
-    xch->hypercall_buffer_current_allocations--;
-
-    if ( nr_pages == 1 && xch->hypercall_buffer_cache_nr < HYPERCALL_BUFFER_CACHE_SIZE )
-    {
-        xch->hypercall_buffer_cache[xch->hypercall_buffer_cache_nr++] = p;
-        rc = 1;
-    }
-
-    hypercall_buffer_cache_unlock(xch);
-
-    return rc;
-}
-
-void xc__hypercall_buffer_cache_release(xc_interface *xch)
-{
-    void *p;
-
-    hypercall_buffer_cache_lock(xch);
-
-    DBGPRINTF("hypercall buffer: total allocations:%d total releases:%d",
-              xch->hypercall_buffer_total_allocations,
-              xch->hypercall_buffer_total_releases);
-    DBGPRINTF("hypercall buffer: current allocations:%d maximum allocations:%d",
-              xch->hypercall_buffer_current_allocations,
-              xch->hypercall_buffer_maximum_allocations);
-    DBGPRINTF("hypercall buffer: cache current size:%d",
-              xch->hypercall_buffer_cache_nr);
-    DBGPRINTF("hypercall buffer: cache hits:%d misses:%d toobig:%d",
-              xch->hypercall_buffer_cache_hits,
-              xch->hypercall_buffer_cache_misses,
-              xch->hypercall_buffer_cache_toobig);
-
-    while ( xch->hypercall_buffer_cache_nr > 0 )
-    {
-        p = xch->hypercall_buffer_cache[--xch->hypercall_buffer_cache_nr];
-        osdep_free_hypercall_buffer(xch, p, 1);
-    }
-
-    hypercall_buffer_cache_unlock(xch);
-}
-
 void *xc__hypercall_buffer_alloc_pages(xc_interface *xch, xc_hypercall_buffer_t *b, int nr_pages)
 {
-    void *p = hypercall_buffer_cache_alloc(xch, nr_pages);
-
-    if ( !p )
-        p = osdep_alloc_hypercall_buffer(xch, nr_pages);
+    void *p = xencall_alloc_buffer_pages(xch->xcall, nr_pages);
 
     if (!p)
         return NULL;
 
     b->hbuf = p;
 
-    memset(p, 0, nr_pages * PAGE_SIZE);
-
     return b->hbuf;
 }
 
 void xc__hypercall_buffer_free_pages(xc_interface *xch, xc_hypercall_buffer_t *b, int nr_pages)
 {
-    if ( b->hbuf == NULL )
-        return;
-
-    if ( !hypercall_buffer_cache_free(xch, b->hbuf, nr_pages) )
-        osdep_free_hypercall_buffer(xch, b->hbuf, nr_pages);
+    xencall_free_buffer_pages(xch->xcall, b->hbuf, nr_pages);
 }
 
-struct allocation_header {
-    int nr_pages;
-};
-
 void *xc__hypercall_buffer_alloc(xc_interface *xch, xc_hypercall_buffer_t *b, size_t size)
 {
-    size_t actual_size = ROUNDUP(size + sizeof(struct allocation_header), PAGE_SHIFT);
-    int nr_pages = actual_size >> PAGE_SHIFT;
-    struct allocation_header *hdr;
+    void *p = xencall_alloc_buffer(xch->xcall, size);
 
-    hdr = xc__hypercall_buffer_alloc_pages(xch, b, nr_pages);
-    if ( hdr == NULL )
+    if (!p)
         return NULL;
 
-    b->hbuf = (void *)(hdr+1);
+    b->hbuf = p;
 
-    hdr->nr_pages = nr_pages;
     return b->hbuf;
 }
 
 void xc__hypercall_buffer_free(xc_interface *xch, xc_hypercall_buffer_t *b)
 {
-    struct allocation_header *hdr;
-
-    if (b->hbuf == NULL)
-        return;
-
-    hdr = b->hbuf;
-    b->hbuf = --hdr;
-
-    xc__hypercall_buffer_free_pages(xch, b, hdr->nr_pages);
+    xencall_free_buffer(xch->xcall, b->hbuf);
 }
 
 int xc__hypercall_bounce_pre(xc_interface *xch, xc_hypercall_buffer_t *b)
index a49cffb8c9e48a2e1e3a8039eb3d9b0029f4e84a..1cceb5d2d68f43fb2fa4dc2c9e5ffe31bb0a9e33 100644 (file)
@@ -14,7 +14,6 @@
 
 int xc_kexec_exec(xc_interface *xch, int type)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_kexec_exec_t, exec);
     int ret = -1;
 
@@ -27,11 +26,9 @@ int xc_kexec_exec(xc_interface *xch, int type)
 
     exec->type = type;
 
-    hypercall.op = __HYPERVISOR_kexec_op;
-    hypercall.arg[0] = KEXEC_CMD_kexec;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(exec);
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
+                  KEXEC_CMD_kexec,
+                  HYPERCALL_BUFFER_AS_ARG(exec));
 
 out:
     xc_hypercall_buffer_free(xch, exec);
@@ -42,7 +39,6 @@ out:
 int xc_kexec_get_range(xc_interface *xch, int range,  int nr,
                        uint64_t *size, uint64_t *start)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_kexec_range_t, get_range);
     int ret = -1;
 
@@ -56,11 +52,9 @@ int xc_kexec_get_range(xc_interface *xch, int range,  int nr,
     get_range->range = range;
     get_range->nr = nr;
 
-    hypercall.op = __HYPERVISOR_kexec_op;
-    hypercall.arg[0] = KEXEC_CMD_kexec_get_range;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(get_range);
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
+                  KEXEC_CMD_kexec_get_range,
+                  HYPERCALL_BUFFER_AS_ARG(get_range));
 
     *size = get_range->size;
     *start = get_range->start;
@@ -76,7 +70,6 @@ int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t arch,
                   uint32_t nr_segments, xen_kexec_segment_t *segments)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(segments, sizeof(*segments) * nr_segments,
                              XC_HYPERCALL_BUFFER_BOUNCE_IN);
     DECLARE_HYPERCALL_BUFFER(xen_kexec_load_t, load);
@@ -99,11 +92,9 @@ int xc_kexec_load(xc_interface *xch, uint8_t type, uint16_t arch,
     load->nr_segments = nr_segments;
     set_xen_guest_handle(load->segments.h, segments);
 
-    hypercall.op = __HYPERVISOR_kexec_op;
-    hypercall.arg[0] = KEXEC_CMD_kexec_load;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(load);
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
+                  KEXEC_CMD_kexec_load,
+                  HYPERCALL_BUFFER_AS_ARG(load));
 
 out:
     xc_hypercall_buffer_free(xch, load);
@@ -114,7 +105,6 @@ out:
 
 int xc_kexec_unload(xc_interface *xch, int type)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(xen_kexec_unload_t, unload);
     int ret = -1;
 
@@ -127,11 +117,9 @@ int xc_kexec_unload(xc_interface *xch, int type)
 
     unload->type = type;
 
-    hypercall.op = __HYPERVISOR_kexec_op;
-    hypercall.arg[0] = KEXEC_CMD_kexec_unload;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(unload);
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall2(xch->xcall, __HYPERVISOR_kexec_op,
+                  KEXEC_CMD_kexec_unload,
+                  HYPERCALL_BUFFER_AS_ARG(unload));
 
 out:
     xc_hypercall_buffer_free(xch, unload);
index 9f4c70719121e56d8c02ee1f02fc86971c0f2ab8..e68c4956ba878b276d23dfdc9f255cfd636e1cc5 100644 (file)
@@ -91,55 +91,6 @@ int osdep_privcmd_close(xc_interface *xch)
     return close(fd);
 }
 
-void *osdep_alloc_hypercall_buffer(xc_interface *xch, int npages)
-{
-    size_t size = npages * XC_PAGE_SIZE;
-    void *p;
-    int rc, saved_errno;
-
-    /* Address returned by mmap is page aligned. */
-    p = mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_LOCKED, -1, 0);
-    if ( p == MAP_FAILED )
-    {
-        PERROR("xc_alloc_hypercall_buffer: mmap failed");
-        return NULL;
-    }
-
-    /* Do not copy the VMA to child process on fork. Avoid the page being COW
-        on hypercall. */
-    rc = madvise(p, npages * XC_PAGE_SIZE, MADV_DONTFORK);
-    if ( rc < 0 )
-    {
-        PERROR("xc_alloc_hypercall_buffer: madvise failed");
-        goto out;
-    }
-
-    return p;
-
-out:
-    saved_errno = errno;
-    (void)munmap(p, size);
-    errno = saved_errno;
-    return NULL;
-}
-
-void osdep_free_hypercall_buffer(xc_interface *xch, void *ptr, int npages)
-{
-    int saved_errno = errno;
-    /* Recover the VMA flags. Maybe it's not necessary */
-    madvise(ptr, npages * XC_PAGE_SIZE, MADV_DOFORK);
-
-    munmap(ptr, npages * XC_PAGE_SIZE);
-    /* We MUST propagate the hypercall errno, not unmap call's. */
-    errno = saved_errno;
-}
-
-int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
-{
-    int fd = xch->privcmdfd;
-    return ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
-}
-
 static int xc_map_foreign_batch_single(int fd, uint32_t dom,
                                        xen_pfn_t *mfn, unsigned long addr)
 {
index 047e13bda4f4dd3acdbd8fecd7e1ef6ed9e68e0d..e3c8241251d0a440568152ae1eda62c863ecaf59 100644 (file)
@@ -61,38 +61,6 @@ void minios_interface_close_fd(int fd)
     files[fd].type = FTYPE_NONE;
 }
 
-void *osdep_alloc_hypercall_buffer(xc_interface *xch, int npages)
-{
-    return xc_memalign(xch, PAGE_SIZE, npages * PAGE_SIZE);
-}
-
-void osdep_free_hypercall_buffer(xc_interface *xch, void *ptr, int npages)
-{
-    free(ptr);
-}
-
-int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
-{
-    multicall_entry_t call;
-    int i, ret;
-
-    call.op = hypercall->op;
-    for (i = 0; i < ARRAY_SIZE(hypercall->arg); i++)
-       call.args[i] = hypercall->arg[i];
-
-    ret = HYPERVISOR_multicall(&call, 1);
-
-    if (ret < 0) {
-       errno = -ret;
-       return -1;
-    }
-    if ((long) call.result < 0) {
-        errno = - (long) call.result;
-        return -1;
-    }
-    return call.result;
-}
-
 void *xc_map_foreign_bulk(xc_interface *xch,
                           uint32_t dom, int prot,
                           const xen_pfn_t *arr, int *err, unsigned int num)
index c613545b54ebdc8888f0f9949ba4203c042a2bf0..124537bdc1f09533cbcd7fe122aea411e698de9a 100644 (file)
@@ -323,7 +323,6 @@ int xc_sched_id(xc_interface *xch,
 int xc_mca_op(xc_interface *xch, struct xen_mc *mc)
 {
     int ret = 0;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(mc, sizeof(*mc), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     if ( xc_hypercall_bounce_pre(xch, mc) )
@@ -333,9 +332,9 @@ int xc_mca_op(xc_interface *xch, struct xen_mc *mc)
     }
     mc->interface_version = XEN_MCA_INTERFACE_VERSION;
 
-    hypercall.op = __HYPERVISOR_mca;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(mc);
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall1(xch->xcall, __HYPERVISOR_mca,
+                   HYPERCALL_BUFFER_AS_ARG(mc));
+
     xc_hypercall_bounce_post(xch, mc);
     return ret;
 }
@@ -471,7 +470,6 @@ int xc_hvm_set_pci_intx_level(
     uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
     unsigned int level)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_pci_intx_level, arg);
     int rc;
 
@@ -482,10 +480,6 @@ int xc_hvm_set_pci_intx_level(
         return -1;
     }
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_set_pci_intx_level;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid  = dom;
     arg->domain = domain;
     arg->bus    = bus;
@@ -493,7 +487,9 @@ int xc_hvm_set_pci_intx_level(
     arg->intx   = intx;
     arg->level  = level;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_set_pci_intx_level,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -505,7 +501,6 @@ int xc_hvm_set_isa_irq_level(
     uint8_t isa_irq,
     unsigned int level)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_isa_irq_level, arg);
     int rc;
 
@@ -516,15 +511,13 @@ int xc_hvm_set_isa_irq_level(
         return -1;
     }
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_set_isa_irq_level;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid   = dom;
     arg->isa_irq = isa_irq;
     arg->level   = level;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_set_isa_irq_level,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -534,7 +527,6 @@ int xc_hvm_set_isa_irq_level(
 int xc_hvm_set_pci_link_route(
     xc_interface *xch, domid_t dom, uint8_t link, uint8_t isa_irq)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_pci_link_route, arg);
     int rc;
 
@@ -545,15 +537,13 @@ int xc_hvm_set_pci_link_route(
         return -1;
     }
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_set_pci_link_route;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid   = dom;
     arg->link    = link;
     arg->isa_irq = isa_irq;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_set_pci_link_route,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -563,7 +553,6 @@ int xc_hvm_set_pci_link_route(
 int xc_hvm_inject_msi(
     xc_interface *xch, domid_t dom, uint64_t addr, uint32_t data)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_inject_msi, arg);
     int rc;
 
@@ -574,15 +563,13 @@ int xc_hvm_inject_msi(
         return -1;
     }
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_inject_msi;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid = dom;
     arg->addr  = addr;
     arg->data  = data;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_inject_msi,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -594,7 +581,6 @@ int xc_hvm_track_dirty_vram(
     uint64_t first_pfn, uint64_t nr,
     unsigned long *dirty_bitmap)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(dirty_bitmap, (nr+7) / 8, XC_HYPERCALL_BUFFER_BOUNCE_OUT);
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_track_dirty_vram, arg);
     int rc;
@@ -607,16 +593,14 @@ int xc_hvm_track_dirty_vram(
         goto out;
     }
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_track_dirty_vram;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid     = dom;
     arg->first_pfn = first_pfn;
     arg->nr        = nr;
     set_xen_guest_handle(arg->dirty_bitmap, dirty_bitmap);
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_track_dirty_vram,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
 out:
     xc_hypercall_buffer_free(xch, arg);
@@ -627,7 +611,6 @@ out:
 int xc_hvm_modified_memory(
     xc_interface *xch, domid_t dom, uint64_t first_pfn, uint64_t nr)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_modified_memory, arg);
     int rc;
 
@@ -638,15 +621,13 @@ int xc_hvm_modified_memory(
         return -1;
     }
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_modified_memory;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
     arg->domid     = dom;
     arg->first_pfn = first_pfn;
     arg->nr        = nr;
 
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_modified_memory,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -656,7 +637,6 @@ int xc_hvm_modified_memory(
 int xc_hvm_set_mem_type(
     xc_interface *xch, domid_t dom, hvmmem_type_t mem_type, uint64_t first_pfn, uint64_t nr)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_set_mem_type, arg);
     int rc;
 
@@ -672,11 +652,9 @@ int xc_hvm_set_mem_type(
     arg->first_pfn    = first_pfn;
     arg->nr           = nr;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_set_mem_type;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_set_mem_type,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
@@ -688,7 +666,6 @@ int xc_hvm_inject_trap(
     uint32_t type, uint32_t error_code, uint32_t insn_len,
     uint64_t cr2)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER(struct xen_hvm_inject_trap, arg);
     int rc;
 
@@ -707,11 +684,9 @@ int xc_hvm_inject_trap(
     arg->insn_len    = insn_len;
     arg->cr2         = cr2;
 
-    hypercall.op     = __HYPERVISOR_hvm_op;
-    hypercall.arg[0] = HVMOP_inject_trap;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
-    rc = do_xen_hypercall(xch, &hypercall);
+    rc = xencall2(xch->xcall, __HYPERVISOR_hvm_op,
+                  HVMOP_inject_trap,
+                  HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_buffer_free(xch, arg);
 
index 9abb3b658eddca6182456ac0e973ec171e6bd0b8..5e3b343b77537f205360f456744c97f5c1e139f9 100644 (file)
@@ -67,46 +67,6 @@ int osdep_privcmd_close(xc_interface *xch)
     return close(fd);
 }
 
-void *osdep_alloc_hypercall_buffer(xc_interface *xch, int npages)
-{
-    size_t size = npages * XC_PAGE_SIZE;
-    void *p;
-
-    p = xc_memalign(xch, XC_PAGE_SIZE, size);
-    if (!p)
-        return NULL;
-
-    if ( mlock(p, size) < 0 )
-    {
-        free(p);
-        return NULL;
-    }
-    return p;
-}
-
-void osdep_free_hypercall_buffer(xc_interface *xch, void *ptr, int npages)
-{
-    (void) munlock(ptr, npages * XC_PAGE_SIZE);
-    free(ptr);
-}
-
-int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
-{
-    int fd = xch->privcmdfd;
-    int error = ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
-
-    /*
-     * Since NetBSD ioctl can only return 0 on success or < 0 on
-     * error, if we want to return a value from ioctl we should
-     * do so by setting hypercall->retval, to mimic Linux ioctl
-     * implementation.
-     */
-    if (error < 0)
-        return error;
-    else
-        return hypercall->retval;
-}
-
 void *xc_map_foreign_bulk(xc_interface *xch,
                           uint32_t dom, int prot,
                           const xen_pfn_t *arr, int *err, unsigned int num)
index de5873e2d48d57d715b68196898df42c214de118..ca4c17a9b547c3be6a6749c41f60c0512f48553b 100644 (file)
@@ -39,16 +39,6 @@ struct xc_interface_core *xc_interface_open(xentoollog_logger *logger,
     xch->error_handler   = logger;           xch->error_handler_tofree   = 0;
     xch->dombuild_logger = dombuild_logger;  xch->dombuild_logger_tofree = 0;
 
-    xch->hypercall_buffer_cache_nr = 0;
-
-    xch->hypercall_buffer_total_allocations = 0;
-    xch->hypercall_buffer_total_releases = 0;
-    xch->hypercall_buffer_current_allocations = 0;
-    xch->hypercall_buffer_maximum_allocations = 0;
-    xch->hypercall_buffer_cache_hits = 0;
-    xch->hypercall_buffer_cache_misses = 0;
-    xch->hypercall_buffer_cache_toobig = 0;
-
     if (!xch->error_handler) {
         xch->error_handler = xch->error_handler_tofree =
             (xentoollog_logger*)
@@ -65,14 +55,22 @@ struct xc_interface_core *xc_interface_open(xentoollog_logger *logger,
     }
     *xch = xch_buf;
 
-    if (!(open_flags & XC_OPENFLAG_DUMMY)) {
-        if ( osdep_privcmd_open(xch) < 0 )
-            goto err;
-    }
+    if (open_flags & XC_OPENFLAG_DUMMY)
+        return xch; /* We are done */
+
+    if ( osdep_privcmd_open(xch) < 0 )
+        goto err;
+
+    xch->xcall = xencall_open(xch->error_handler,
+        open_flags & XC_OPENFLAG_NON_REENTRANT ? XENCALL_OPENFLAG_NON_REENTRANT : 0U);
+
+    if ( xch->xcall == NULL )
+        goto err;
 
     return xch;
 
  err:
+    osdep_privcmd_close(xch);
     xtl_logger_destroy(xch->error_handler_tofree);
     if (xch != &xch_buf) free(xch);
     return NULL;
@@ -85,11 +83,12 @@ int xc_interface_close(xc_interface *xch)
     if (!xch)
         return 0;
 
+    rc = xencall_close(xch->xcall);
+    if (rc) PERROR("Could not close xencall interface");
+
     rc = osdep_privcmd_close(xch);
     if (rc) PERROR("Could not close hypervisor interface");
 
-    xc__hypercall_buffer_cache_release(xch);
-
     xtl_logger_destroy(xch->dombuild_logger_tofree);
     xtl_logger_destroy(xch->error_handler_tofree);
 
@@ -228,7 +227,6 @@ int xc_mmuext_op(
     unsigned int nr_ops,
     domid_t dom)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(op, nr_ops*sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
     long ret = -1;
 
@@ -238,13 +236,9 @@ int xc_mmuext_op(
         goto out1;
     }
 
-    hypercall.op     = __HYPERVISOR_mmuext_op;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(op);
-    hypercall.arg[1] = (unsigned long)nr_ops;
-    hypercall.arg[2] = (unsigned long)0;
-    hypercall.arg[3] = (unsigned long)dom;
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall4(xch->xcall, __HYPERVISOR_mmuext_op,
+                   HYPERCALL_BUFFER_AS_ARG(op),
+                   nr_ops, 0, dom);
 
     xc_hypercall_bounce_post(xch, op);
 
@@ -254,8 +248,7 @@ int xc_mmuext_op(
 
 static int flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
 {
-    int err = 0;
-    DECLARE_HYPERCALL;
+    int rc, err = 0;
     DECLARE_NAMED_HYPERCALL_BOUNCE(updates, mmu->updates, mmu->idx*sizeof(*mmu->updates), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     if ( mmu->idx == 0 )
@@ -268,13 +261,10 @@ static int flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
         goto out;
     }
 
-    hypercall.op     = __HYPERVISOR_mmu_update;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(updates);
-    hypercall.arg[1] = (unsigned long)mmu->idx;
-    hypercall.arg[2] = 0;
-    hypercall.arg[3] = mmu->subject;
-
-    if ( do_xen_hypercall(xch, &hypercall) < 0 )
+    rc = xencall4(xch->xcall, __HYPERVISOR_mmu_update,
+                  HYPERCALL_BUFFER_AS_ARG(updates),
+                  mmu->idx, 0, mmu->subject);
+    if ( rc < 0 )
     {
         ERROR("Failure when submitting mmu updates");
         err = 1;
@@ -317,7 +307,6 @@ int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
 
 long do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(arg, len, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
     long ret = -1;
 
@@ -327,11 +316,8 @@ long do_memory_op(xc_interface *xch, int cmd, void *arg, size_t len)
         goto out1;
     }
 
-    hypercall.op     = __HYPERVISOR_memory_op;
-    hypercall.arg[0] = (unsigned long) cmd;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(arg);
-
-    ret = do_xen_hypercall(xch, &hypercall);
+    ret = xencall2(xch->xcall, __HYPERVISOR_memory_op,
+                   cmd, HYPERCALL_BUFFER_AS_ARG(arg));
 
     xc_hypercall_bounce_post(xch, arg);
  out1:
index 30157cfe2d8f24ba7dbcb75c70025cbba1d6af64..c93df7fa3786b755cd9196a043218e85847ab7c5 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "_paths.h"
 #include "xenctrl.h"
+#include <xencall.h>
 
 #include <xen/sys/privcmd.h>
 
@@ -53,7 +54,6 @@ struct iovec {
 #include <sys/uio.h>
 #endif
 
-#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall
 #define DECLARE_DOMCTL struct xen_domctl domctl
 #define DECLARE_SYSCTL struct xen_sysctl sysctl
 #define DECLARE_PHYSDEV_OP struct physdev_op physdev_op
@@ -94,29 +94,11 @@ struct xc_interface_core {
     FILE *dombuild_logger_file;
     const char *currently_progress_reporting;
 
-    /*
-     * A simple cache of unused, single page, hypercall buffers
-     *
-     * Protected by a global lock.
-     */
-#define HYPERCALL_BUFFER_CACHE_SIZE 4
-    int hypercall_buffer_cache_nr;
-    void *hypercall_buffer_cache[HYPERCALL_BUFFER_CACHE_SIZE];
-
-    /*
-     * Hypercall buffer statistics. All protected by the global
-     * hypercall_buffer_cache lock.
-     */
-    int hypercall_buffer_total_allocations;
-    int hypercall_buffer_total_releases;
-    int hypercall_buffer_current_allocations;
-    int hypercall_buffer_maximum_allocations;
-    int hypercall_buffer_cache_hits;
-    int hypercall_buffer_cache_misses;
-    int hypercall_buffer_cache_toobig;
-
     /* Privcmd interface */
     int privcmdfd;
+
+    /* Hypercall interface */
+    xencall_handle *xcall;
 };
 
 int osdep_privcmd_open(xc_interface *xch);
@@ -232,24 +214,16 @@ void xc__hypercall_buffer_cache_release(xc_interface *xch);
  * Hypercall interfaces.
  */
 
-int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall);
-
 static inline int do_xen_version(xc_interface *xch, int cmd, xc_hypercall_buffer_t *dest)
 {
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER_ARGUMENT(dest);
-
-    hypercall.op     = __HYPERVISOR_xen_version;
-    hypercall.arg[0] = (unsigned long) cmd;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(dest);
-
-    return do_xen_hypercall(xch, &hypercall);
+    return xencall2(xch->xcall, __HYPERVISOR_xen_version,
+                    cmd, HYPERCALL_BUFFER_AS_ARG(dest));
 }
 
 static inline int do_physdev_op(xc_interface *xch, int cmd, void *op, size_t len)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(op, len, XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     if ( xc_hypercall_bounce_pre(xch, op) )
@@ -258,11 +232,9 @@ static inline int do_physdev_op(xc_interface *xch, int cmd, void *op, size_t len
         goto out1;
     }
 
-    hypercall.op = __HYPERVISOR_physdev_op;
-    hypercall.arg[0] = (unsigned long) cmd;
-    hypercall.arg[1] = HYPERCALL_BUFFER_AS_ARG(op);
-
-    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
+    ret = xencall2(xch->xcall, __HYPERVISOR_physdev_op,
+                   cmd, HYPERCALL_BUFFER_AS_ARG(op));
+    if ( ret < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("physdev operation failed -- need to"
@@ -277,7 +249,6 @@ out1:
 static inline int do_domctl(xc_interface *xch, struct xen_domctl *domctl)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(domctl, sizeof(*domctl), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     domctl->interface_version = XEN_DOMCTL_INTERFACE_VERSION;
@@ -288,10 +259,9 @@ static inline int do_domctl(xc_interface *xch, struct xen_domctl *domctl)
         goto out1;
     }
 
-    hypercall.op     = __HYPERVISOR_domctl;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(domctl);
-
-    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
+    ret = xencall1(xch->xcall, __HYPERVISOR_domctl,
+                   HYPERCALL_BUFFER_AS_ARG(domctl));
+    if ( ret < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("domctl operation failed -- need to"
@@ -306,7 +276,6 @@ static inline int do_domctl(xc_interface *xch, struct xen_domctl *domctl)
 static inline int do_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(sysctl, sizeof(*sysctl), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     sysctl->interface_version = XEN_SYSCTL_INTERFACE_VERSION;
@@ -317,9 +286,9 @@ static inline int do_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
         goto out1;
     }
 
-    hypercall.op     = __HYPERVISOR_sysctl;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(sysctl);
-    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
+    ret = xencall1(xch->xcall, __HYPERVISOR_sysctl,
+                   HYPERCALL_BUFFER_AS_ARG(sysctl));
+    if ( ret < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("sysctl operation failed -- need to"
@@ -335,7 +304,6 @@ static inline int do_platform_op(xc_interface *xch,
                                  struct xen_platform_op *platform_op)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(platform_op, sizeof(*platform_op),
                              XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
@@ -347,9 +315,9 @@ static inline int do_platform_op(xc_interface *xch,
         return -1;
     }
 
-    hypercall.op     = __HYPERVISOR_platform_op;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(platform_op);
-    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
+    ret = xencall1(xch->xcall, __HYPERVISOR_platform_op,
+                   HYPERCALL_BUFFER_AS_ARG(platform_op));
+    if ( ret < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("platform operation failed -- need to"
@@ -365,13 +333,11 @@ static inline int do_multicall_op(xc_interface *xch,
                                   uint32_t nr_calls)
 {
     int ret = -1;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BUFFER_ARGUMENT(call_list);
 
-    hypercall.op     = __HYPERVISOR_multicall;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(call_list);
-    hypercall.arg[1] = nr_calls;
-    if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
+    ret = xencall2(xch->xcall, __HYPERVISOR_multicall,
+                   HYPERCALL_BUFFER_AS_ARG(call_list), nr_calls);
+    if ( ret < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("multicall operation failed -- need to"
index 6f84b82f2d2787283e9c8227da8722bbe6c74389..18622fac31be889704c9b6237ad28ad924ac784c 100644 (file)
@@ -67,22 +67,6 @@ int osdep_privcmd_close(xc_interface *xch)
     return close(fd);
 }
 
-void *osdep_alloc_hypercall_buffer(xc_interface *xch, int npages)
-{
-    return xc_memalign(xch, XC_PAGE_SIZE, npages * XC_PAGE_SIZE);
-}
-
-static void osdep_free_hypercall_buffer(xc_interface *xch, void *ptr, int npages)
-{
-    free(ptr);
-}
-
-int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall)
-{
-    int fd = xch->privcmdfd;
-    return ioctl(fd, IOCTL_PRIVCMD_HYPERCALL, hypercall);
-}
-
 void *xc_map_foreign_batch(xc_interface *xch,
                           uint32_t dom, int prot,
                           xen_pfn_t *arr, int num)
index 8f4c0ccc591ced665be5194f3854858802ce175f..4e5c278acbd758f02e74109b4ba20984c1d18228 100644 (file)
@@ -23,7 +23,6 @@
 static int do_tmem_op(xc_interface *xch, tmem_op_t *op)
 {
     int ret;
-    DECLARE_HYPERCALL;
     DECLARE_HYPERCALL_BOUNCE(op, sizeof(*op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
 
     if ( xc_hypercall_bounce_pre(xch, op) )
@@ -32,9 +31,9 @@ static int do_tmem_op(xc_interface *xch, tmem_op_t *op)
         return -EFAULT;
     }
 
-    hypercall.op = __HYPERVISOR_tmem_op;
-    hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(op);
-    if ((ret = do_xen_hypercall(xch, &hypercall)) < 0)
+    ret = xencall1(xch->xcall, __HYPERVISOR_tmem_op,
+                   HYPERCALL_BUFFER_AS_ARG(op));
+    if ( ret < 0 )
     {
         if ( errno == EACCES )
             DPRINTF("tmem operation failed -- need to"
index cf6a4754fbf2f33f645c2f164b6f27abfcdc5dc4..a2ef0ec4180ee94449b04e9f91f57890b4896acd 100644 (file)
@@ -87,12 +87,12 @@ xenlockprof: xenlockprof.o
        $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
 # xen-hptool incorrectly uses libxc internals
-xen-hptool.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc
+xen-hptool.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall)
 xen-hptool: xen-hptool.o
        $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) $(APPEND_LDFLAGS)
 
 # xen-mfndump incorrectly uses libxc internals
-xen-mfndump.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc
+xen-mfndump.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall)
 xen-mfndump: xen-mfndump.o
        $(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(APPEND_LDFLAGS)
 
index 2d1f112b298a93f71fe41a32cee099580290bc3d..e127af8c2eaac7cb76da2115d24e7ef48c763b79 100644 (file)
@@ -16,7 +16,7 @@ PROGRAMS = readnotes lsevtchn
 CFLAGS += -Werror
 
 # incorrectly uses libxc internals
-CFLAGS_readnotes.o  := $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) -I$(XEN_ROOT)/tools/libxc
+CFLAGS_readnotes.o  := $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenguest) -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall)
 CFLAGS_lsevtchn.o   := $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl)
 
 .PHONY: all
index d4918679a3e21b93dc306a193422bd4a32fb498d..64876b3a2017ce65c2ffbfd5080a0b2bf0f54c0e 100644 (file)
@@ -2,7 +2,7 @@ XEN_ROOT=$(CURDIR)/../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 # xenpaging.c and file_ops.c incorrectly use libxc internals
-CFLAGS += $(CFLAGS_libxentoollog) $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) -I$(XEN_ROOT)/tools/libxc
+CFLAGS += $(CFLAGS_libxentoollog) $(CFLAGS_libxenevtchn) $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore) $(PTHREAD_CFLAGS) -I$(XEN_ROOT)/tools/libxc $(CFLAGS_libxencall)
 LDLIBS += $(LDLIBS_libxentoollog) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenstore) $(PTHREAD_LIBS)
 LDFLAGS += $(PTHREAD_LDFLAGS)