From 85f926efaa62d8a1db41d0f05897fd9230bc83a9 Mon Sep 17 00:00:00 2001 From: Alexander Tereshkin Date: Sat, 12 May 2012 18:22:16 +0400 Subject: [PATCH 1/5] Removed unnecessary access to /proc/u2mfn. --- vchan/init.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/vchan/init.c b/vchan/init.c index a8192bf9..90e1e21a 100644 --- a/vchan/init.c +++ b/vchan/init.c @@ -52,7 +52,6 @@ static int ring_init(struct libvchan *ctrl) mfn = virtual_to_mfn(ring); #else - int u2mfn = open("/proc/u2mfn", O_RDONLY); ring = (struct vchan_interface *) u2mfn_alloc_kpage (); if (ring == MAP_FAILED) @@ -60,7 +59,6 @@ static int ring_init(struct libvchan *ctrl) if (u2mfn_get_last_mfn (&mfn) < 0) return -1; - close(u2mfn); #endif ctrl->ring = ring; From 0f13ea2a845a03c2b5f1c018a8521f959de03cc1 Mon Sep 17 00:00:00 2001 From: Alexander Tereshkin Date: Sat, 12 May 2012 18:32:36 +0400 Subject: [PATCH 2/5] Fixed a potential memory leak. --- vchan/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vchan/init.c b/vchan/init.c index 90e1e21a..58ddffd7 100644 --- a/vchan/init.c +++ b/vchan/init.c @@ -264,9 +264,9 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) if (!ref) goto fail; ctrl->ring_ref = atoi(ref); + free(ref); if (!ctrl->ring_ref) goto fail; - free(ref); snprintf(buf, sizeof buf, "/local/domain/%d/device/vchan/%d/event-channel", domain, devno); @@ -274,9 +274,9 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) if (!ref) goto fail; remote_port = atoi(ref); + free(ref); if (!remote_port) goto fail; - free(ref); #ifdef XENCTRL_HAS_XC_INTERFACE xcfd = xc_interface_open(NULL, NULL, 0); if (!xcfd) From 7ea3f4a7927013033404e4dba6e10e90e1c49928 Mon Sep 17 00:00:00 2001 From: Alexander Tereshkin Date: Sat, 12 May 2012 19:27:09 +0400 Subject: [PATCH 3/5] vchan modifications for the Windows build. --- vchan/init.c | 160 +++++++++++++++++++++++++++++++++++++++-------- vchan/io.c | 9 ++- vchan/libvchan.h | 19 ++++-- vchan/sources | 22 +++++++ 4 files changed, 178 insertions(+), 32 deletions(-) create mode 100644 vchan/sources diff --git a/vchan/init.c b/vchan/init.c index 58ddffd7..03227686 100644 --- a/vchan/init.c +++ b/vchan/init.c @@ -19,6 +19,8 @@ * */ +#ifndef WINNT + #include #include #include @@ -27,18 +29,66 @@ #include #include #include -#include #include #include #include -#include -#include "libvchan.h" #ifndef CONFIG_STUBDOM #include "../u2mfn/u2mfnlib.h" #else #include #endif +#endif + +#include +#include +#include +#include "libvchan.h" + + +static int fill_ctrl(struct libvchan *ctrl, struct vchan_interface *ring, int ring_ref) +{ + if (!ctrl || !ring) + return -1; + + ctrl->ring = ring; + ctrl->ring_ref = ring_ref; + + ring->cons_in = ring->prod_in = ring->cons_out = ring->prod_out = + 0; + ring->server_closed = ring->client_closed = 0; + ring->debug = 0xaabbccdd; + + return 0; +} + +#ifdef WINNT +static int ring_init(struct libvchan *ctrl) +{ + struct gntmem_handle* h; + grant_ref_t grants[1]; + int result; + struct vchan_interface *ring; + + h = gntmem_open(); + if (h == INVALID_HANDLE_VALUE) + return -1; + + gntmem_set_local_quota(h, 1); + gntmem_set_global_quota(h, 1); + + memset(grants, 0, sizeof(grants)); + ring = gntmem_grant_pages_to_domain(h, 0, 1, grants); + if (!ring) { + gntmem_close(h); + return -1; + } + + return fill_ctrl(ctrl, ring, grants[0]); +} + +#else + static int ring_init(struct libvchan *ctrl) { int mfn; @@ -61,14 +111,11 @@ static int ring_init(struct libvchan *ctrl) return -1; #endif - ctrl->ring = ring; - ctrl->ring_ref = mfn; - ring->cons_in = ring->prod_in = ring->cons_out = ring->prod_out = - 0; - ring->server_closed = ring->client_closed = 0; - ring->debug = 0xaabbccdd; - return 0; + return fill_ctrl(ctrl, ring, mfn); } + +#endif + /** creates event channel; creates "ring-ref" and "event-channel" xenstore entries; @@ -86,12 +133,16 @@ static int server_interface_init(struct libvchan *ctrl, int devno) unsigned int len; /* XXX temp hack end */ #ifdef XENCTRL_HAS_XC_INTERFACE - xc_evtchn *evfd; + xc_evtchn *evfd; #else - int evfd; + EVTCHN evfd; #endif evtchn_port_or_error_t port; +#ifdef WINNT + xs = xs_domain_open(); +#else xs = xs_daemon_open(); +#endif if (!xs) { return ret; } @@ -117,6 +168,10 @@ static int server_interface_init(struct libvchan *ctrl, int devno) if (domid_s) domid = atoi(domid_s); + snprintf(buf, sizeof buf, "device/vchan/%d/version", devno); + if (!xs_write(xs, 0, buf, "2", strlen("2"))) + goto fail2; + snprintf(ref, sizeof ref, "%d", ctrl->ring_ref); snprintf(buf, sizeof buf, "device/vchan/%d/ring-ref", devno); if (!xs_write(xs, 0, buf, ref, strlen(ref))) @@ -151,8 +206,12 @@ static int server_interface_init(struct libvchan *ctrl, int devno) if (ret) #ifdef XENCTRL_HAS_XC_INTERFACE xc_evtchn_close(evfd); +#else +#ifdef WINNT + xc_evtchn_close(evfd); #else close(evfd); +#endif #endif fail: xs_daemon_close(xs); @@ -197,6 +256,8 @@ struct libvchan *libvchan_server_init(int devno) return ctrl; } +#ifndef WINNT + int libvchan_server_handle_connected(struct libvchan *ctrl) { struct xs_handle *xs; @@ -241,14 +302,16 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) unsigned int len; struct xs_handle *xs; #ifdef XENCTRL_HAS_XC_INTERFACE - xc_interface *xcfd; + xc_interface *xcfd; #else int xcfd; #endif + int xcg; char buf[64]; char *ref; + int version; #ifdef XENCTRL_HAS_XC_INTERFACE - xc_evtchn *evfd; + xc_evtchn *evfd; #else int evfd; #endif @@ -257,6 +320,18 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) if (!xs) { return ret; } + + version = 1; + snprintf(buf, sizeof buf, + "/local/domain/%d/device/vchan/%d/version", domain, + devno); + ref = xs_read(xs, 0, buf, &len); + if (ref) { + version = atoi(ref); + free(ref); + } + + snprintf(buf, sizeof buf, "/local/domain/%d/device/vchan/%d/ring-ref", domain, devno); @@ -277,23 +352,40 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) free(ref); if (!remote_port) goto fail; + + switch (version) { + case 1: + #ifdef XENCTRL_HAS_XC_INTERFACE - xcfd = xc_interface_open(NULL, NULL, 0); - if (!xcfd) - goto fail; + xcfd = xc_interface_open(NULL, NULL, 0); + if (!xcfd) + goto fail; #else - xcfd = xc_interface_open(); - if (xcfd < 0) - goto fail; + xcfd = xc_interface_open(); + if (xcfd < 0) + goto fail; #endif - ctrl->ring = (struct vchan_interface *) - xc_map_foreign_range(xcfd, domain, 4096, - PROT_READ | PROT_WRITE, ctrl->ring_ref); + ctrl->ring = (struct vchan_interface *) + xc_map_foreign_range(xcfd, domain, 4096, + PROT_READ | PROT_WRITE, ctrl->ring_ref); #ifdef XENCTRL_HAS_XC_INTERFACE - xc_interface_close(xcfd); + xc_interface_close(xcfd); #else - close(xcfd); + close(xcfd); #endif + break; + case 2: + xcg = xc_gnttab_open(); + if (xcg < 0) + goto fail; + ctrl->ring = (struct vchan_interface *) + xc_gnttab_map_grant_ref(xcg, domain, ctrl->ring_ref, PROT_READ | PROT_WRITE); + xc_gnttab_close(xcg); + break; + default: + goto fail; + } + if (ctrl->ring == 0 || ctrl->ring == MAP_FAILED) goto fail; #ifdef XENCTRL_HAS_XC_INTERFACE @@ -312,7 +404,7 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno) #ifdef XENCTRL_HAS_XC_INTERFACE xc_evtchn_close(evfd); #else - close(evfd); + close(evfd); #endif else ret = 0; @@ -338,3 +430,19 @@ struct libvchan *libvchan_client_init(int domain, int devno) ctrl->is_server = 0; return ctrl; } + +#else + +// Windows domains can not be dom0 + +int libvchan_server_handle_connected(struct libvchan *ctrl) +{ + return -1; +} + +struct libvchan *libvchan_client_init(int domain, int devno) +{ + return NULL; +} + +#endif \ No newline at end of file diff --git a/vchan/io.c b/vchan/io.c index 23135a25..beed6caf 100644 --- a/vchan/io.c +++ b/vchan/io.c @@ -20,10 +20,15 @@ */ #include "libvchan.h" + +#ifndef WINNT #include -#include #include #include +#endif + +#include + /** \return How much data is immediately available for reading */ @@ -166,7 +171,7 @@ int libvchan_close(struct libvchan *ctrl) } /// The fd to use for select() set -int libvchan_fd_for_select(struct libvchan *ctrl) +EVTCHN libvchan_fd_for_select(struct libvchan *ctrl) { return xc_evtchn_fd(ctrl->evfd); } diff --git a/vchan/libvchan.h b/vchan/libvchan.h index 3f647462..63ab6e9f 100644 --- a/vchan/libvchan.h +++ b/vchan/libvchan.h @@ -22,7 +22,18 @@ #ifndef _LIBVCHAN_H #define _LIBVCHAN_H +#ifdef WINNT +#include +#include +#include +typedef HANDLE EVTCHN; +#define snprintf _snprintf +#else #include +typedef int EVTCHN; +#endif + + #include typedef uint32_t VCHAN_RING_IDX; @@ -42,9 +53,9 @@ struct libvchan { uint32_t ring_ref; /// descriptor to event channel interface #ifdef XENCTRL_HAS_XC_INTERFACE - xc_evtchn *evfd; + xc_evtchn *evfd; #else - int evfd; + EVTCHN evfd; #endif int evport; int devno; @@ -55,16 +66,16 @@ struct libvchan { }; struct libvchan *libvchan_server_init(int devno); -int libvchan_server_handle_connected(struct libvchan *ctrl); struct libvchan *libvchan_client_init(int domain, int devno); +int libvchan_server_handle_connected(struct libvchan *ctrl); int libvchan_write(struct libvchan *ctrl, char *data, int size); int libvchan_read(struct libvchan *ctrl, char *data, int size); int libvchan_wait(struct libvchan *ctrl); int libvchan_close(struct libvchan *ctrl); void libvchan_prepare_to_select(struct libvchan *ctrl); -int libvchan_fd_for_select(struct libvchan *ctrl); +EVTCHN libvchan_fd_for_select(struct libvchan *ctrl); int libvchan_is_eof(struct libvchan *ctrl); int libvchan_data_ready(struct libvchan *ctrl); int libvchan_buffer_space(struct libvchan *ctrl); diff --git a/vchan/sources b/vchan/sources new file mode 100644 index 00000000..6c3a4245 --- /dev/null +++ b/vchan/sources @@ -0,0 +1,22 @@ +TARGETNAME=libvchan +TARGETTYPE=LIBRARY +TARGETPATH=..\libs + +#BUILD_PASS0_CONSUMES=gntmem evtchn xenstore +#BUILD_PASS0_PRODUCES=vchan + +USE_MSVCRT=1 + +DLLDEF=libvchan.def + +INCLUDES=$(INCLUDES); \ + ..\include;\ + +SOURCES=io.c init.c + +TARGETLIBS=\ + $(SDK_LIB_PATH)\setupapi.lib \ + $(SDK_LIB_PATH)\kernel32.lib + + + From e31128341b65a5f21f8e0fa4f3df2bf50d47fff8 Mon Sep 17 00:00:00 2001 From: Alexander Tereshkin Date: Sat, 12 May 2012 20:19:56 +0400 Subject: [PATCH 4/5] Windows-related code moved to core/win directory. --- vchan/sources | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vchan/sources b/vchan/sources index 6c3a4245..9b5e8eb8 100644 --- a/vchan/sources +++ b/vchan/sources @@ -1,6 +1,6 @@ TARGETNAME=libvchan TARGETTYPE=LIBRARY -TARGETPATH=..\libs +TARGETPATH=..\win\libs #BUILD_PASS0_CONSUMES=gntmem evtchn xenstore #BUILD_PASS0_PRODUCES=vchan @@ -10,7 +10,7 @@ USE_MSVCRT=1 DLLDEF=libvchan.def INCLUDES=$(INCLUDES); \ - ..\include;\ + ..\win\include;\ SOURCES=io.c init.c From db324b270e18f218039cf47ca736fe731147b2fb Mon Sep 17 00:00:00 2001 From: Alexander Tereshkin Date: Tue, 29 May 2012 17:07:17 +0400 Subject: [PATCH 5/5] libvchan_server_init() now does not wait for a client to connect. A server should wait for an incoming event and then call libvchan_server_handle_connected(). --- vchan/init.c | 18 +++++++++++------- vchan/io.c | 17 +++++++++++++++++ vchan/sources | 2 ++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/vchan/init.c b/vchan/init.c index 03227686..d870aea2 100644 --- a/vchan/init.c +++ b/vchan/init.c @@ -256,7 +256,7 @@ struct libvchan *libvchan_server_init(int devno) return ctrl; } -#ifndef WINNT + int libvchan_server_handle_connected(struct libvchan *ctrl) { @@ -264,14 +264,21 @@ int libvchan_server_handle_connected(struct libvchan *ctrl) char buf[64]; int ret = -1; int libvchan_fd; - fd_set rfds; +// fd_set rfds; +#ifdef WINNT + xs = xs_domain_open(); +#else xs = xs_daemon_open(); +#endif if (!xs) { return ret; } + +#ifndef WINNT // clear the pending flag xc_evtchn_pending(ctrl->evfd); +#endif snprintf(buf, sizeof buf, "device/vchan/%d", ctrl->devno); xs_rm(xs, 0, buf); @@ -291,6 +298,8 @@ fail2: return ret; } +#ifndef WINNT + /** retrieves ring-ref and event-channel numbers from xenstore (if they don't exist, return error, because nobody seems to listen); @@ -435,11 +444,6 @@ struct libvchan *libvchan_client_init(int domain, int devno) // Windows domains can not be dom0 -int libvchan_server_handle_connected(struct libvchan *ctrl) -{ - return -1; -} - struct libvchan *libvchan_client_init(int domain, int devno) { return NULL; diff --git a/vchan/io.c b/vchan/io.c index beed6caf..e735c86a 100644 --- a/vchan/io.c +++ b/vchan/io.c @@ -71,6 +71,22 @@ int libvchan_is_eof(struct libvchan *ctrl) /** \return -1 return value means peer has closed */ + +#ifdef WINNT +int libvchan_wait(struct libvchan *ctrl) +{ + int ret; + + ret = xc_evtchn_pending(ctrl->evfd); + if (ret!=-1 && xc_evtchn_unmask(ctrl->evfd, ctrl->evport)) + return -1; + if (ret!=-1 && libvchan_is_eof(ctrl)) + return -1; + return ret; +} + +#else + int libvchan_wait(struct libvchan *ctrl) { int ret; @@ -98,6 +114,7 @@ int libvchan_wait(struct libvchan *ctrl) return -1; return ret; } +#endif /** may sleep (only if no buffer space available); diff --git a/vchan/sources b/vchan/sources index 9b5e8eb8..1baae972 100644 --- a/vchan/sources +++ b/vchan/sources @@ -9,6 +9,8 @@ USE_MSVCRT=1 DLLDEF=libvchan.def +C_DEFINES = $(C_DEFINES) /DCONFIG_STUBDOM + INCLUDES=$(INCLUDES); \ ..\win\include;\