[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH XEN v2 08/15] tools: Refactor /dev/xen/gnt{dev, shr} wrappers into libxengnttab.
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. XXX consider combining into a single namespace (i.e. with xengnttab_handle having two open fd's in it on Linux) 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 (EVTCHNOP) 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 <ian.campbell@xxxxxxxxxx> --- 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. --- .gitignore | 2 + docs/misc/toolstack-library-abis.pandoc | 38 ++-- stubdom/Makefile | 19 +- tools/Makefile | 4 + tools/Rules.mk | 14 +- tools/console/Makefile | 5 +- tools/console/daemon/io.c | 21 +- tools/libvchan/Makefile | 8 +- tools/libvchan/init.c | 24 +-- 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 | 44 ----- tools/libxc/xc_nognttab.c | 48 ----- tools/libxc/xc_private.c | 80 -------- tools/libxc/xc_private.h | 24 --- tools/libxenevtchn/minios.c | 5 +- tools/libxengnttab/Makefile | 69 +++++++ tools/libxengnttab/gntshr_core.c | 89 +++++++++ tools/libxengnttab/gntshr_unimp.c | 59 ++++++ tools/libxengnttab/gnttab_core.c | 118 ++++++++++++ tools/libxengnttab/gnttab_unimp.c | 86 +++++++++ tools/libxengnttab/include/xengnttab.h | 215 +++++++++++++++++++++ tools/libxengnttab/libxengnttab.map | 23 +++ tools/libxengnttab/linux.c | 326 ++++++++++++++++++++++++++++++++ tools/libxengnttab/minios.c | 114 +++++++++++ tools/libxengnttab/private.h | 47 +++++ tools/xenstore/Makefile | 4 +- tools/xenstore/xenstored_core.h | 4 +- tools/xenstore/xenstored_domain.c | 24 +-- tools/xenstore/xenstored_minios.c | 5 +- 37 files changed, 1432 insertions(+), 849 deletions(-) create mode 100644 tools/libxc/xc_gnttab_compat.c delete mode 100644 tools/libxc/xc_nogntshr.c delete mode 100644 tools/libxc/xc_nognttab.c create mode 100644 tools/libxengnttab/Makefile create mode 100644 tools/libxengnttab/gntshr_core.c create mode 100644 tools/libxengnttab/gntshr_unimp.c create mode 100644 tools/libxengnttab/gnttab_core.c create mode 100644 tools/libxengnttab/gnttab_unimp.c create mode 100644 tools/libxengnttab/include/xengnttab.h create mode 100644 tools/libxengnttab/libxengnttab.map create mode 100644 tools/libxengnttab/linux.c create mode 100644 tools/libxengnttab/minios.c create mode 100644 tools/libxengnttab/private.h diff --git a/.gitignore b/.gitignore index 61167d9..8cbd177 100644 --- a/.gitignore +++ b/.gitignore @@ -61,6 +61,7 @@ stubdom/ioemu stubdom/xenstore stubdom/libxentoollog-* stubdom/libxenevtchn-* +stubdom/libxengnttab-* stubdom/libxc-* stubdom/lwip-* stubdom/mini-os-* @@ -89,6 +90,7 @@ config/Stubdom.mk config/Docs.mk tools/libxentoollog/headers.chk tools/libxenevtchn/headers.chk +tools/libxengnttab/headers.chk tools/blktap2/daemon/blktapctrl tools/blktap2/drivers/img2qcow tools/blktap2/drivers/lock-util diff --git a/docs/misc/toolstack-library-abis.pandoc b/docs/misc/toolstack-library-abis.pandoc index d7ae875..6b6146a 100644 --- a/docs/misc/toolstack-library-abis.pandoc +++ b/docs/misc/toolstack-library-abis.pandoc @@ -128,6 +128,29 @@ Interface Underlying interface Known external us `xenevtchn_unbind` `IOCTL_EVTCHN_UNBIND` qemu-pv `xenevtchn_unmask` `write(2)` qemu-dm, qemu-pv +## `libxengnttab`: grant tables + +Interacting with Grant Tables via `/dev/xen/gnt{shr,alloc}`. + +Interface Underlying interface Known external users +--------------------------------- ------------------------------ -------------------- +`xengnttab_map_domain_grant_refs` `IOCTL_GNTDEV_SET_MAX_GRANTS` +`xengnttab_map_grant_ref_notify` `IOCTL_GNTDEV_MAP_GRANT_REF` +`xengnttab_map_grant_ref` `IOCTL_GNTDEV_MAP_GRANT_REF` qemu-pv +`xengnttab_map_grant_refs` `IOCTL_GNTDEV_SET_MAX_GRANTS` qemu-pv +`xengnttab_munmap` `munmap(2)` qemu-pv +`xengnttab_open` `open(2)` qemu-pv +`xengnttab_close` `close(2)` qemu-pv +`xengnttab_set_max_grants` `IOCTL_GNTDEV_SET_MAX_GRANTS` +`xengntshr_close` `close(2)` +`xengntshr_munmap` `munmap(2)` +`xengntshr_open` `open(2)` +`xengntshr_share_page_notify` `IOCTL_GNTALLOC_ALLOC_GREF` +`xengntshr_share_pages` `IOCTL_GNTALLOC_ALLOC_GREF` + +`xengnt???_*_notify` also use `IOCTL_GNTALLOC_SET_UNMAP_NOTIFY`, +`IOCTL_GNTALLOC_SET_UNMAP_NOTIFY`, etc + # Unstable libraries These libraries do not provide a stable interface and are required to @@ -181,23 +204,10 @@ Interface Underlying interface Known external us ### Grant tables Interacting with Grant Tables via `__HYPERVISOR_grant_table_op` -(`GNTTABOP_*`) or `/dev/xen/gnt{shr,alloc}`. +(`GNTTABOP_*`)`. Interface Underlying interface Known external users --------------------------------- ------------------------------ -------------------- -`xc_gnttab_map_domain_grant_refs` `IOCTL_GNTDEV_SET_MAX_GRANTS` -`xc_gnttab_map_grant_ref_notify` `IOCTL_GNTDEV_MAP_GRANT_REF` -`xc_gnttab_map_grant_ref` `IOCTL_GNTDEV_MAP_GRANT_REF` qemu-pv -`xc_gnttab_map_grant_refs` `IOCTL_GNTDEV_SET_MAX_GRANTS` qemu-pv -`xc_gnttab_munmap` `munmap(2)` qemu-pv -`xc_gnttab_open` `open(2)` qemu-pv -`xc_gnttab_close` `close(2)` qemu-pv -`xc_gnttab_set_max_grants` `IOCTL_GNTDEV_SET_MAX_GRANTS` -`xc_gntshr_close` `close(2)` -`xc_gntshr_munmap` `munmap(2)` -`xc_gntshr_open` `open(2)` -`xc_gntshr_share_page_notify` `IOCTL_GNTALLOC_ALLOC_GREF` -`xc_gntshr_share_pages` `IOCTL_GNTALLOC_ALLOC_GREF` `xc_gnttab_op` `__HYPERVISOR_grant_table_op` `xc_gnttab_get_version` `GNTTABOP_get_version` `xc_gnttab_map_table_v1` `GNTTABOP_setup_table` diff --git a/stubdom/Makefile b/stubdom/Makefile index b4dd39a..7eab97f 100644 --- a/stubdom/Makefile +++ b/stubdom/Makefile @@ -324,6 +324,12 @@ mk-headers-$(XEN_TARGET_ARCH): $(IOEMU_LINKFARM_TARGET) ln -sf $(XEN_ROOT)/tools/libxenevtchn/include/*.h include/ && \ ln -sf $(XEN_ROOT)/tools/libxenevtchn/*.c . && \ ln -sf $(XEN_ROOT)/tools/libxenevtchn/Makefile . ) + mkdir -p libxengnttab-$(XEN_TARGET_ARCH)/include + [ -h libxengnttab-$(XEN_TARGET_ARCH)/Makefile ] || ( cd libxengnttab-$(XEN_TARGET_ARCH) && \ + ln -sf $(XEN_ROOT)/tools/libxengnttab/*.h . && \ + ln -sf $(XEN_ROOT)/tools/libxengnttab/include/*.h include/ && \ + ln -sf $(XEN_ROOT)/tools/libxengnttab/*.c . && \ + ln -sf $(XEN_ROOT)/tools/libxengnttab/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 . && \ @@ -369,12 +375,23 @@ libxenevtchn-$(XEN_TARGET_ARCH)/libxenevtchn.a: $(NEWLIB_STAMPFILE) CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libxenevtchn-$(XEN_TARGET_ARCH) ####### +# libxengnttab +####### + +.PHONY: libxengnttab +libxengnttab: libxengnttab-$(XEN_TARGET_ARCH)/libxengnttab.a +libxengnttab-$(XEN_TARGET_ARCH)/libxengnttab.a: $(NEWLIB_STAMPFILE) + $(MAKE) -C $(XEN_ROOT)/tools/include + $(MAKE) DESTDIR= -C $(MINI_OS) links + CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= -C libxengnttab-$(XEN_TARGET_ARCH) + +####### # libxc ####### .PHONY: libxc libxc: libxc-$(XEN_TARGET_ARCH)/libxenctrl.a libxc-$(XEN_TARGET_ARCH)/libxenguest.a -libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: libxentoollog libxenevtchn cross-zlib +libxc-$(XEN_TARGET_ARCH)/libxenctrl.a: libxentoollog libxenevtchn libxengnttab cross-zlib $(MAKE) -C $(XEN_ROOT)/tools/include $(MAKE) DESTDIR= -C $(MINI_OS) links CPPFLAGS="$(TARGET_CPPFLAGS)" CFLAGS="$(TARGET_CFLAGS)" $(MAKE) DESTDIR= CONFIG_LIBXC_MINIOS=y -C libxc-$(XEN_TARGET_ARCH) diff --git a/tools/Makefile b/tools/Makefile index 3497c53..d3bf571 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -5,6 +5,7 @@ SUBDIRS-y := SUBDIRS-y += include SUBDIRS-y += libxentoollog SUBDIRS-y += libxenevtchn +SUBDIRS-y += libxengnttab SUBDIRS-y += libxc SUBDIRS-$(FLASK_ENABLE) += flask SUBDIRS-y += xenstore @@ -250,9 +251,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/libxentoollog/include \ -I$(XEN_ROOT)/tools/libxenevtchn/include \ + -I$(XEN_ROOT)/tools/libxengnttab/include \ -I$(XEN_ROOT)/tools/libxc/include \ -I$(XEN_ROOT)/tools/xenstore/include \ -I$(XEN_ROOT)/tools/xenstore/compat/include \ @@ -261,6 +264,7 @@ subdir-all-qemu-xen-dir: qemu-xen-dir-find -L$(XEN_ROOT)/tools/xenstore \ -Wl,-rpath-link=$(XEN_ROOT)/tools/libxentoollog \ -Wl,-rpath-link=$(XEN_ROOT)/tools/libxenevtchn \ + -Wl,-rpath-link=$(XEN_ROOT)/tools/libxengnttab \ $(QEMU_UPSTREAM_RPATH)" \ --bindir=$(LIBEXEC_BIN) \ --datadir=$(SHAREDIR)/qemu-xen \ diff --git a/tools/Rules.mk b/tools/Rules.mk index f675fa7..e3923e2 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/libxentoollog XEN_LIBXENEVTCHN = $(XEN_ROOT)/tools/libxenevtchn +XEN_LIBXENGNTTAB = $(XEN_ROOT)/tools/libxengnttab 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_libxenctrl) $(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 0141d7f..1d4b6ae 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) @@ -27,8 +25,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: $(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 8829b09..7f2f861 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -23,6 +23,7 @@ #include "utils.h" #include "io.h" #include <xenevtchn.h> +#include <xengnttab.h> #include <xenstore.h> #include <xen/io/console.h> #include <xen/grant_table.h> @@ -73,7 +74,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; @@ -521,8 +522,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_munmap(xgt_handle, dom->interface, 1); else munmap(dom->interface, XC_PAGE_SIZE); dom->interface = NULL; @@ -553,9 +554,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; @@ -1030,8 +1031,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)); } @@ -1207,9 +1208,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/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 fef6c8d..d1c1191 100644 --- a/tools/libvchan/init.c +++ b/tools/libvchan/init.c @@ -79,7 +79,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); @@ -105,7 +105,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; @@ -119,7 +119,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; @@ -129,9 +129,9 @@ out: return ring_ref; out_unmap_left: if (pages_left) - xc_gntshr_munmap(ctrl->gntshr, ctrl->read.buffer, pages_left); + xengntshr_munmap(ctrl->gntshr, ctrl->read.buffer, pages_left); out_ring: - xc_gntshr_munmap(ctrl->gntshr, ring, 1); + xengntshr_munmap(ctrl->gntshr, ring, 1); ring_ref = -1; ctrl->ring = NULL; ctrl->write.order = ctrl->read.order = 0; @@ -143,7 +143,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); @@ -173,7 +173,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; @@ -191,7 +191,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; @@ -203,10 +203,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, + xengnttab_munmap(ctrl->gnttab, ctrl->write.buffer, 1 << (ctrl->write.order - PAGE_SHIFT)); out_unmap_ring: - xc_gnttab_munmap(ctrl->gnttab, ctrl->ring, 1); + xengnttab_munmap(ctrl->gnttab, ctrl->ring, 1); ctrl->ring = 0; ctrl->write.order = ctrl->read.order = 0; rv = -1; @@ -326,7 +326,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; @@ -414,7 +414,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 4bd15ed..439e2bd 100644 --- a/tools/libvchan/io.c +++ b/tools/libvchan/io.c @@ -365,10 +365,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_munmap(ctrl->gntshr, ctrl->ring, 1); } else { ctrl->ring->cli_live = 0; - xc_gnttab_munmap(ctrl->gnttab, ctrl->ring, 1); + xengnttab_munmap(ctrl->gnttab, ctrl->ring, 1); } } if (ctrl->event) { @@ -378,10 +378,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 0517dda..950c6e0 100644 --- a/tools/libvchan/libxenvchan.h +++ b/tools/libvchan/libxenvchan.h @@ -46,7 +46,7 @@ #include <xen/io/libxenvchan.h> #include <xen/sys/evtchn.h> #include <xenevtchn.h> -#include <xenctrl.h> +#include <xengnttab.h> struct libxenvchan_ring { /* Pointer into the shared page. Offsets into buffer. */ @@ -67,8 +67,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 19ad0df..3c939ce 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -42,12 +42,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 @@ -127,6 +128,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) @@ -210,7 +213,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 e60aa34..9675ebb 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 <Derek.Murray@xxxxxxxxxxxx> - * * 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; @@ -118,8 +115,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, @@ -1528,116 +1523,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); @@ -1648,59 +1533,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 53cd670..8c7e906 100644 --- a/tools/libxc/xc_gnttab.c +++ b/tools/libxc/xc_gnttab.c @@ -144,59 +144,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..1f496a1 --- /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 <xengnttab.h> + +#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_munmap(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_munmap(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 f2c7f10..7246b79 100644 --- a/tools/libxc/xc_linux_osdep.c +++ b/tools/libxc/xc_linux_osdep.c @@ -32,8 +32,6 @@ #include <sys/ioctl.h> #include <xen/memory.h> -#include <xen/sys/gntdev.h> -#include <xen/sys/gntalloc.h> #include "xenctrl.h" #include "xenctrlosdep.h" @@ -42,9 +40,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; @@ -456,281 +451,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 * getpagesize())) ) - 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 2cc9ea9..947b19a 100644 --- a/tools/libxc/xc_minios.c +++ b/tools/libxc/xc_minios.c @@ -24,8 +24,6 @@ #include <mini-os/os.h> #include <mini-os/mm.h> #include <mini-os/lib.h> -#include <mini-os/gntmap.h> -#include <sys/mman.h> #include <xen/memory.h> #include <unistd.h> @@ -39,7 +37,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); @@ -203,76 +200,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 6681018..0000000 --- a/tools/libxc/xc_nogntshr.c +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> - * - * 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. - * - */ - -#include <stdlib.h> - -#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_nognttab.c b/tools/libxc/xc_nognttab.c deleted file mode 100644 index 4b4a2ca..0000000 --- a/tools/libxc/xc_nognttab.c +++ /dev/null @@ -1,48 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> - * - * 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. - * - */ - -#include <stdlib.h> - -#include "xc_private.h" - -int osdep_gnttab_open(xc_gnttab *xgt) -{ - return -1; -} - -int osdep_gnttab_close(xc_gnttab *xgt) -{ - return 0; -} - -int xc_gnttab_set_max_grants(xc_gnttab *xgt, uint32_t count) -{ - 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) -{ - abort(); -} - -int xc_gnttab_munmap(xc_gnttab *xgt, void *start_address, uint32_t count) -{ - abort(); -} diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index b2c3c06..e411210 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -250,86 +250,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 81af034..61f2f45 100644 --- a/tools/libxc/xc_private.h +++ b/tools/libxc/xc_private.h @@ -124,30 +124,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/libxenevtchn/minios.c b/tools/libxenevtchn/minios.c index 1408182..aefaf2c 100644 --- a/tools/libxenevtchn/minios.c +++ b/tools/libxenevtchn/minios.c @@ -24,13 +24,12 @@ #include <mini-os/events.h> #include <mini-os/wait.h> -#include <sys/socket.h> - #include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdint.h> +#include <unistd.h> #include <inttypes.h> #include <malloc.h> @@ -40,8 +39,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/libxengnttab/Makefile b/tools/libxengnttab/Makefile new file mode 100644 index 0000000..15bf0fe --- /dev/null +++ b/tools/libxengnttab/Makefile @@ -0,0 +1,69 @@ +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 headers.chk diff --git a/tools/libxengnttab/gntshr_core.c b/tools/libxengnttab/gntshr_core.c new file mode 100644 index 0000000..3a3da5a --- /dev/null +++ b/tools/libxengnttab/gntshr_core.c @@ -0,0 +1,89 @@ +/****************************************************************************** + * + * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> + * + * 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. + * + * Split out from xc_gnttab.c + */ + +#include <stdlib.h> + +#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; + + 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_munmap(xengntshr_handle *xgs, void *start_address, uint32_t count) +{ + return osdep_gntshr_munmap(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/libxengnttab/gntshr_unimp.c b/tools/libxengnttab/gntshr_unimp.c new file mode 100644 index 0000000..c0acc21 --- /dev/null +++ b/tools/libxengnttab/gntshr_unimp.c @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> + * + * 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. + * + * Split out from xc_gnttab.c + */ + +#include <stdlib.h> + +#include "private.h" + +xengntshr_handle *xengntshr_open(xentoollog_logger *logger, unsigned open_flags) +{ + return NULL; +} + +int xengntshr_close(xengntshr_handle *xgs) +{ + return 0; +} + +void *xengntshr_share_pages(xengntshr_handle *xcg, uint32_t domid, + int count, uint32_t *refs, int writable) +{ + abort(); +} + +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 xengntshr_munmap(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/libxengnttab/gnttab_core.c b/tools/libxengnttab/gnttab_core.c new file mode 100644 index 0000000..2b7bdfd --- /dev/null +++ b/tools/libxengnttab/gnttab_core.c @@ -0,0 +1,118 @@ +/****************************************************************************** + * + * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> + * + * 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. + * + * Split out from xc_gnttab.c + */ + +#include <stdlib.h> + +#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; + + 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_munmap(xengnttab_handle *xgt, void *start_address, uint32_t count) +{ + return osdep_gnttab_munmap(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/libxengnttab/gnttab_unimp.c b/tools/libxengnttab/gnttab_unimp.c new file mode 100644 index 0000000..ca5618a --- /dev/null +++ b/tools/libxengnttab/gnttab_unimp.c @@ -0,0 +1,86 @@ +/****************************************************************************** + * + * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> + * + * 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. + * + * Split out from xc_gnttab.c + */ + +#include <stdlib.h> + +#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_munmap(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/libxengnttab/include/xengnttab.h b/tools/libxengnttab/include/xengnttab.h new file mode 100644 index 0000000..b333662 --- /dev/null +++ b/tools/libxengnttab/include/xengnttab.h @@ -0,0 +1,215 @@ +/* + * 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. + * + * Split off from: + * xenctrl.h + * + * A library for low-level access to the Xen control interfaces. + * + * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> + */ +#ifndef XENGNTTAB_H +#define XENGNTTAB_H + +#include <stdint.h> + +#include <xen/grant_table.h> +#include <xen/event_channel.h> + +/* Callers who don't care don't need to #include <xentoollog.h> */ +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_munmap. 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_munmap. 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_munmap. 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_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 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_munmap(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_munmap(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/libxengnttab/libxengnttab.map b/tools/libxengnttab/libxengnttab.map new file mode 100644 index 0000000..b46f9aa --- /dev/null +++ b/tools/libxengnttab/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_munmap; + + xengntshr_open; + xengntshr_close; + + xengntshr_share_page_notify; + xengntshr_share_pages; + + xengntshr_munmap; + local: *; /* Do not expose anything by default */ +}; diff --git a/tools/libxengnttab/linux.c b/tools/libxengnttab/linux.c new file mode 100644 index 0000000..ad912a6 --- /dev/null +++ b/tools/libxengnttab/linux.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2007-2008, D G Murray <Derek.Murray@xxxxxxxxxxxx> + * + * 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. + * + * Split out from xc_linux_osdep.c + */ + +#include <fcntl.h> +#include <errno.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include <sys/ioctl.h> +#include <sys/mman.h> + +#include <xen/sys/gntdev.h> +#include <xen/sys/gntalloc.h> + +#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_munmap(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 * getpagesize())) ) + 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_munmap(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/libxengnttab/minios.c b/tools/libxengnttab/minios.c new file mode 100644 index 0000000..b593232 --- /dev/null +++ b/tools/libxengnttab/minios.c @@ -0,0 +1,114 @@ +/* + * + * Copyright 2007-2008 Samuel Thibault <samuel.thibault@xxxxxxxxxxxxx>. + * 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. + * + * Splitfrom xc_minios.c + */ + +#include <mini-os/types.h> +#include <mini-os/os.h> +#include <mini-os/lib.h> + +#include <mini-os/gntmap.h> +#include <sys/mman.h> + +#include <errno.h> +#include <unistd.h> + +#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_munmap(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/libxengnttab/private.h b/tools/libxengnttab/private.h new file mode 100644 index 0000000..cb7e2cc --- /dev/null +++ b/tools/libxengnttab/private.h @@ -0,0 +1,47 @@ +#ifndef XENGNTTAB_PRIVATE_H +#define XENGNTTAB_PRIVATE_H + +#include <xentoollog.h> +#include <xengnttab.h> + +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_munmap(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_munmap(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/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 dcf95b5..2b01076 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -21,12 +21,14 @@ #define _XENSTORED_CORE_H #include <xenctrl.h> +#include <xengnttab.h> #include <sys/types.h> #include <dirent.h> #include <stdbool.h> #include <stdint.h> #include <errno.h> + #include "xenstore_lib.h" #include "list.h" #include "tdb.h" @@ -197,7 +199,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 b649107..aa4d896 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -35,7 +35,7 @@ #include <xen/grant_table.h> static xc_interface **xc_handle; -xc_gnttab **xcg_handle; +xengnttab_handle **xgt_handle; static evtchn_port_t virq_port; xenevtchn_handle *xce_handle = NULL; @@ -167,9 +167,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, @@ -179,8 +179,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_munmap(*xgt_handle, interface, 1); else munmap(interface, XC_PAGE_SIZE); } @@ -578,9 +578,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; } @@ -635,15 +635,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 f9c921e..f929e31 100644 --- a/tools/xenstore/xenstored_minios.c +++ b/tools/xenstore/xenstored_minios.c @@ -18,7 +18,6 @@ */ #include <sys/types.h> #include <sys/mman.h> -#include <xenctrl.h> #include "xenstored_core.h" #include <xen/grant_table.h> @@ -51,12 +50,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_munmap(*xgt_handle, interface, 1); } -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |