From patchwork Fri Jan 15 13:22:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ian Campbell X-Patchwork-Id: 8040681 Return-Path: X-Original-To: patchwork-xen-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id DB2EF9F716 for ; Fri, 15 Jan 2016 13:26:52 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id EE34F2035D for ; Fri, 15 Jan 2016 13:26:47 +0000 (UTC) Received: from lists.xen.org (lists.xenproject.org [50.57.142.19]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AC41320390 for ; Fri, 15 Jan 2016 13:26:42 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aK4Lc-0003sv-RU; Fri, 15 Jan 2016 13:23:24 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1aK4La-0003pE-Ma for xen-devel@lists.xen.org; Fri, 15 Jan 2016 13:23:23 +0000 Received: from [85.158.137.68] by server-16.bemta-3.messagelabs.com id F2/DA-07451-9C2F8965; Fri, 15 Jan 2016 13:23:21 +0000 X-Env-Sender: prvs=815b692d9=Ian.Campbell@citrix.com X-Msg-Ref: server-6.tower-31.messagelabs.com!1452864198!16105355!1 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 7.35.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 19900 invoked from network); 15 Jan 2016 13:23:19 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-6.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 15 Jan 2016 13:23:19 -0000 X-IronPort-AV: E=Sophos;i="5.22,299,1449532800"; d="scan'208";a="325395760" From: Ian Campbell To: , , Date: Fri, 15 Jan 2016 13:22:44 +0000 Message-ID: <1452864188-2417-6-git-send-email-ian.campbell@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1452864188-2417-1-git-send-email-ian.campbell@citrix.com> References: <1452864168.32341.97.camel@citrix.com> <1452864188-2417-1-git-send-email-ian.campbell@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: Ian Campbell Subject: [Xen-devel] [PATCH XEN v8 05/29] tools: Refactor /dev/xen/gnt{dev, shr} wrappers into libxengnttab. X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Spam-Status: No, score=-2.8 required=5.0 tests=BAYES_00, RCVD_IN_BRBL_LASTEXT, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP libxengnttab will provide a stable API and ABI for accessing the grant table devices. The functions are moved into the xengnt{tab,shr} namespace to make a clean break from libxc and avoid ambiguity regarding which interfaces are stable. All in-tree users are updated to use the new names. Upon request (via #define XC_WANT_COMPAT_GNTTAB_API) libxenctrl will provide a compat API for the old names. This is used by qemu-xen for the time being. qemu-xen-traditional is updated in lockstep. This leaves a few grant table related functions which go via privcmd (GNTTABOP) rather than ioctls on the /dev/xen/gnt* devices in libxenctrl. Specifically: - xc_gnttab_get_version - xc_gnttab_map_table_v1 - xc_gnttab_map_table_v2 - xc_gnttab_op These functions do not appear to be needed by qemu-dm, qemu-pv (provision of device model to HVM guests and PV backends respectively) or by libvchan suggesting they are not needed by non-toolstack uses of event channels. 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. After this change libxenvchan no longer needs to link against libxenctrl. It still needs xenctrl.h in one file for xen_mb and friends. Signed-off-by: Ian Campbell Acked-by: Wei Liu --- Must be applied with: - "qemu-xen-traditional: Use libxengnttab" and a corresponding QEMU_TAG update folded here. - "mini-os: Include libxengnttab with libxc"" and a corresponding bump to MINIOS_UPSTREAM_REVISION folded in here. v3: - Remove SHLIB_libxenctrl from SHDEPS_libxenvchan, and replace with SHLIB_libxentoollog. - Move to tools/libs/gnttab - Adjust for rebase over 31cf2ca75181 "tools/libxc: linux: Don't use getpagesize() when unmapping the grants" v5: Allow _close(NULL). v6: The extensive API document updates from the previous round of review have been implemented in "tools/libs/gnttab: Extensive updates to API documentation." later in the series, so as not to add further functional changes than already required to this refactoring patch. v7: Added mk-headers-$(XEN_TARGET_ARCH) build dependency instead of open coding the recursion. s/gnttab_munmap/gnttab_unmap/ and s/gntshr_munmap/gntshr_unshare/ in the API and equivalents in the internals/osdeps etc. v8: s/EVTCHNOP/GNTTABOP/ cut-&-paste error in commit log. Remove *.so on clean, add distclean target. --- .gitignore | 2 + stubdom/Makefile | 17 +- tools/Makefile | 3 + tools/Rules.mk | 14 +- tools/console/Makefile | 5 +- tools/console/daemon/io.c | 21 +- tools/libs/Makefile | 1 + tools/libs/evtchn/minios.c | 5 +- tools/libs/gnttab/Makefile | 73 +++++ tools/libs/gnttab/gntshr_core.c | 95 ++++++ .../xc_nognttab.c => libs/gnttab/gntshr_unimp.c} | 34 ++- tools/libs/gnttab/gnttab_core.c | 124 ++++++++ tools/libs/gnttab/gnttab_unimp.c | 89 ++++++ tools/libs/gnttab/include/xengnttab.h | 216 ++++++++++++++ tools/libs/gnttab/libxengnttab.map | 23 ++ tools/libs/gnttab/linux.c | 329 +++++++++++++++++++++ tools/libs/gnttab/minios.c | 117 ++++++++ tools/libs/gnttab/private.h | 47 +++ tools/libvchan/Makefile | 8 +- tools/libvchan/init.c | 26 +- tools/libvchan/io.c | 8 +- tools/libvchan/libxenvchan.h | 6 +- tools/libxc/Makefile | 15 +- tools/libxc/include/xenctrl.h | 168 ----------- tools/libxc/include/xenctrl_compat.h | 48 +++ tools/libxc/xc_gnttab.c | 53 ---- tools/libxc/xc_gnttab_compat.c | 111 +++++++ tools/libxc/xc_linux_osdep.c | 280 ------------------ tools/libxc/xc_minios.c | 73 ----- tools/libxc/xc_nogntshr.c | 46 --- tools/libxc/xc_private.c | 80 ----- tools/libxc/xc_private.h | 24 -- tools/xenstore/Makefile | 4 +- tools/xenstore/xenstored_core.h | 4 +- tools/xenstore/xenstored_domain.c | 24 +- tools/xenstore/xenstored_minios.c | 5 +- 36 files changed, 1397 insertions(+), 801 deletions(-) create mode 100644 tools/libs/gnttab/Makefile create mode 100644 tools/libs/gnttab/gntshr_core.c rename tools/{libxc/xc_nognttab.c => libs/gnttab/gntshr_unimp.c} (52%) create mode 100644 tools/libs/gnttab/gnttab_core.c create mode 100644 tools/libs/gnttab/gnttab_unimp.c create mode 100644 tools/libs/gnttab/include/xengnttab.h create mode 100644 tools/libs/gnttab/libxengnttab.map create mode 100644 tools/libs/gnttab/linux.c create mode 100644 tools/libs/gnttab/minios.c create mode 100644 tools/libs/gnttab/private.h create mode 100644 tools/libxc/xc_gnttab_compat.c delete mode 100644 tools/libxc/xc_nogntshr.c diff --git a/.gitignore b/.gitignore index aa92d78..a117161 100644 --- a/.gitignore +++ b/.gitignore @@ -63,6 +63,7 @@ stubdom/ioemu/ stubdom/libs-* stubdom/libxc-* stubdom/libxenevtchn-* +stubdom/libxengnttab-* stubdom/libxentoollog-* stubdom/lwip-* stubdom/lwip/ @@ -89,6 +90,7 @@ config/Stubdom.mk config/Docs.mk tools/libs/toollog/headers.chk tools/libs/evtchn/headers.chk +tools/libs/gnttab/headers.chk tools/blktap2/daemon/blktapctrl tools/blktap2/drivers/img2qcow tools/blktap2/drivers/lock-util diff --git a/stubdom/Makefile b/stubdom/Makefile index 702d66b..2dbf4a8 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -325,6 +325,12 @@ mk-headers-$(XEN_TARGET_ARCH): $(IOEMU_LINKFARM_TARGET) ln -sf $(XEN_ROOT)/tools/libs/evtchn/include/*.h include/ && \ ln -sf $(XEN_ROOT)/tools/libs/evtchn/*.c . && \ ln -sf $(XEN_ROOT)/tools/libs/evtchn/Makefile . ) + mkdir -p libs-$(XEN_TARGET_ARCH)/gnttab/include + [ -h libs-$(XEN_TARGET_ARCH)/gnttab/Makefile ] || ( cd libs-$(XEN_TARGET_ARCH)/gnttab && \ + ln -sf $(XEN_ROOT)/tools/libs/gnttab/*.h . && \ + 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 libxc-$(XEN_TARGET_ARCH) [ -h libxc-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxc-$(XEN_TARGET_ARCH) && \ ln -sf $(XEN_ROOT)/tools/libxc/*.h . && \ @@ -366,12 +372,21 @@ libs-$(XEN_TARGET_ARCH)/evtchn/libxenevtchn.a: mk-headers-$(XEN_TARGET_ARCH) $(N CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libs-$(XEN_TARGET_ARCH)/evtchn ####### +# libxengnttab +####### + +.PHONY: libxengnttab +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 + +####### # 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 cross-zlib +libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: mk-headers-$(XEN_TARGET_ARCH) libxentoollog libxenevtchn libxengnttab 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 diff --git a/tools/Makefile b/tools/Makefile index 99e016a..f373e71 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -249,9 +249,11 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find --includedir=$(LIBEXEC_INC) \ --source-path=$$source \ --extra-cflags="-DXC_WANT_COMPAT_EVTCHN_API=1 \ + -DXC_WANT_COMPAT_GNTTAB_API=1 \ -I$(XEN_ROOT)/tools/include \ -I$(XEN_ROOT)/tools/libs/toollog/include \ -I$(XEN_ROOT)/tools/libs/evtchn/include \ + -I$(XEN_ROOT)/tools/libs/gnttab/include \ -I$(XEN_ROOT)/tools/libxc/include \ -I$(XEN_ROOT)/tools/xenstore/include \ -I$(XEN_ROOT)/tools/xenstore/compat/include \ @@ -260,6 +262,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find -L$(XEN_ROOT)/tools/xenstore \ -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/toollog \ -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/evtchn \ + -Wl,-rpath-link=$(XEN_ROOT)/tools/libs/gnttab \ $(QEMU_UPSTREAM_RPATH)" \ --bindir=$(LIBEXEC_BIN) \ --datadir=$(SHAREDIR)/qemu-xen \ diff --git a/tools/Rules.mk b/tools/Rules.mk index 0c83e22..379990f 100644 --- a/tools/Rules.mk +++ b/tools/Rules.mk @@ -12,6 +12,7 @@ INSTALL = $(XEN_ROOT)/tools/cross-install 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_LIBXC = $(XEN_ROOT)/tools/libxc XEN_XENLIGHT = $(XEN_ROOT)/tools/libxl XEN_XENSTORE = $(XEN_ROOT)/tools/xenstore @@ -88,8 +89,17 @@ SHDEPS_libxenevtchn = LDLIBS_libxenevtchn = $(XEN_LIBXENEVTCHN)/libxenevtchn$(libextension) SHLIB_libxenevtchn = -Wl,-rpath-link=$(XEN_LIBXENEVTCHN) +CFLAGS_libxengnttab = -I$(XEN_LIBXENGNTTAB)/include $(CFLAGS_xeninclude) +LDLIBS_libxengnttab = $(XEN_LIBXENGNTTAB)/libxengnttab$(libextension) +SHLIB_libxengnttab = -Wl,-rpath-link=$(XEN_LIBXENGNTTAB) + +# xengntshr_* interfaces are actually part of libxengnttab.so +CFLAGS_libxengntshr = -I$(XEN_LIBXENGNTTAB)/include $(CFLAGS_xeninclude) +LDLIBS_libxengntshr = $(XEN_LIBXENGNTTAB)/libxengnttab$(libextension) +SHLIB_libxengntshr = -Wl,-rpath-link=$(XEN_LIBXENGNTTAB) + CFLAGS_libxenctrl = -I$(XEN_LIBXC)/include $(CFLAGS_libxentoollog) $(CFLAGS_xeninclude) -SHDEPS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) +SHDEPS_libxenctrl = $(SHLIB_libxentoollog) $(SHLIB_libxenevtchn) $(SHLIB_libxengnttab) $(SHLIB_libxengntshr) LDLIBS_libxenctrl = $(SHDEPS_libxenctrl) $(XEN_LIBXC)/libxenctrl$(libextension) SHLIB_libxenctrl = $(SHDEPS_libxenctrl) -Wl,-rpath-link=$(XEN_LIBXC) @@ -109,7 +119,7 @@ LDLIBS_libxenstat = $(SHDEPS_libxenstat) $(XEN_LIBXENSTAT)/libxenstat$(libexten SHLIB_libxenstat = $(SHDEPS_libxenstat) -Wl,-rpath-link=$(XEN_LIBXENSTAT) CFLAGS_libxenvchan = -I$(XEN_LIBVCHAN) -SHDEPS_libxenvchan = $(SHLIB_libxenctrl) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) +SHDEPS_libxenvchan = $(SHLIB_libxentoollog) $(SHLIB_libxenstore) $(SHLIB_libxenevtchn) $(SHLIB_libxengnttab) $(SHLIB_libxengntshr) LDLIBS_libxenvchan = $(SHDEPS_libxenvchan) $(XEN_LIBVCHAN)/libxenvchan$(libextension) SHLIB_libxenvchan = $(SHDEPS_libxenvchan) -Wl,-rpath-link=$(XEN_LIBVCHAN) diff --git a/tools/console/Makefile b/tools/console/Makefile index 4b3a492..6eeac8f 100644 --- a/tools/console/Makefile +++ b/tools/console/Makefile @@ -3,10 +3,8 @@ include $(XEN_ROOT)/tools/Rules.mk CFLAGS += -Werror -CFLAGS += $(CFLAGS_libxenevtchn) CFLAGS += $(CFLAGS_libxenctrl) CFLAGS += $(CFLAGS_libxenstore) -LDLIBS += $(LDLIBS_libxenevtchn) LDLIBS += $(LDLIBS_libxenctrl) LDLIBS += $(LDLIBS_libxenstore) LDLIBS += $(SOCKET_LIBS) @@ -28,8 +26,9 @@ clean: .PHONY: distclean distclean: clean +daemon/io.o: CFLAGS += $(CFLAGS_libxenevtchn) $(CFLAGS_libxengnttab) xenconsoled: $(patsubst %.c,%.o,$(wildcard daemon/*.c)) - $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) $(LDLIBS_xenconsoled) $(APPEND_LDFLAGS) + $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxengnttab) $(LDLIBS_xenconsoled) $(APPEND_LDFLAGS) xenconsole: client/_paths.h $(patsubst %.c,%.o,$(wildcard client/*.c)) $(CC) $(LDFLAGS) $^ -o $@ $(LDLIBS) $(LDLIBS_xenconsole) $(APPEND_LDFLAGS) diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 2f2e9c5..e2e7a6b 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -22,6 +22,7 @@ #include "utils.h" #include "io.h" #include +#include #include #include #include @@ -72,7 +73,7 @@ static int log_time_hv_needts = 1; static int log_time_guest_needts = 1; static int log_hv_fd = -1; -static xc_gnttab *xcg_handle = NULL; +static xengnttab_handle *xgt_handle = NULL; static struct pollfd *fds; static unsigned int current_array_size; @@ -520,8 +521,8 @@ static void domain_unmap_interface(struct domain *dom) { if (dom->interface == NULL) return; - if (xcg_handle && dom->ring_ref == -1) - xc_gnttab_munmap(xcg_handle, dom->interface, 1); + if (xgt_handle && dom->ring_ref == -1) + xengnttab_unmap(xgt_handle, dom->interface, 1); else munmap(dom->interface, XC_PAGE_SIZE); dom->interface = NULL; @@ -552,9 +553,9 @@ static int domain_create_ring(struct domain *dom) if (ring_ref != dom->ring_ref && dom->ring_ref != -1) domain_unmap_interface(dom); - if (!dom->interface && xcg_handle) { + if (!dom->interface && xgt_handle) { /* Prefer using grant table */ - dom->interface = xc_gnttab_map_grant_ref(xcg_handle, + dom->interface = xengnttab_map_grant_ref(xgt_handle, dom->domid, GNTTAB_RESERVED_CONSOLE, PROT_READ|PROT_WRITE); dom->ring_ref = -1; @@ -1029,8 +1030,8 @@ void handle_io(void) handle_hv_logs(xce_handle, true); } - xcg_handle = xc_gnttab_open(NULL, 0); - if (xcg_handle == NULL) { + xgt_handle = xengnttab_open(NULL, 0); + if (xgt_handle == NULL) { dolog(LOG_DEBUG, "Failed to open xcg handle: %d (%s)", errno, strerror(errno)); } @@ -1206,9 +1207,9 @@ void handle_io(void) xenevtchn_close(xce_handle); xce_handle = NULL; } - if (xcg_handle != NULL) { - xc_gnttab_close(xcg_handle); - xcg_handle = NULL; + if (xgt_handle != NULL) { + xengnttab_close(xgt_handle); + xgt_handle = NULL; } log_hv_evtchn = -1; } diff --git a/tools/libs/Makefile b/tools/libs/Makefile index 0e3f523..00156ae 100644 --- a/tools/libs/Makefile +++ b/tools/libs/Makefile @@ -4,5 +4,6 @@ include $(XEN_ROOT)/tools/Rules.mk SUBDIRS-y := SUBDIRS-y += toollog SUBDIRS-y += evtchn +SUBDIRS-y += gnttab all clean install distclean: %: subdirs-% diff --git a/tools/libs/evtchn/minios.c b/tools/libs/evtchn/minios.c index fb913a2..b839cd0 100644 --- a/tools/libs/evtchn/minios.c +++ b/tools/libs/evtchn/minios.c @@ -27,13 +27,12 @@ #include #include -#include - #include #include #include #include #include +#include #include #include @@ -43,8 +42,6 @@ extern void minios_evtchn_close_fd(int fd); extern struct wait_queue_head event_queue; -//void minios_evtchn_close_fd(int fd); - /* XXX Note: This is not threadsafe */ static struct evtchn_port_info* port_alloc(int fd) { struct evtchn_port_info *port_info; diff --git a/tools/libs/gnttab/Makefile b/tools/libs/gnttab/Makefile new file mode 100644 index 0000000..af64542 --- /dev/null +++ b/tools/libs/gnttab/Makefile @@ -0,0 +1,73 @@ +XEN_ROOT = $(CURDIR)/../../.. +include $(XEN_ROOT)/tools/Rules.mk + +MAJOR = 1 +MINOR = 0 +SHLIB_LDFLAGS += -Wl,--version-script=libxengnttab.map + +CFLAGS += -Werror -Wmissing-prototypes +CFLAGS += -I./include $(CFLAGS_xeninclude) +CFLAGS += $(CFLAGS_libxentoollog) + +SRCS-GNTTAB += gnttab_core.c +SRCS-GNTSHR += gntshr_core.c + +SRCS-$(CONFIG_Linux) += $(SRCS-GNTTAB) $(SRCS-GNTSHR) linux.c +SRCS-$(CONFIG_MiniOS) += $(SRCS-GNTTAB) gntshr_unimp.c minios.c +SRCS-$(CONFIG_FreeBSD) += gnttab_unimp.c gntshr_unimp.c +SRCS-$(CONFIG_SunOS) += gnttab_unimp.c gntshr_unimp.c +SRCS-$(CONFIG_NetBSD) += gnttab_unimp.c gntshr_unimp.c + +LIB_OBJS := $(patsubst %.c,%.o,$(SRCS-y)) +PIC_OBJS := $(patsubst %.c,%.opic,$(SRCS-y)) + +LIB := libxengnttab.a +ifneq ($(nosharedlibs),y) +LIB += libxengnttab.so +endif + +.PHONY: all +all: build + +.PHONY: build +build: + $(MAKE) libs + +.PHONY: libs +libs: headers.chk $(LIB) + +headers.chk: $(wildcard include/*.h) + +libxengnttab.a: $(LIB_OBJS) + $(AR) rc $@ $^ + +libxengnttab.so: libxengnttab.so.$(MAJOR) + $(SYMLINK_SHLIB) $< $@ +libxengnttab.so.$(MAJOR): libxengnttab.so.$(MAJOR).$(MINOR) + $(SYMLINK_SHLIB) $< $@ + +libxengnttab.so.$(MAJOR).$(MINOR): $(PIC_OBJS) libxengnttab.map + $(CC) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libxengnttab.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) libxengnttab.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir) + $(INSTALL_DATA) libxengnttab.a $(DESTDIR)$(libdir) + $(SYMLINK_SHLIB) libxengnttab.so.$(MAJOR).$(MINOR) $(DESTDIR)$(libdir)/libxengnttab.so.$(MAJOR) + $(SYMLINK_SHLIB) libxengnttab.so.$(MAJOR) $(DESTDIR)$(libdir)/libxengnttab.so + $(INSTALL_DATA) include/xengnttab.h $(DESTDIR)$(includedir) + +.PHONY: TAGS +TAGS: + etags -t *.c *.h + +.PHONY: clean +clean: + rm -rf *.rpm $(LIB) *~ $(DEPS) $(LIB_OBJS) $(PIC_OBJS) + rm -f libxengnttab.so.$(MAJOR).$(MINOR) libxengnttab.so.$(MAJOR) + rm -f headers.chk + +.PHONY: distclean +distclean: clean diff --git a/tools/libs/gnttab/gntshr_core.c b/tools/libs/gnttab/gntshr_core.c new file mode 100644 index 0000000..7f6bf9d --- /dev/null +++ b/tools/libs/gnttab/gntshr_core.c @@ -0,0 +1,95 @@ +/****************************************************************************** + * + * Copyright (c) 2007-2008, D G Murray + * + * 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 . + * + * Split out from xc_gnttab.c + */ + +#include + +#include "private.h" + +xengntshr_handle *xengntshr_open(xentoollog_logger *logger, unsigned open_flags) +{ + xengntshr_handle *xgs = malloc(sizeof(*xgs)); + int rc; + + if (!xgs) return NULL; + + xgs->fd = -1; + xgs->logger = logger; + xgs->logger_tofree = NULL; + + if (!xgs->logger) { + xgs->logger = xgs->logger_tofree = + (xentoollog_logger*) + xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); + if (!xgs->logger) goto err; + } + + rc = osdep_gntshr_open(xgs); + if ( rc < 0 ) goto err; + + return xgs; + +err: + osdep_gntshr_close(xgs); + xtl_logger_destroy(xgs->logger_tofree); + free(xgs); + return NULL; +} + +int xengntshr_close(xengntshr_handle *xgs) +{ + int rc; + + if ( !xgs ) + return 0; + + rc = osdep_gntshr_close(xgs); + xtl_logger_destroy(xgs->logger_tofree); + free(xgs); + return rc; +} +void *xengntshr_share_pages(xengntshr_handle *xcg, uint32_t domid, + int count, uint32_t *refs, int writable) +{ + return osdep_gntshr_share_pages(xcg, domid, count, refs, writable, -1, -1); +} + +void *xengntshr_share_page_notify(xengntshr_handle *xcg, uint32_t domid, + uint32_t *ref, int writable, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + return osdep_gntshr_share_pages(xcg, domid, 1, ref, writable, + notify_offset, notify_port); +} + +int xengntshr_unshare(xengntshr_handle *xgs, void *start_address, uint32_t count) +{ + return osdep_gntshr_unshare(xgs, start_address, count); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xc_nognttab.c b/tools/libs/gnttab/gntshr_unimp.c similarity index 52% rename from tools/libxc/xc_nognttab.c rename to tools/libs/gnttab/gntshr_unimp.c index e8a0fcb..e210484 100644 --- a/tools/libxc/xc_nognttab.c +++ b/tools/libs/gnttab/gntshr_unimp.c @@ -14,37 +14,49 @@ * * You should have received a copy of the GNU Lesser General Public * License along with this library; If not, see . + * + * Split out from xc_gnttab.c */ #include -#include "xc_private.h" +#include "private.h" -int osdep_gnttab_open(xc_gnttab *xgt) +xengntshr_handle *xengntshr_open(xentoollog_logger *logger, unsigned open_flags) { - return -1; + return NULL; } -int osdep_gnttab_close(xc_gnttab *xgt) +int xengntshr_close(xengntshr_handle *xgs) { return 0; } -int xc_gnttab_set_max_grants(xc_gnttab *xgt, uint32_t count) +void *xengntshr_share_pages(xengntshr_handle *xcg, uint32_t domid, + int count, uint32_t *refs, int writable) { abort(); } -void *osdep_gnttab_grant_map(xc_gnttab *xgt, - uint32_t count, int flags, int prot, - uint32_t *domids, uint32_t *refs, - uint32_t notify_offset, - evtchn_port_t notify_port) +void *xengntshr_share_page_notify(xengntshr_handle *xcg, uint32_t domid, + uint32_t *ref, int writable, + uint32_t notify_offset, + evtchn_port_t notify_port) { abort(); } -int xc_gnttab_munmap(xc_gnttab *xgt, void *start_address, uint32_t count) +int xengntshr_unshare(xengntshr_handle *xgs, void *start_address, uint32_t count) { abort(); } + +/* + * 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/gnttab/gnttab_core.c b/tools/libs/gnttab/gnttab_core.c new file mode 100644 index 0000000..5d0474d --- /dev/null +++ b/tools/libs/gnttab/gnttab_core.c @@ -0,0 +1,124 @@ +/****************************************************************************** + * + * Copyright (c) 2007-2008, D G Murray + * + * 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 . + * + * Split out from xc_gnttab.c + */ + +#include + +#include "private.h" + +xengnttab_handle *xengnttab_open(xentoollog_logger *logger, unsigned open_flags) +{ + xengnttab_handle *xgt = malloc(sizeof(*xgt)); + int rc; + + if (!xgt) return NULL; + + xgt->fd = -1; + xgt->logger = logger; + xgt->logger_tofree = NULL; + + if (!xgt->logger) { + xgt->logger = xgt->logger_tofree = + (xentoollog_logger*) + xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); + if (!xgt->logger) goto err; + } + + rc = osdep_gnttab_open(xgt); + if ( rc < 0 ) goto err; + + return xgt; + +err: + osdep_gnttab_close(xgt); + xtl_logger_destroy(xgt->logger_tofree); + free(xgt); + return NULL; +} + +int xengnttab_close(xengnttab_handle *xgt) +{ + int rc; + + if ( !xgt ) + return 0; + + rc = osdep_gnttab_close(xgt); + xtl_logger_destroy(xgt->logger_tofree); + free(xgt); + return rc; +} + +int xengnttab_set_max_grants(xengnttab_handle *xgt, uint32_t count) +{ + return osdep_gnttab_set_max_grants(xgt, count); +} + +void *xengnttab_map_grant_ref(xengnttab_handle *xgt, + uint32_t domid, + uint32_t ref, + int prot) +{ + return osdep_gnttab_grant_map(xgt, 1, 0, prot, &domid, &ref, -1, -1); +} + +void *xengnttab_map_grant_refs(xengnttab_handle *xgt, + uint32_t count, + uint32_t *domids, + uint32_t *refs, + int prot) +{ + return osdep_gnttab_grant_map(xgt, count, 0, prot, domids, refs, -1, -1); +} + +void *xengnttab_map_domain_grant_refs(xengnttab_handle *xgt, + uint32_t count, + uint32_t domid, + uint32_t *refs, + int prot) +{ + return osdep_gnttab_grant_map(xgt, count, XENGNTTAB_GRANT_MAP_SINGLE_DOMAIN, + prot, &domid, refs, -1, -1); +} + +void *xengnttab_map_grant_ref_notify(xengnttab_handle *xgt, + uint32_t domid, + uint32_t ref, + int prot, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + return osdep_gnttab_grant_map(xgt, 1, 0, prot, &domid, &ref, + notify_offset, notify_port); +} + +int xengnttab_unmap(xengnttab_handle *xgt, void *start_address, uint32_t count) +{ + return osdep_gnttab_unmap(xgt, start_address, count); +} + +/* + * 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/gnttab/gnttab_unimp.c b/tools/libs/gnttab/gnttab_unimp.c new file mode 100644 index 0000000..b3a4a20 --- /dev/null +++ b/tools/libs/gnttab/gnttab_unimp.c @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright (c) 2007-2008, D G Murray + * + * 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 . + * + * Split out from xc_gnttab.c + */ + +#include + +#include "private.h" + +xengnttab_handle *xengnttab_open(xentoollog_logger *logger, unsigned open_flags) +{ + return NULL; +} + +int xengnttab_close(xengnttab_handle *xgt) +{ + return 0; +} + +int xengnttab_set_max_grants(xengnttab_handle *xgt, uint32_t count) +{ + abort(); +} + +void *xengnttab_map_grant_ref(xengnttab_handle *xgt, + uint32_t domid, + uint32_t ref, + int prot) +{ + abort(); +} + +void *xengnttab_map_grant_refs(xengnttab_handle *xgt, + uint32_t count, + uint32_t *domids, + uint32_t *refs, + int prot) +{ + abort(); +} + +void *xengnttab_map_domain_grant_refs(xengnttab_handle *xgt, + uint32_t count, + uint32_t domid, + uint32_t *refs, + int prot) +{ + abort(); +} + +void *xengnttab_map_grant_ref_notify(xengnttab_handle *xgt, + uint32_t domid, + uint32_t ref, + int prot, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + abort(); +} + +int xengnttab_unmap(xengnttab_handle *xgt, void *start_address, uint32_t count) +{ + abort(); +} + +/* + * 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/gnttab/include/xengnttab.h b/tools/libs/gnttab/include/xengnttab.h new file mode 100644 index 0000000..700a5f1 --- /dev/null +++ b/tools/libs/gnttab/include/xengnttab.h @@ -0,0 +1,216 @@ +/* + * 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 . + * + * Split off from: + * xenctrl.h + * + * A library for low-level access to the Xen control interfaces. + * + * Copyright (c) 2007-2008, D G Murray + */ +#ifndef XENGNTTAB_H +#define XENGNTTAB_H + +#include + +#include +#include + +/* Callers who don't care don't need to #include */ +typedef struct xentoollog_logger xentoollog_logger; + +/* + * Grant Table Interface (making use of grants from other domains) + */ + +typedef struct xengntdev_handle xengnttab_handle; + +/* + * Note: + * After fork a child process must not use any opened xc gnttab + * handle inherited from their parent. They must open a new handle if + * they want to interact with xc. + * + * Return an fd onto the grant table driver. Logs errors. + */ +xengnttab_handle *xengnttab_open(xentoollog_logger *logger, unsigned open_flags); + +/* + * Close a handle previously allocated with xengnttab_open(). + * Never logs errors. + */ +int xengnttab_close(xengnttab_handle *xgt); + +/* + * Memory maps a grant reference from one domain to a local address range. + * Mappings should be unmapped with xengnttab_unmap. Logs errors. + * + * @parm xgt a handle on an open grant table interface + * @parm domid the domain to map memory from + * @parm ref the grant reference ID to map + * @parm prot same flag as in mmap() + */ +void *xengnttab_map_grant_ref(xengnttab_handle *xgt, + uint32_t domid, + uint32_t ref, + int prot); + +/** + * Memory maps one or more grant references from one or more domains to a + * contiguous local address range. Mappings should be unmapped with + * xengnttab_unmap. Logs errors. + * + * @parm xgt a handle on an open grant table interface + * @parm count the number of grant references to be mapped + * @parm domids an array of @count domain IDs by which the corresponding @refs + * were granted + * @parm refs an array of @count grant references to be mapped + * @parm prot same flag as in mmap() + */ +void *xengnttab_map_grant_refs(xengnttab_handle *xgt, + uint32_t count, + uint32_t *domids, + uint32_t *refs, + int prot); + +/** + * Memory maps one or more grant references from one domain to a + * contiguous local address range. Mappings should be unmapped with + * xengnttab_unmap. Logs errors. + * + * @parm xgt a handle on an open grant table interface + * @parm count the number of grant references to be mapped + * @parm domid the domain to map memory from + * @parm refs an array of @count grant references to be mapped + * @parm prot same flag as in mmap() + */ +void *xengnttab_map_domain_grant_refs(xengnttab_handle *xgt, + uint32_t count, + uint32_t domid, + uint32_t *refs, + int prot); + +/** + * Memory maps a grant reference from one domain to a local address range. + * Mappings should be unmapped with xengnttab_unmap. If notify_offset or + * notify_port are not -1, this version will attempt to set up an unmap + * notification at the given offset and event channel. When the page is + * unmapped, the byte at the given offset will be zeroed and a wakeup will be + * sent to the given event channel. Logs errors. + * + * @parm xgt a handle on an open grant table interface + * @parm domid the domain to map memory from + * @parm ref the grant reference ID to map + * @parm prot same flag as in mmap() + * @parm notify_offset The byte offset in the page to use for unmap + * notification; -1 for none. + * @parm notify_port The event channel port to use for unmap notify, or -1 + */ +void *xengnttab_map_grant_ref_notify(xengnttab_handle *xgt, + uint32_t domid, + uint32_t ref, + int prot, + uint32_t notify_offset, + evtchn_port_t notify_port); + +/* + * Unmaps the @count pages starting at @start_address, which were mapped by a + * call to xengnttab_map_grant_ref or xengnttab_map_grant_refs. Never logs. + */ +int xengnttab_unmap(xengnttab_handle *xgt, void *start_address, uint32_t count); + +/* + * Sets the maximum number of grants that may be mapped by the given instance + * to @count. Never logs. + * + * N.B. This function must be called after opening the handle, and before any + * other functions are invoked on it. + * + * N.B. When variable-length grants are mapped, fragmentation may be observed, + * and it may not be possible to satisfy requests up to the maximum number + * of grants. + */ +int xengnttab_set_max_grants(xengnttab_handle *xgt, + uint32_t count); + +/* + * Grant Sharing Interface (allocating and granting pages) + */ + +typedef struct xengntdev_handle xengntshr_handle; + +/* + * Return an fd onto the grant sharing driver. Logs errors. + * + * Note: + * After fork a child process must not use any opened xc gntshr + * handle inherited from their parent. They must open a new handle if + * they want to interact with xc. + * + */ +xengntshr_handle *xengntshr_open(xentoollog_logger *logger, + unsigned open_flags); + +/* + * Close a handle previously allocated with xengntshr_open(). + * Never logs errors. + */ +int xengntshr_close(xengntshr_handle *xgs); + +/* + * Creates and shares pages with another domain. + * + * @parm xgs a handle to an open grant sharing instance + * @parm domid the domain to share memory with + * @parm count the number of pages to share + * @parm refs the grant references of the pages (output) + * @parm writable true if the other domain can write to the pages + * @return local mapping of the pages + */ +void *xengntshr_share_pages(xengntshr_handle *xgs, uint32_t domid, + int count, uint32_t *refs, int writable); + +/* + * Creates and shares a page with another domain, with unmap notification. + * + * @parm xgs a handle to an open grant sharing instance + * @parm domid the domain to share memory with + * @parm refs the grant reference of the pages (output) + * @parm writable true if the other domain can write to the page + * @parm notify_offset The byte offset in the page to use for unmap + * notification; -1 for none. + * @parm notify_port The event channel port to use for unmap notify, or -1 + * @return local mapping of the page + */ +void *xengntshr_share_page_notify(xengntshr_handle *xgs, uint32_t domid, + uint32_t *ref, int writable, + uint32_t notify_offset, + evtchn_port_t notify_port); +/* + * Unmaps the @count pages starting at @start_address, which were mapped by a + * call to xengntshr_share_*. Never logs. + */ +int xengntshr_unshare(xengntshr_handle *xgs, void *start_address, uint32_t count); + +#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/gnttab/libxengnttab.map b/tools/libs/gnttab/libxengnttab.map new file mode 100644 index 0000000..66e8c12 --- /dev/null +++ b/tools/libs/gnttab/libxengnttab.map @@ -0,0 +1,23 @@ +VERS_1.0 { + global: + xengnttab_open; + xengnttab_close; + + xengnttab_set_max_grants; + + xengnttab_map_domain_grant_refs; + xengnttab_map_grant_ref; + xengnttab_map_grant_ref_notify; + xengnttab_map_grant_refs; + + xengnttab_unmap; + + xengntshr_open; + xengntshr_close; + + xengntshr_share_page_notify; + xengntshr_share_pages; + + xengntshr_unshare; + local: *; /* Do not expose anything by default */ +}; diff --git a/tools/libs/gnttab/linux.c b/tools/libs/gnttab/linux.c new file mode 100644 index 0000000..768119a --- /dev/null +++ b/tools/libs/gnttab/linux.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2007-2008, D G Murray + * + * 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 . + * + * Split out from xc_linux_osdep.c + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "private.h" + +#define DEVXEN "/dev/xen/" + +#define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1)) + +#define GTERROR(_l, _f...) xtl_log(_l, XTL_ERROR, errno, "gnttab", _f) +#define GSERROR(_l, _f...) xtl_log(_l, XTL_ERROR, errno, "gntshr", _f) + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1UL << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +int osdep_gnttab_open(xengnttab_handle *xgt) +{ + int fd = open(DEVXEN "gntdev", O_RDWR); + if ( fd == -1 ) + return -1; + xgt->fd = fd; + return 0; +} + +int osdep_gnttab_close(xengnttab_handle *xgt) +{ + if ( xgt->fd == -1 ) + return 0; + + return close(xgt->fd); +} + +int osdep_gnttab_set_max_grants(xengnttab_handle *xgt, uint32_t count) +{ + int fd = xgt->fd, rc; + struct ioctl_gntdev_set_max_grants max_grants = { .count = count }; + + rc = ioctl(fd, IOCTL_GNTDEV_SET_MAX_GRANTS, &max_grants); + if (rc) { + /* + * Newer (e.g. pv-ops) kernels don't implement this IOCTL, + * so ignore the resulting specific failure. + */ + if (errno == ENOTTY) + rc = 0; + else + GTERROR(xgt->logger, "ioctl SET_MAX_GRANTS failed"); + } + + return rc; +} + +void *osdep_gnttab_grant_map(xengnttab_handle *xgt, + uint32_t count, int flags, int prot, + uint32_t *domids, uint32_t *refs, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + int fd = xgt->fd; + struct ioctl_gntdev_map_grant_ref *map; + unsigned int map_size = ROUNDUP((sizeof(*map) + (count - 1) * + sizeof(struct ioctl_gntdev_map_grant_ref)), + PAGE_SHIFT); + void *addr = NULL; + int domids_stride = 1; + int i; + + if (flags & XENGNTTAB_GRANT_MAP_SINGLE_DOMAIN) + domids_stride = 0; + + if ( map_size <= PAGE_SIZE ) + map = alloca(sizeof(*map) + + (count - 1) * sizeof(struct ioctl_gntdev_map_grant_ref)); + else + { + map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_POPULATE, -1, 0); + if ( map == MAP_FAILED ) + { + GTERROR(xgt->logger, "mmap of map failed"); + return NULL; + } + } + + for ( i = 0; i < count; i++ ) + { + map->refs[i].domid = domids[i * domids_stride]; + map->refs[i].ref = refs[i]; + } + + map->count = count; + + if ( ioctl(fd, IOCTL_GNTDEV_MAP_GRANT_REF, map) ) { + GTERROR(xgt->logger, "ioctl MAP_GRANT_REF failed"); + goto out; + } + + retry: + addr = mmap(NULL, PAGE_SIZE * count, prot, MAP_SHARED, fd, + map->index); + + if (addr == MAP_FAILED && errno == EAGAIN) + { + /* + * The grant hypercall can return EAGAIN if the granted page is + * swapped out. Since the paging daemon may be in the same domain, the + * hypercall cannot block without causing a deadlock. + * + * Because there are no notificaitons when the page is swapped in, wait + * a bit before retrying, and hope that the page will arrive eventually. + */ + usleep(1000); + goto retry; + } + + if (addr != MAP_FAILED) + { + int rv = 0; + struct ioctl_gntdev_unmap_notify notify; + notify.index = map->index; + notify.action = 0; + if (notify_offset < PAGE_SIZE * count) { + notify.index += notify_offset; + notify.action |= UNMAP_NOTIFY_CLEAR_BYTE; + } + if (notify_port != -1) { + notify.event_channel_port = notify_port; + notify.action |= UNMAP_NOTIFY_SEND_EVENT; + } + if (notify.action) + rv = ioctl(fd, IOCTL_GNTDEV_SET_UNMAP_NOTIFY, ¬ify); + if (rv) { + GTERROR(xgt->logger, "ioctl SET_UNMAP_NOTIFY failed"); + munmap(addr, count * PAGE_SIZE); + addr = MAP_FAILED; + } + } + + if (addr == MAP_FAILED) + { + int saved_errno = errno; + struct ioctl_gntdev_unmap_grant_ref unmap_grant; + + /* Unmap the driver slots used to store the grant information. */ + GTERROR(xgt->logger, "mmap failed"); + unmap_grant.index = map->index; + unmap_grant.count = count; + ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant); + errno = saved_errno; + addr = NULL; + } + + out: + if ( map_size > PAGE_SIZE ) + munmap(map, map_size); + + return addr; +} + +int osdep_gnttab_unmap(xengnttab_handle *xgt, + void *start_address, + uint32_t count) +{ + int fd = xgt->fd; + struct ioctl_gntdev_get_offset_for_vaddr get_offset; + struct ioctl_gntdev_unmap_grant_ref unmap_grant; + int rc; + + if ( start_address == NULL ) + { + errno = EINVAL; + return -1; + } + + /* First, it is necessary to get the offset which was initially used to + * mmap() the pages. + */ + get_offset.vaddr = (unsigned long)start_address; + if ( (rc = ioctl(fd, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR, + &get_offset)) ) + return rc; + + if ( get_offset.count != count ) + { + errno = EINVAL; + return -1; + } + + /* Next, unmap the memory. */ + if ( (rc = munmap(start_address, count * PAGE_SIZE)) ) + return rc; + + /* Finally, unmap the driver slots used to store the grant information. */ + unmap_grant.index = get_offset.offset; + unmap_grant.count = count; + if ( (rc = ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant)) ) + return rc; + + return 0; +} + +int osdep_gntshr_open(xengntshr_handle *xgs) +{ + int fd = open(DEVXEN "gntalloc", O_RDWR); + if ( fd == -1 ) + return -1; + xgs->fd = fd; + return 0; +} + +int osdep_gntshr_close(xengntshr_handle *xgs) +{ + if ( xgs->fd == -1 ) + return 0; + + return close(xgs->fd); +} + +void *osdep_gntshr_share_pages(xengntshr_handle *xgs, + uint32_t domid, int count, + uint32_t *refs, int writable, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + struct ioctl_gntalloc_alloc_gref *gref_info = NULL; + struct ioctl_gntalloc_unmap_notify notify; + struct ioctl_gntalloc_dealloc_gref gref_drop; + int fd = xgs->fd; + int err; + void *area = NULL; + gref_info = malloc(sizeof(*gref_info) + count * sizeof(uint32_t)); + if (!gref_info) + return NULL; + gref_info->domid = domid; + gref_info->flags = writable ? GNTALLOC_FLAG_WRITABLE : 0; + gref_info->count = count; + + err = ioctl(fd, IOCTL_GNTALLOC_ALLOC_GREF, gref_info); + if (err) { + GSERROR(xgs->logger, "ioctl failed"); + goto out; + } + + area = mmap(NULL, count * PAGE_SIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, gref_info->index); + + if (area == MAP_FAILED) { + area = NULL; + GSERROR(xgs->logger, "mmap failed"); + goto out_remove_fdmap; + } + + notify.index = gref_info->index; + notify.action = 0; + if (notify_offset < PAGE_SIZE * count) { + notify.index += notify_offset; + notify.action |= UNMAP_NOTIFY_CLEAR_BYTE; + } + if (notify_port != -1) { + notify.event_channel_port = notify_port; + notify.action |= UNMAP_NOTIFY_SEND_EVENT; + } + if (notify.action) + err = ioctl(fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, ¬ify); + if (err) { + GSERROR(xgs->logger, "ioctl SET_UNMAP_NOTIFY failed"); + munmap(area, count * PAGE_SIZE); + area = NULL; + } + + memcpy(refs, gref_info->gref_ids, count * sizeof(uint32_t)); + + out_remove_fdmap: + /* Removing the mapping from the file descriptor does not cause the pages to + * be deallocated until the mapping is removed. + */ + gref_drop.index = gref_info->index; + gref_drop.count = count; + ioctl(fd, IOCTL_GNTALLOC_DEALLOC_GREF, &gref_drop); + out: + free(gref_info); + return area; +} + +int osdep_gntshr_unshare(xengntshr_handle *xgs, + void *start_address, uint32_t count) +{ + return munmap(start_address, count * PAGE_SIZE); +} + +/* + * 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/gnttab/minios.c b/tools/libs/gnttab/minios.c new file mode 100644 index 0000000..7e04174 --- /dev/null +++ b/tools/libs/gnttab/minios.c @@ -0,0 +1,117 @@ +/* + * + * Copyright 2007-2008 Samuel Thibault . + * 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 . + * + * Splitfrom xc_minios.c + */ + +#include +#include +#include + +#include +#include + +#include +#include + +#include "private.h" + +void minios_gnttab_close_fd(int fd); + +int osdep_gnttab_open(xengnttab_handle *xgt) +{ + int fd = alloc_fd(FTYPE_GNTMAP); + if ( fd == -1 ) + return -1; + gntmap_init(&files[fd].gntmap); + xgt->fd = fd; + return 0; +} + +int osdep_gnttab_close(xengnttab_handle *xgt) +{ + if ( xgt->fd == -1 ) + return 0; + + return close(xgt->fd); +} + +void minios_gnttab_close_fd(int fd) +{ + gntmap_fini(&files[fd].gntmap); + files[fd].type = FTYPE_NONE; +} + +void *osdep_gnttab_grant_map(xengnttab_handle *xgt, + uint32_t count, int flags, int prot, + uint32_t *domids, uint32_t *refs, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + int fd = xgt->fd; + int stride = 1; + if (flags & XENGNTTAB_GRANT_MAP_SINGLE_DOMAIN) + stride = 0; + if (notify_offset != -1 || notify_port != -1) { + errno = ENOSYS; + return NULL; + } + return gntmap_map_grant_refs(&files[fd].gntmap, + count, domids, stride, + refs, prot & PROT_WRITE); +} + +int osdep_gnttab_unmap(xengnttab_handle *xgt, + void *start_address, + uint32_t count) +{ + int fd = xgt->fd; + int ret; + ret = gntmap_munmap(&files[fd].gntmap, + (unsigned long) start_address, + count); + if (ret < 0) { + errno = -ret; + return -1; + } + return ret; +} + +int osdep_gnttab_set_max_grants(xengnttab_handle *xgt, uint32_t count) +{ + int fd = xgt->fd; + int ret; + ret = gntmap_set_max_grants(&files[fd].gntmap, + count); + if (ret < 0) { + errno = -ret; + return -1; + } + return ret; +} + +/* + * 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/gnttab/private.h b/tools/libs/gnttab/private.h new file mode 100644 index 0000000..d286c86 --- /dev/null +++ b/tools/libs/gnttab/private.h @@ -0,0 +1,47 @@ +#ifndef XENGNTTAB_PRIVATE_H +#define XENGNTTAB_PRIVATE_H + +#include +#include + +struct xengntdev_handle { + xentoollog_logger *logger, *logger_tofree; + int fd; +}; + +int osdep_gnttab_open(xengnttab_handle *xgt); +int osdep_gnttab_close(xengnttab_handle *xgt); + +int osdep_gnttab_set_max_grants(xengnttab_handle *xgt, uint32_t count); + +#define XENGNTTAB_GRANT_MAP_SINGLE_DOMAIN 0x1 +void *osdep_gnttab_grant_map(xengnttab_handle *xgt, + uint32_t count, int flags, int prot, + uint32_t *domids, uint32_t *refs, + uint32_t notify_offset, + evtchn_port_t notify_port); +int osdep_gnttab_unmap(xengnttab_handle *xgt, + void *start_address, + uint32_t count); +int osdep_gntshr_open(xengntshr_handle *xgs); +int osdep_gntshr_close(xengntshr_handle *xgs); + +void *osdep_gntshr_share_pages(xengntshr_handle *xgs, + uint32_t domid, int count, + uint32_t *refs, int writable, + uint32_t notify_offset, + evtchn_port_t notify_port); +int osdep_gntshr_unshare(xengntshr_handle *xgs, + void *start_address, uint32_t count); + +#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/libvchan/Makefile b/tools/libvchan/Makefile index 84128a3..0573d2f 100644 --- a/tools/libvchan/Makefile +++ b/tools/libvchan/Makefile @@ -10,15 +10,17 @@ NODE_OBJS = node.o NODE2_OBJS = node-select.o LIBVCHAN_PIC_OBJS = $(patsubst %.o,%.opic,$(LIBVCHAN_OBJS)) -LIBVCHAN_LIBS = $(LDLIBS_libxenstore) $(LDLIBS_libxenctrl) $(LDLIBS_libxenevtchn) -$(LIBVCHAN_OBJS) $(LIBVCHAN_PIC_OBJS): CFLAGS += $(CFLAGS_libxenstore) $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn) -$(NODE_OBJS) $(NODE2_OBJS): CFLAGS += $(CFLAGS_libxenctrl) $(CFLAGS_libxenevtchn) +LIBVCHAN_LIBS = $(LDLIBS_libxenstore) $(LDLIBS_libxengnttab) $(LDLIBS_libxengntshr) $(LDLIBS_libxenevtchn) +$(LIBVCHAN_OBJS) $(LIBVCHAN_PIC_OBJS): CFLAGS += $(CFLAGS_libxenstore) $(CFLAGS_libxengnttab) $(CFLAGS_libxengntshr) $(CFLAGS_libxenevtchn) +$(NODE_OBJS) $(NODE2_OBJS): CFLAGS += $(CFLAGS_libxengnttab) $(CFLAGS_libxengntshr) $(CFLAGS_libxenevtchn) MAJOR = 1.0 MINOR = 0 CFLAGS += -I../include -I. +io.o io.opic: CFLAGS += $(CFLAGS_libxenctrl) # for xen_mb et al + .PHONY: all all: libxenvchan.so vchan-node1 vchan-node2 libxenvchan.a diff --git a/tools/libvchan/init.c b/tools/libvchan/init.c index 66cb103..91531b9 100644 --- a/tools/libvchan/init.c +++ b/tools/libvchan/init.c @@ -78,7 +78,7 @@ static int init_gnt_srv(struct libxenvchan *ctrl, int domain) uint32_t ring_ref = -1; void *ring; - ring = xc_gntshr_share_page_notify(ctrl->gntshr, domain, + ring = xengntshr_share_page_notify(ctrl->gntshr, domain, &ring_ref, 1, offsetof(struct vchan_interface, srv_live), ctrl->event_port); @@ -104,7 +104,7 @@ static int init_gnt_srv(struct libxenvchan *ctrl, int domain) ctrl->read.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET; break; default: - ctrl->read.buffer = xc_gntshr_share_pages(ctrl->gntshr, domain, + ctrl->read.buffer = xengntshr_share_pages(ctrl->gntshr, domain, pages_left, ctrl->ring->grants, 1); if (!ctrl->read.buffer) goto out_ring; @@ -118,7 +118,7 @@ static int init_gnt_srv(struct libxenvchan *ctrl, int domain) ctrl->write.buffer = ((void*)ctrl->ring) + LARGE_RING_OFFSET; break; default: - ctrl->write.buffer = xc_gntshr_share_pages(ctrl->gntshr, domain, + ctrl->write.buffer = xengntshr_share_pages(ctrl->gntshr, domain, pages_right, ctrl->ring->grants + pages_left, 1); if (!ctrl->write.buffer) goto out_unmap_left; @@ -128,9 +128,9 @@ out: return ring_ref; out_unmap_left: if (pages_left) - xc_gntshr_munmap(ctrl->gntshr, ctrl->read.buffer, pages_left); + xengntshr_unshare(ctrl->gntshr, ctrl->read.buffer, pages_left); out_ring: - xc_gntshr_munmap(ctrl->gntshr, ring, 1); + xengntshr_unshare(ctrl->gntshr, ring, 1); ring_ref = -1; ctrl->ring = NULL; ctrl->write.order = ctrl->read.order = 0; @@ -142,7 +142,7 @@ static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t ring_ref) int rv = -1; uint32_t *grants; - ctrl->ring = xc_gnttab_map_grant_ref_notify(ctrl->gnttab, + ctrl->ring = xengnttab_map_grant_ref_notify(ctrl->gnttab, domain, ring_ref, PROT_READ|PROT_WRITE, offsetof(struct vchan_interface, cli_live), ctrl->event_port); @@ -172,7 +172,7 @@ static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t ring_ref) default: { int pages_left = 1 << (ctrl->write.order - PAGE_SHIFT); - ctrl->write.buffer = xc_gnttab_map_domain_grant_refs(ctrl->gnttab, + ctrl->write.buffer = xengnttab_map_domain_grant_refs(ctrl->gnttab, pages_left, domain, grants, PROT_READ|PROT_WRITE); if (!ctrl->write.buffer) goto out_unmap_ring; @@ -190,7 +190,7 @@ static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t ring_ref) default: { int pages_right = 1 << (ctrl->read.order - PAGE_SHIFT); - ctrl->read.buffer = xc_gnttab_map_domain_grant_refs(ctrl->gnttab, + ctrl->read.buffer = xengnttab_map_domain_grant_refs(ctrl->gnttab, pages_right, domain, grants, PROT_READ); if (!ctrl->read.buffer) goto out_unmap_left; @@ -202,10 +202,10 @@ static int init_gnt_cli(struct libxenvchan *ctrl, int domain, uint32_t ring_ref) return rv; out_unmap_left: if (ctrl->write.order >= PAGE_SHIFT) - xc_gnttab_munmap(ctrl->gnttab, ctrl->write.buffer, - 1 << (ctrl->write.order - PAGE_SHIFT)); + xengnttab_unmap(ctrl->gnttab, ctrl->write.buffer, + 1 << (ctrl->write.order - PAGE_SHIFT)); out_unmap_ring: - xc_gnttab_munmap(ctrl->gnttab, ctrl->ring, 1); + xengnttab_unmap(ctrl->gnttab, ctrl->ring, 1); ctrl->ring = 0; ctrl->write.order = ctrl->read.order = 0; rv = -1; @@ -325,7 +325,7 @@ struct libxenvchan *libxenvchan_server_init(xentoollog_logger *logger, int domai ctrl->write.order = LARGE_RING_SHIFT; } - ctrl->gntshr = xc_gntshr_open(logger, 0); + ctrl->gntshr = xengntshr_open(logger, 0); if (!ctrl->gntshr) goto out; @@ -413,7 +413,7 @@ struct libxenvchan *libxenvchan_client_init(xentoollog_logger *logger, int domai if (!ctrl->event_port) goto fail; - ctrl->gnttab = xc_gnttab_open(logger, 0); + ctrl->gnttab = xengnttab_open(logger, 0); if (!ctrl->gnttab) goto fail; diff --git a/tools/libvchan/io.c b/tools/libvchan/io.c index 53393a5..da303fb 100644 --- a/tools/libvchan/io.c +++ b/tools/libvchan/io.c @@ -366,10 +366,10 @@ void libxenvchan_close(struct libxenvchan *ctrl) if (ctrl->ring) { if (ctrl->is_server) { ctrl->ring->srv_live = 0; - xc_gntshr_munmap(ctrl->gntshr, ctrl->ring, 1); + xengntshr_unshare(ctrl->gntshr, ctrl->ring, 1); } else { ctrl->ring->cli_live = 0; - xc_gnttab_munmap(ctrl->gnttab, ctrl->ring, 1); + xengnttab_unmap(ctrl->gnttab, ctrl->ring, 1); } } if (ctrl->event) { @@ -379,10 +379,10 @@ void libxenvchan_close(struct libxenvchan *ctrl) } if (ctrl->is_server) { if (ctrl->gntshr) - xc_gntshr_close(ctrl->gntshr); + xengntshr_close(ctrl->gntshr); } else { if (ctrl->gnttab) - xc_gnttab_close(ctrl->gnttab); + xengnttab_close(ctrl->gnttab); } free(ctrl); } diff --git a/tools/libvchan/libxenvchan.h b/tools/libvchan/libxenvchan.h index 1544378..341c375 100644 --- a/tools/libvchan/libxenvchan.h +++ b/tools/libvchan/libxenvchan.h @@ -45,7 +45,7 @@ #include #include #include -#include +#include struct libxenvchan_ring { /* Pointer into the shared page. Offsets into buffer. */ @@ -66,8 +66,8 @@ struct libxenvchan_ring { struct libxenvchan { /* Mapping handle for shared ring page */ union { - xc_gntshr *gntshr; /* for server */ - xc_gnttab *gnttab; /* for client */ + xengntshr_handle *gntshr; /* for server */ + xengnttab_handle *gnttab; /* for client */ }; /* Pointer to shared ring page */ struct vchan_interface *ring; diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 184cbb7..33d18db 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -43,12 +43,13 @@ CTRL_SRCS-y += xc_resource.c CTRL_SRCS-$(CONFIG_X86) += xc_psr.c CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c xc_linux_osdep.c -CTRL_SRCS-$(CONFIG_FreeBSD) += xc_freebsd.c xc_freebsd_osdep.c xc_nognttab.c xc_nogntshr.c -CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c xc_nognttab.c xc_nogntshr.c -CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c xc_nognttab.c xc_nogntshr.c -CTRL_SRCS-$(CONFIG_NetBSDRump) += xc_netbsd.c xc_nognttab.c xc_nogntshr.c -CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c xc_nogntshr.c +CTRL_SRCS-$(CONFIG_FreeBSD) += xc_freebsd.c xc_freebsd_osdep.c +CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c +CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd.c +CTRL_SRCS-$(CONFIG_NetBSDRump) += xc_netbsd.c +CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c CTRL_SRCS-y += xc_evtchn_compat.c +CTRL_SRCS-y += xc_gnttab_compat.c GUEST_SRCS-y := GUEST_SRCS-y += xg_private.c xc_suspend.c @@ -126,6 +127,8 @@ OSDEP_PIC_OBJS := $(patsubst %.c,%.opic,$(OSDEP_SRCS-y)) $(CTRL_LIB_OBJS) $(GUEST_LIB_OBJS) $(OSDEP_LIB_OBJS) \ $(CTRL_PIC_OBJS) $(GUEST_PIC_OBJS) $(OSDEP_PIC_OBJS) : CFLAGS += -include $(XEN_ROOT)/tools/config.h +$(CTRL_LIB_OBJS) $(CTRL_PIC_OBJS): CFLAGS += $(CFLAGS_libxengnttab) $(CFLAGS_libxengntshr) + LIB := libxenctrl.a ifneq ($(nosharedlibs),y) LIB += libxenctrl.so libxenctrl.so.$(MAJOR) libxenctrl.so.$(MAJOR).$(MINOR) @@ -209,7 +212,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) $(DLOPEN_LIBS) $(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) $(DLOPEN_LIBS) $(PTHREAD_LIBS) $(APPEND_LDFLAGS) # libxenguest diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 0fc2a11..16e2628 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -5,9 +5,6 @@ * * Copyright (c) 2003-2004, K A Fraser. * - * xc_gnttab functions: - * Copyright (c) 2007-2008, D G Murray - * * 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; @@ -117,8 +114,6 @@ */ typedef struct xc_interface_core xc_interface; -typedef struct xengntdev_handle xc_gnttab; -typedef struct xengntdev_handle xc_gntshr; enum xc_error_code { XC_ERROR_NONE = 0, @@ -1548,116 +1543,6 @@ int xc_domain_subscribe_for_suspend( * These functions sometimes log messages as above, but not always. */ -/* - * Note: - * After fork a child process must not use any opened xc gnttab - * handle inherited from their parent. They must open a new handle if - * they want to interact with xc. - * - * Return an fd onto the grant table driver. Logs errors. - */ -xc_gnttab *xc_gnttab_open(xentoollog_logger *logger, - unsigned open_flags); - -/* - * Close a handle previously allocated with xc_gnttab_open(). - * Never logs errors. - */ -int xc_gnttab_close(xc_gnttab *xcg); - -/* - * Memory maps a grant reference from one domain to a local address range. - * Mappings should be unmapped with xc_gnttab_munmap. Logs errors. - * - * @parm xcg a handle on an open grant table interface - * @parm domid the domain to map memory from - * @parm ref the grant reference ID to map - * @parm prot same flag as in mmap() - */ -void *xc_gnttab_map_grant_ref(xc_gnttab *xcg, - uint32_t domid, - uint32_t ref, - int prot); - -/** - * Memory maps one or more grant references from one or more domains to a - * contiguous local address range. Mappings should be unmapped with - * xc_gnttab_munmap. Logs errors. - * - * @parm xcg a handle on an open grant table interface - * @parm count the number of grant references to be mapped - * @parm domids an array of @count domain IDs by which the corresponding @refs - * were granted - * @parm refs an array of @count grant references to be mapped - * @parm prot same flag as in mmap() - */ -void *xc_gnttab_map_grant_refs(xc_gnttab *xcg, - uint32_t count, - uint32_t *domids, - uint32_t *refs, - int prot); - -/** - * Memory maps one or more grant references from one domain to a - * contiguous local address range. Mappings should be unmapped with - * xc_gnttab_munmap. Logs errors. - * - * @parm xcg a handle on an open grant table interface - * @parm count the number of grant references to be mapped - * @parm domid the domain to map memory from - * @parm refs an array of @count grant references to be mapped - * @parm prot same flag as in mmap() - */ -void *xc_gnttab_map_domain_grant_refs(xc_gnttab *xcg, - uint32_t count, - uint32_t domid, - uint32_t *refs, - int prot); - -/** - * Memory maps a grant reference from one domain to a local address range. - * Mappings should be unmapped with xc_gnttab_munmap. If notify_offset or - * notify_port are not -1, this version will attempt to set up an unmap - * notification at the given offset and event channel. When the page is - * unmapped, the byte at the given offset will be zeroed and a wakeup will be - * sent to the given event channel. Logs errors. - * - * @parm xcg a handle on an open grant table interface - * @parm domid the domain to map memory from - * @parm ref the grant reference ID to map - * @parm prot same flag as in mmap() - * @parm notify_offset The byte offset in the page to use for unmap - * notification; -1 for none. - * @parm notify_port The event channel port to use for unmap notify, or -1 - */ -void *xc_gnttab_map_grant_ref_notify(xc_gnttab *xcg, - uint32_t domid, - uint32_t ref, - int prot, - uint32_t notify_offset, - evtchn_port_t notify_port); - -/* - * Unmaps the @count pages starting at @start_address, which were mapped by a - * call to xc_gnttab_map_grant_ref or xc_gnttab_map_grant_refs. Never logs. - */ -int xc_gnttab_munmap(xc_gnttab *xcg, - void *start_address, - uint32_t count); - -/* - * Sets the maximum number of grants that may be mapped by the given instance - * to @count. Never logs. - * - * N.B. This function must be called after opening the handle, and before any - * other functions are invoked on it. - * - * N.B. When variable-length grants are mapped, fragmentation may be observed, - * and it may not be possible to satisfy requests up to the maximum number - * of grants. - */ -int xc_gnttab_set_max_grants(xc_gnttab *xcg, - uint32_t count); int xc_gnttab_op(xc_interface *xch, int cmd, void * op, int op_size, int count); @@ -1668,59 +1553,6 @@ grant_entry_v1_t *xc_gnttab_map_table_v1(xc_interface *xch, int domid, int *gnt_ grant_entry_v2_t *xc_gnttab_map_table_v2(xc_interface *xch, int domid, int *gnt_num); /* Sometimes these don't set errno [fixme], and sometimes they don't log. */ -/* - * Return an fd onto the grant sharing driver. Logs errors. - * - * Note: - * After fork a child process must not use any opened xc gntshr - * handle inherited from their parent. They must open a new handle if - * they want to interact with xc. - * - */ -xc_gntshr *xc_gntshr_open(xentoollog_logger *logger, - unsigned open_flags); - -/* - * Close a handle previously allocated with xc_gntshr_open(). - * Never logs errors. - */ -int xc_gntshr_close(xc_gntshr *xcg); - -/* - * Creates and shares pages with another domain. - * - * @parm xcg a handle to an open grant sharing instance - * @parm domid the domain to share memory with - * @parm count the number of pages to share - * @parm refs the grant references of the pages (output) - * @parm writable true if the other domain can write to the pages - * @return local mapping of the pages - */ -void *xc_gntshr_share_pages(xc_gntshr *xcg, uint32_t domid, - int count, uint32_t *refs, int writable); - -/* - * Creates and shares a page with another domain, with unmap notification. - * - * @parm xcg a handle to an open grant sharing instance - * @parm domid the domain to share memory with - * @parm refs the grant reference of the pages (output) - * @parm writable true if the other domain can write to the page - * @parm notify_offset The byte offset in the page to use for unmap - * notification; -1 for none. - * @parm notify_port The event channel port to use for unmap notify, or -1 - * @return local mapping of the page - */ -void *xc_gntshr_share_page_notify(xc_gntshr *xcg, uint32_t domid, - uint32_t *ref, int writable, - uint32_t notify_offset, - evtchn_port_t notify_port); -/* - * Unmaps the @count pages starting at @start_address, which were mapped by a - * call to xc_gntshr_share_*. Never logs. - */ -int xc_gntshr_munmap(xc_gntshr *xcg, void *start_address, uint32_t count); - int xc_physdev_map_pirq(xc_interface *xch, int domid, int index, diff --git a/tools/libxc/include/xenctrl_compat.h b/tools/libxc/include/xenctrl_compat.h index 48daeb2..d99fa11 100644 --- a/tools/libxc/include/xenctrl_compat.h +++ b/tools/libxc/include/xenctrl_compat.h @@ -35,6 +35,54 @@ int xc_evtchn_unmask(xc_evtchn *xce, evtchn_port_t port); #endif /* XC_WANT_COMPAT_EVTCHN_API */ +#ifdef XC_WANT_COMPAT_GNTTAB_API + +typedef struct xengntdev_handle xc_gnttab; + +xc_gnttab *xc_gnttab_open(xentoollog_logger *logger, + unsigned open_flags); +int xc_gnttab_close(xc_gnttab *xcg); +void *xc_gnttab_map_grant_ref(xc_gnttab *xcg, + uint32_t domid, + uint32_t ref, + int prot); +void *xc_gnttab_map_grant_refs(xc_gnttab *xcg, + uint32_t count, + uint32_t *domids, + uint32_t *refs, + int prot); +void *xc_gnttab_map_domain_grant_refs(xc_gnttab *xcg, + uint32_t count, + uint32_t domid, + uint32_t *refs, + int prot); +void *xc_gnttab_map_grant_ref_notify(xc_gnttab *xcg, + uint32_t domid, + uint32_t ref, + int prot, + uint32_t notify_offset, + evtchn_port_t notify_port); +int xc_gnttab_munmap(xc_gnttab *xcg, + void *start_address, + uint32_t count); +int xc_gnttab_set_max_grants(xc_gnttab *xcg, + uint32_t count); + +typedef struct xengntdev_handle xc_gntshr; + +xc_gntshr *xc_gntshr_open(xentoollog_logger *logger, + unsigned open_flags); +int xc_gntshr_close(xc_gntshr *xcg); +void *xc_gntshr_share_pages(xc_gntshr *xcg, uint32_t domid, + int count, uint32_t *refs, int writable); +void *xc_gntshr_share_page_notify(xc_gntshr *xcg, uint32_t domid, + uint32_t *ref, int writable, + uint32_t notify_offset, + evtchn_port_t notify_port); +int xc_gntshr_munmap(xc_gntshr *xcg, void *start_address, uint32_t count); + +#endif /* XC_WANT_COMPAT_GNTTAB_API */ + #endif /* diff --git a/tools/libxc/xc_gnttab.c b/tools/libxc/xc_gnttab.c index a51f405..dd32aa2 100644 --- a/tools/libxc/xc_gnttab.c +++ b/tools/libxc/xc_gnttab.c @@ -143,59 +143,6 @@ grant_entry_v2_t *xc_gnttab_map_table_v2(xc_interface *xch, int domid, return _gnttab_map_table(xch, domid, gnt_num); } -void *xc_gnttab_map_grant_ref(xc_gnttab *xgt, - uint32_t domid, - uint32_t ref, - int prot) -{ - return osdep_gnttab_grant_map(xgt, 1, 0, prot, &domid, &ref, -1, -1); -} - -void *xc_gnttab_map_grant_refs(xc_gnttab *xgt, - uint32_t count, - uint32_t *domids, - uint32_t *refs, - int prot) -{ - return osdep_gnttab_grant_map(xgt, count, 0, prot, domids, refs, -1, -1); -} - -void *xc_gnttab_map_domain_grant_refs(xc_gnttab *xgt, - uint32_t count, - uint32_t domid, - uint32_t *refs, - int prot) -{ - return osdep_gnttab_grant_map(xgt, count, XC_GRANT_MAP_SINGLE_DOMAIN, - prot, &domid, refs, -1, -1); -} - -void *xc_gnttab_map_grant_ref_notify(xc_gnttab *xgt, - uint32_t domid, - uint32_t ref, - int prot, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - return osdep_gnttab_grant_map(xgt, 1, 0, prot, &domid, &ref, - notify_offset, notify_port); -} - -void *xc_gntshr_share_pages(xc_gntshr *xcg, uint32_t domid, - int count, uint32_t *refs, int writable) -{ - return osdep_gntshr_share_pages(xcg, domid, count, refs, writable, -1, -1); -} - -void *xc_gntshr_share_page_notify(xc_gntshr *xcg, uint32_t domid, - uint32_t *ref, int writable, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - return osdep_gntshr_share_pages(xcg, domid, 1, ref, writable, - notify_offset, notify_port); -} - /* * Local variables: * mode: C diff --git a/tools/libxc/xc_gnttab_compat.c b/tools/libxc/xc_gnttab_compat.c new file mode 100644 index 0000000..6f036d8 --- /dev/null +++ b/tools/libxc/xc_gnttab_compat.c @@ -0,0 +1,111 @@ +/* + * Compat shims for use of 3rd party consumers of libxenctrl xc_gnt{tab,shr} + * functionality which has been split into separate libraries. + */ + +#include + +#define XC_WANT_COMPAT_GNTTAB_API +#include "xenctrl.h" + +xc_gnttab *xc_gnttab_open(xentoollog_logger *logger, + unsigned open_flags) +{ + return xengnttab_open(logger, open_flags); +} + +int xc_gnttab_close(xc_gnttab *xcg) +{ + return xengnttab_close(xcg); +} + +void *xc_gnttab_map_grant_ref(xc_gnttab *xcg, + uint32_t domid, + uint32_t ref, + int prot) +{ + return xengnttab_map_grant_ref(xcg, domid, ref, prot); +} + +void *xc_gnttab_map_grant_refs(xc_gnttab *xcg, + uint32_t count, + uint32_t *domids, + uint32_t *refs, + int prot) +{ + return xengnttab_map_grant_refs(xcg, count, domids, refs, prot); +} + +void *xc_gnttab_map_domain_grant_refs(xc_gnttab *xcg, + uint32_t count, + uint32_t domid, + uint32_t *refs, + int prot) +{ + return xengnttab_map_domain_grant_refs(xcg, count, domid, refs, prot); +} + +void *xc_gnttab_map_grant_ref_notify(xc_gnttab *xcg, + uint32_t domid, + uint32_t ref, + int prot, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + return xengnttab_map_grant_ref_notify(xcg, domid, ref, prot, + notify_offset, notify_port); +} + +int xc_gnttab_munmap(xc_gnttab *xcg, + void *start_address, + uint32_t count) +{ + return xengnttab_unmap(xcg, start_address, count); +} + +int xc_gnttab_set_max_grants(xc_gnttab *xcg, + uint32_t count) +{ + return xengnttab_set_max_grants(xcg, count); +} + +xc_gntshr *xc_gntshr_open(xentoollog_logger *logger, + unsigned open_flags) +{ + return xengntshr_open(logger, open_flags); +} + +int xc_gntshr_close(xc_gntshr *xcg) +{ + return xengntshr_close(xcg); +} + +void *xc_gntshr_share_pages(xc_gntshr *xcg, uint32_t domid, + int count, uint32_t *refs, int writable) +{ + return xengntshr_share_pages(xcg, domid, count, refs, writable); +} + +void *xc_gntshr_share_page_notify(xc_gntshr *xcg, uint32_t domid, + uint32_t *ref, int writable, + uint32_t notify_offset, + evtchn_port_t notify_port) +{ + return xengntshr_share_page_notify(xcg, domid, ref, writable, + notify_offset, notify_port); +} + +int xc_gntshr_munmap(xc_gntshr *xcg, void *start_address, uint32_t count) +{ + return xengntshr_unshare(xcg, start_address, count); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/tools/libxc/xc_linux_osdep.c b/tools/libxc/xc_linux_osdep.c index 6b329ce..9c318e0 100644 --- a/tools/libxc/xc_linux_osdep.c +++ b/tools/libxc/xc_linux_osdep.c @@ -31,8 +31,6 @@ #include #include -#include -#include #include "xenctrl.h" #include "xenctrlosdep.h" @@ -41,9 +39,6 @@ #define ROUNDUP(_x,_w) (((unsigned long)(_x)+(1UL<<(_w))-1) & ~((1UL<<(_w))-1)) -#define GTERROR(_l, _f...) xtl_log(_l, XTL_ERROR, errno, "gnttab", _f) -#define GSERROR(_l, _f...) xtl_log(_l, XTL_ERROR, errno, "gntshr", _f) - static xc_osdep_handle linux_privcmd_open(xc_interface *xch) { int flags, saved_errno; @@ -461,281 +456,6 @@ static struct xc_osdep_ops linux_privcmd_ops = { }, }; -#define DEVXEN "/dev/xen/" - -int osdep_gnttab_open(xc_gnttab *xgt) -{ - int fd = open(DEVXEN "gntdev", O_RDWR); - if ( fd == -1 ) - return -1; - xgt->fd = fd; - return 0; -} - -int osdep_gnttab_close(xc_gnttab *xgt) -{ - if ( xgt->fd == -1 ) - return 0; - - return close(xgt->fd); -} - -int xc_gnttab_set_max_grants(xc_gnttab *xgt, uint32_t count) -{ - int fd = xgt->fd, rc; - struct ioctl_gntdev_set_max_grants max_grants = { .count = count }; - - rc = ioctl(fd, IOCTL_GNTDEV_SET_MAX_GRANTS, &max_grants); - if (rc) { - /* - * Newer (e.g. pv-ops) kernels don't implement this IOCTL, - * so ignore the resulting specific failure. - */ - if (errno == ENOTTY) - rc = 0; - else - GTERROR(xgt->logger, "ioctl SET_MAX_GRANTS failed"); - } - - return rc; -} - -void *osdep_gnttab_grant_map(xc_gnttab *xgt, - uint32_t count, int flags, int prot, - uint32_t *domids, uint32_t *refs, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - int fd = xgt->fd; - struct ioctl_gntdev_map_grant_ref *map; - unsigned int map_size = ROUNDUP((sizeof(*map) + (count - 1) * - sizeof(struct ioctl_gntdev_map_grant_ref)), - XC_PAGE_SHIFT); - void *addr = NULL; - int domids_stride = 1; - int i; - - if (flags & XC_GRANT_MAP_SINGLE_DOMAIN) - domids_stride = 0; - - if ( map_size <= XC_PAGE_SIZE ) - map = alloca(sizeof(*map) + - (count - 1) * sizeof(struct ioctl_gntdev_map_grant_ref)); - else - { - map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_POPULATE, -1, 0); - if ( map == MAP_FAILED ) - { - GTERROR(xgt->logger, "mmap of map failed"); - return NULL; - } - } - - for ( i = 0; i < count; i++ ) - { - map->refs[i].domid = domids[i * domids_stride]; - map->refs[i].ref = refs[i]; - } - - map->count = count; - - if ( ioctl(fd, IOCTL_GNTDEV_MAP_GRANT_REF, map) ) { - GTERROR(xgt->logger, "ioctl MAP_GRANT_REF failed"); - goto out; - } - - retry: - addr = mmap(NULL, XC_PAGE_SIZE * count, prot, MAP_SHARED, fd, - map->index); - - if (addr == MAP_FAILED && errno == EAGAIN) - { - /* - * The grant hypercall can return EAGAIN if the granted page is - * swapped out. Since the paging daemon may be in the same domain, the - * hypercall cannot block without causing a deadlock. - * - * Because there are no notificaitons when the page is swapped in, wait - * a bit before retrying, and hope that the page will arrive eventually. - */ - usleep(1000); - goto retry; - } - - if (addr != MAP_FAILED) - { - int rv = 0; - struct ioctl_gntdev_unmap_notify notify; - notify.index = map->index; - notify.action = 0; - if (notify_offset < XC_PAGE_SIZE * count) { - notify.index += notify_offset; - notify.action |= UNMAP_NOTIFY_CLEAR_BYTE; - } - if (notify_port != -1) { - notify.event_channel_port = notify_port; - notify.action |= UNMAP_NOTIFY_SEND_EVENT; - } - if (notify.action) - rv = ioctl(fd, IOCTL_GNTDEV_SET_UNMAP_NOTIFY, ¬ify); - if (rv) { - GTERROR(xgt->logger, "ioctl SET_UNMAP_NOTIFY failed"); - munmap(addr, count * XC_PAGE_SIZE); - addr = MAP_FAILED; - } - } - - if (addr == MAP_FAILED) - { - int saved_errno = errno; - struct ioctl_gntdev_unmap_grant_ref unmap_grant; - - /* Unmap the driver slots used to store the grant information. */ - GTERROR(xgt->logger, "mmap failed"); - unmap_grant.index = map->index; - unmap_grant.count = count; - ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant); - errno = saved_errno; - addr = NULL; - } - - out: - if ( map_size > XC_PAGE_SIZE ) - munmap(map, map_size); - - return addr; -} - -int xc_gnttab_munmap(xc_gnttab *xgt, void *start_address, uint32_t count) -{ - int fd = xgt->fd; - struct ioctl_gntdev_get_offset_for_vaddr get_offset; - struct ioctl_gntdev_unmap_grant_ref unmap_grant; - int rc; - - if ( start_address == NULL ) - { - errno = EINVAL; - return -1; - } - - /* First, it is necessary to get the offset which was initially used to - * mmap() the pages. - */ - get_offset.vaddr = (unsigned long)start_address; - if ( (rc = ioctl(fd, IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR, - &get_offset)) ) - return rc; - - if ( get_offset.count != count ) - { - errno = EINVAL; - return -1; - } - - /* Next, unmap the memory. */ - if ( (rc = munmap(start_address, count * XC_PAGE_SIZE)) ) - return rc; - - /* Finally, unmap the driver slots used to store the grant information. */ - unmap_grant.index = get_offset.offset; - unmap_grant.count = count; - if ( (rc = ioctl(fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &unmap_grant)) ) - return rc; - - return 0; -} - -int osdep_gntshr_open(xc_gntshr *xgs) -{ - int fd = open(DEVXEN "gntalloc", O_RDWR); - if ( fd == -1 ) - return -1; - xgs->fd = fd; - return 0; -} - -int osdep_gntshr_close(xc_gntshr *xgs) -{ - if ( xgs->fd == -1 ) - return 0; - - return close(xgs->fd); -} - -void *osdep_gntshr_share_pages(xc_gntshr *xgs, - uint32_t domid, int count, - uint32_t *refs, int writable, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - struct ioctl_gntalloc_alloc_gref *gref_info = NULL; - struct ioctl_gntalloc_unmap_notify notify; - struct ioctl_gntalloc_dealloc_gref gref_drop; - int fd = xgs->fd; - int err; - void *area = NULL; - gref_info = malloc(sizeof(*gref_info) + count * sizeof(uint32_t)); - if (!gref_info) - return NULL; - gref_info->domid = domid; - gref_info->flags = writable ? GNTALLOC_FLAG_WRITABLE : 0; - gref_info->count = count; - - err = ioctl(fd, IOCTL_GNTALLOC_ALLOC_GREF, gref_info); - if (err) { - GSERROR(xgs->logger, "ioctl failed"); - goto out; - } - - area = mmap(NULL, count * XC_PAGE_SIZE, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, gref_info->index); - - if (area == MAP_FAILED) { - area = NULL; - GSERROR(xgs->logger, "mmap failed"); - goto out_remove_fdmap; - } - - notify.index = gref_info->index; - notify.action = 0; - if (notify_offset < XC_PAGE_SIZE * count) { - notify.index += notify_offset; - notify.action |= UNMAP_NOTIFY_CLEAR_BYTE; - } - if (notify_port != -1) { - notify.event_channel_port = notify_port; - notify.action |= UNMAP_NOTIFY_SEND_EVENT; - } - if (notify.action) - err = ioctl(fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, ¬ify); - if (err) { - GSERROR(xgs->logger, "ioctl SET_UNMAP_NOTIFY failed"); - munmap(area, count * XC_PAGE_SIZE); - area = NULL; - } - - memcpy(refs, gref_info->gref_ids, count * sizeof(uint32_t)); - - out_remove_fdmap: - /* Removing the mapping from the file descriptor does not cause the pages to - * be deallocated until the mapping is removed. - */ - gref_drop.index = gref_info->index; - gref_drop.count = count; - ioctl(fd, IOCTL_GNTALLOC_DEALLOC_GREF, &gref_drop); - out: - free(gref_info); - return area; -} - -int xc_gntshr_munmap(xc_gntshr *xgs, - void *start_address, uint32_t count) -{ - return munmap(start_address, count * XC_PAGE_SIZE); -} - static struct xc_osdep_ops *linux_osdep_init(xc_interface *xch, enum xc_osdep_type type) { switch ( type ) diff --git a/tools/libxc/xc_minios.c b/tools/libxc/xc_minios.c index fd7def6..22d985c 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include #include #include @@ -38,7 +36,6 @@ #include "xc_private.h" void minios_interface_close_fd(int fd); -void minios_gnttab_close_fd(int fd); extern void minios_interface_close_fd(int fd); @@ -202,76 +199,6 @@ void *xc_memalign(xc_interface *xch, size_t alignment, size_t size) return memalign(alignment, size); } -int osdep_gnttab_open(xc_gnttab *xgt) -{ - int fd = alloc_fd(FTYPE_GNTMAP); - if ( fd == -1 ) - return -1; - gntmap_init(&files[fd].gntmap); - xgt->fd = fd; - return 0; -} - -int osdep_gnttab_close(xc_gnttab *xgt) -{ - if ( xgt->fd == -1 ) - return 0; - - return close(xgt->fd); -} - -void minios_gnttab_close_fd(int fd) -{ - gntmap_fini(&files[fd].gntmap); - files[fd].type = FTYPE_NONE; -} - -void *osdep_gnttab_grant_map(xc_gnttab *xgt, - uint32_t count, int flags, int prot, - uint32_t *domids, uint32_t *refs, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - int fd = xgt->fd; - int stride = 1; - if (flags & XC_GRANT_MAP_SINGLE_DOMAIN) - stride = 0; - if (notify_offset != -1 || notify_port != -1) { - errno = ENOSYS; - return NULL; - } - return gntmap_map_grant_refs(&files[fd].gntmap, - count, domids, stride, - refs, prot & PROT_WRITE); -} - -int xc_gnttab_munmap(xc_gnttab *xgt, void *start_address, uint32_t count) -{ - int fd = xgt->fd; - int ret; - ret = gntmap_munmap(&files[fd].gntmap, - (unsigned long) start_address, - count); - if (ret < 0) { - errno = -ret; - return -1; - } - return ret; -} - -int xc_gnttab_set_max_grants(xc_gnttab *xgt, uint32_t count) -{ - int fd = xgt->fd; - int ret; - ret = gntmap_set_max_grants(&files[fd].gntmap, - count); - if (ret < 0) { - errno = -ret; - return -1; - } - return ret; -} - static struct xc_osdep_ops *minios_osdep_init(xc_interface *xch, enum xc_osdep_type type) { switch ( type ) diff --git a/tools/libxc/xc_nogntshr.c b/tools/libxc/xc_nogntshr.c deleted file mode 100644 index 9aa6064..0000000 --- a/tools/libxc/xc_nogntshr.c +++ /dev/null @@ -1,46 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2007-2008, D G Murray - * - * 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 . - */ - -#include - -#include "xc_private.h" - -int osdep_gntshr_open(xc_gnttab *xgt) -{ - return -1; -} - -int osdep_gntshr_close(xc_gnttab *xgt) -{ - return 0; -} - -void *osdep_gntshr_share_pages(xc_gntshr *xgs, - uint32_t domid, int count, - uint32_t *refs, int writable, - uint32_t notify_offset, - evtchn_port_t notify_port) -{ - abort() -} - -int xc_gntshr_munmap(xc_gntshr *xgs, - void *start_address, uint32_t count) -{ - abort(); -} diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 7f52a5d..85e6f02 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -249,86 +249,6 @@ int do_xen_hypercall(xc_interface *xch, privcmd_hypercall_t *hypercall) return xch->ops->u.privcmd.hypercall(xch, xch->ops_handle, hypercall); } -xc_gnttab *xc_gnttab_open(xentoollog_logger *logger, unsigned open_flags) -{ - xc_gnttab *xgt = malloc(sizeof(*xgt)); - int rc; - - if (!xgt) return NULL; - - xgt->fd = -1; - xgt->logger = logger; - xgt->logger_tofree = NULL; - - if (!xgt->logger) { - xgt->logger = xgt->logger_tofree = - (xentoollog_logger*) - xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); - if (!xgt->logger) goto err; - } - - rc = osdep_gnttab_open(xgt); - if ( rc < 0 ) goto err; - - return xgt; - -err: - osdep_gnttab_close(xgt); - xtl_logger_destroy(xgt->logger_tofree); - free(xgt); - return NULL; -} - -int xc_gnttab_close(xc_gnttab *xgt) -{ - int rc; - - rc = osdep_gnttab_close(xgt); - xtl_logger_destroy(xgt->logger_tofree); - free(xgt); - return rc; -} - -xc_gntshr *xc_gntshr_open(xentoollog_logger *logger, unsigned open_flags) -{ - xc_gntshr *xgs = malloc(sizeof(*xgs)); - int rc; - - if (!xgs) return NULL; - - xgs->fd = -1; - xgs->logger = logger; - xgs->logger_tofree = NULL; - - if (!xgs->logger) { - xgs->logger = xgs->logger_tofree = - (xentoollog_logger*) - xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0); - if (!xgs->logger) goto err; - } - - rc = osdep_gntshr_open(xgs); - if ( rc < 0 ) goto err; - - return xgs; - -err: - osdep_gntshr_close(xgs); - xtl_logger_destroy(xgs->logger_tofree); - free(xgs); - return NULL; -} - -int xc_gntshr_close(xc_gntshr *xgs) -{ - int rc; - - rc = osdep_gntshr_close(xgs); - xtl_logger_destroy(xgs->logger_tofree); - free(xgs); - return rc; -} - static pthread_key_t errbuf_pkey; static pthread_once_t errbuf_pkey_once = PTHREAD_ONCE_INIT; diff --git a/tools/libxc/xc_private.h b/tools/libxc/xc_private.h index 35c99e0..a32accb 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -123,30 +123,6 @@ struct xc_interface_core { xc_osdep_handle ops_handle; /* opaque data for xc_osdep_ops */ }; -struct xengntdev_handle { - xentoollog_logger *logger, *logger_tofree; - int fd; -}; - -int osdep_gnttab_open(xc_gnttab *xgt); -int osdep_gnttab_close(xc_gnttab *xgt); - -#define XC_GRANT_MAP_SINGLE_DOMAIN 0x1 -void *osdep_gnttab_grant_map(xc_gnttab *xgt, - uint32_t count, int flags, int prot, - uint32_t *domids, uint32_t *refs, - uint32_t notify_offset, - evtchn_port_t notify_port); - -int osdep_gntshr_open(xc_gntshr *xgs); -int osdep_gntshr_close(xc_gntshr *xgs); - -void *osdep_gntshr_share_pages(xc_gntshr *xgs, - uint32_t domid, int count, - uint32_t *refs, int writable, - uint32_t notify_offset, - evtchn_port_t notify_port); - void xc_report_error(xc_interface *xch, int code, const char *fmt, ...) __attribute__((format(printf,3,4))); void xc_reportv(xc_interface *xch, xentoollog_logger *lg, xentoollog_level, diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index c161046..178771f 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -78,8 +78,10 @@ init-xenstore-domain.o: CFLAGS += $(CFLAGS_libxenguest) init-xenstore-domain: init-xenstore-domain.o $(LIBXENSTORE) $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(LDLIBS_libxenguest) $(LDLIBS_libxenstore) -o $@ $(APPEND_LDFLAGS) +$(XENSTORED_OBJS): CFLAGS += $(CFLAGS_libxengnttab) + xenstored: $(XENSTORED_OBJS) - $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) + $(CC) $^ $(LDFLAGS) $(LDLIBS_libxenevtchn) $(LDLIBS_libxengnttab) $(LDLIBS_libxenctrl) $(SOCKET_LIBS) -o $@ $(APPEND_LDFLAGS) xenstored.a: $(XENSTORED_OBJS) $(AR) cr $@ $^ diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index 8c853c9..624737d 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -20,12 +20,14 @@ #define _XENSTORED_CORE_H #include +#include #include #include #include #include #include + #include "xenstore_lib.h" #include "list.h" #include "tdb.h" @@ -196,7 +198,7 @@ void finish_daemonize(void); /* Open a pipe for signal handling */ void init_pipe(int reopen_log_pipe[2]); -xc_gnttab **xcg_handle; +xengnttab_handle **xgt_handle; #endif /* _XENSTORED_CORE_H */ diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 6ceec29..414a9fd 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -34,7 +34,7 @@ #include static xc_interface **xc_handle; -xc_gnttab **xcg_handle; +xengnttab_handle **xgt_handle; static evtchn_port_t virq_port; xenevtchn_handle *xce_handle = NULL; @@ -166,9 +166,9 @@ static int readchn(struct connection *conn, void *data, unsigned int len) static void *map_interface(domid_t domid, unsigned long mfn) { - if (*xcg_handle != NULL) { + if (*xgt_handle != NULL) { /* this is the preferred method */ - return xc_gnttab_map_grant_ref(*xcg_handle, domid, + return xengnttab_map_grant_ref(*xgt_handle, domid, GNTTAB_RESERVED_XENSTORE, PROT_READ|PROT_WRITE); } else { return xc_map_foreign_range(*xc_handle, domid, @@ -178,8 +178,8 @@ static void *map_interface(domid_t domid, unsigned long mfn) static void unmap_interface(void *interface) { - if (*xcg_handle != NULL) - xc_gnttab_munmap(*xcg_handle, interface, 1); + if (*xgt_handle != NULL) + xengnttab_unmap(*xgt_handle, interface, 1); else munmap(interface, XC_PAGE_SIZE); } @@ -577,9 +577,9 @@ static int close_xc_handle(void *_handle) return 0; } -static int close_xcg_handle(void *_handle) +static int close_xgt_handle(void *_handle) { - xc_gnttab_close(*(xc_gnttab **)_handle); + xengnttab_close(*(xengnttab_handle **)_handle); return 0; } @@ -634,15 +634,15 @@ void domain_init(void) talloc_set_destructor(xc_handle, close_xc_handle); - xcg_handle = talloc(talloc_autofree_context(), xc_gnttab*); - if (!xcg_handle) + xgt_handle = talloc(talloc_autofree_context(), xengnttab_handle*); + if (!xgt_handle) barf_perror("Failed to allocate domain gnttab handle"); - *xcg_handle = xc_gnttab_open(NULL, 0); - if (*xcg_handle == NULL) + *xgt_handle = xengnttab_open(NULL, 0); + if (*xgt_handle == NULL) xprintf("WARNING: Failed to open connection to gnttab\n"); else - talloc_set_destructor(xcg_handle, close_xcg_handle); + talloc_set_destructor(xgt_handle, close_xgt_handle); xce_handle = xenevtchn_open(NULL, 0); diff --git a/tools/xenstore/xenstored_minios.c b/tools/xenstore/xenstored_minios.c index b686e1c..c94493e 100644 --- a/tools/xenstore/xenstored_minios.c +++ b/tools/xenstore/xenstored_minios.c @@ -17,7 +17,6 @@ */ #include #include -#include #include "xenstored_core.h" #include @@ -50,12 +49,12 @@ evtchn_port_t xenbus_evtchn(void) void *xenbus_map(void) { - return xc_gnttab_map_grant_ref(*xcg_handle, xenbus_master_domid(), + return xengnttab_map_grant_ref(*xgt_handle, xenbus_master_domid(), GNTTAB_RESERVED_XENSTORE, PROT_READ|PROT_WRITE); } void unmap_xenbus(void *interface) { - xc_gnttab_munmap(*xcg_handle, interface, 1); + xengnttab_unmap(*xgt_handle, interface, 1); }