Merge branch 'hvm' of git://gitpro.qubes-os.org/alex/core into hvm
This commit is contained in:
commit
2e9fcbbc1f
142
vchan/init.c
142
vchan/init.c
@ -19,6 +19,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef WINNT
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -27,18 +29,66 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <xs.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <xenctrl.h>
|
#include <xenctrl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include "libvchan.h"
|
|
||||||
#ifndef CONFIG_STUBDOM
|
#ifndef CONFIG_STUBDOM
|
||||||
#include "../u2mfn/u2mfnlib.h"
|
#include "../u2mfn/u2mfnlib.h"
|
||||||
#else
|
#else
|
||||||
#include <mm.h>
|
#include <mm.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <xs.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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)
|
static int ring_init(struct libvchan *ctrl)
|
||||||
{
|
{
|
||||||
int mfn;
|
int mfn;
|
||||||
@ -52,7 +102,6 @@ static int ring_init(struct libvchan *ctrl)
|
|||||||
|
|
||||||
mfn = virtual_to_mfn(ring);
|
mfn = virtual_to_mfn(ring);
|
||||||
#else
|
#else
|
||||||
int u2mfn = open("/proc/u2mfn", O_RDONLY);
|
|
||||||
ring = (struct vchan_interface *) u2mfn_alloc_kpage ();
|
ring = (struct vchan_interface *) u2mfn_alloc_kpage ();
|
||||||
|
|
||||||
if (ring == MAP_FAILED)
|
if (ring == MAP_FAILED)
|
||||||
@ -60,17 +109,13 @@ static int ring_init(struct libvchan *ctrl)
|
|||||||
|
|
||||||
if (u2mfn_get_last_mfn (&mfn) < 0)
|
if (u2mfn_get_last_mfn (&mfn) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
close(u2mfn);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ctrl->ring = ring;
|
return fill_ctrl(ctrl, ring, mfn);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
creates event channel;
|
creates event channel;
|
||||||
creates "ring-ref" and "event-channel" xenstore entries;
|
creates "ring-ref" and "event-channel" xenstore entries;
|
||||||
@ -90,10 +135,14 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
|
|||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||||
xc_evtchn *evfd;
|
xc_evtchn *evfd;
|
||||||
#else
|
#else
|
||||||
int evfd;
|
EVTCHN evfd;
|
||||||
#endif
|
#endif
|
||||||
evtchn_port_or_error_t port;
|
evtchn_port_or_error_t port;
|
||||||
|
#ifdef WINNT
|
||||||
|
xs = xs_domain_open();
|
||||||
|
#else
|
||||||
xs = xs_daemon_open();
|
xs = xs_daemon_open();
|
||||||
|
#endif
|
||||||
if (!xs) {
|
if (!xs) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -119,6 +168,10 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
|
|||||||
if (domid_s)
|
if (domid_s)
|
||||||
domid = atoi(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(ref, sizeof ref, "%d", ctrl->ring_ref);
|
||||||
snprintf(buf, sizeof buf, "device/vchan/%d/ring-ref", devno);
|
snprintf(buf, sizeof buf, "device/vchan/%d/ring-ref", devno);
|
||||||
if (!xs_write(xs, 0, buf, ref, strlen(ref)))
|
if (!xs_write(xs, 0, buf, ref, strlen(ref)))
|
||||||
@ -153,8 +206,12 @@ static int server_interface_init(struct libvchan *ctrl, int devno)
|
|||||||
if (ret)
|
if (ret)
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||||
xc_evtchn_close(evfd);
|
xc_evtchn_close(evfd);
|
||||||
|
#else
|
||||||
|
#ifdef WINNT
|
||||||
|
xc_evtchn_close(evfd);
|
||||||
#else
|
#else
|
||||||
close(evfd);
|
close(evfd);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
fail:
|
fail:
|
||||||
xs_daemon_close(xs);
|
xs_daemon_close(xs);
|
||||||
@ -199,20 +256,29 @@ struct libvchan *libvchan_server_init(int devno)
|
|||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int libvchan_server_handle_connected(struct libvchan *ctrl)
|
int libvchan_server_handle_connected(struct libvchan *ctrl)
|
||||||
{
|
{
|
||||||
struct xs_handle *xs;
|
struct xs_handle *xs;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
int libvchan_fd;
|
int libvchan_fd;
|
||||||
fd_set rfds;
|
// fd_set rfds;
|
||||||
|
|
||||||
|
#ifdef WINNT
|
||||||
|
xs = xs_domain_open();
|
||||||
|
#else
|
||||||
xs = xs_daemon_open();
|
xs = xs_daemon_open();
|
||||||
|
#endif
|
||||||
if (!xs) {
|
if (!xs) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WINNT
|
||||||
// clear the pending flag
|
// clear the pending flag
|
||||||
xc_evtchn_pending(ctrl->evfd);
|
xc_evtchn_pending(ctrl->evfd);
|
||||||
|
#endif
|
||||||
|
|
||||||
snprintf(buf, sizeof buf, "device/vchan/%d", ctrl->devno);
|
snprintf(buf, sizeof buf, "device/vchan/%d", ctrl->devno);
|
||||||
xs_rm(xs, 0, buf);
|
xs_rm(xs, 0, buf);
|
||||||
@ -232,6 +298,8 @@ fail2:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WINNT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
retrieves ring-ref and event-channel numbers from xenstore (if
|
retrieves ring-ref and event-channel numbers from xenstore (if
|
||||||
they don't exist, return error, because nobody seems to listen);
|
they don't exist, return error, because nobody seems to listen);
|
||||||
@ -247,8 +315,10 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
|
|||||||
#else
|
#else
|
||||||
int xcfd;
|
int xcfd;
|
||||||
#endif
|
#endif
|
||||||
|
int xcg;
|
||||||
char buf[64];
|
char buf[64];
|
||||||
char *ref;
|
char *ref;
|
||||||
|
int version;
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||||
xc_evtchn *evfd;
|
xc_evtchn *evfd;
|
||||||
#else
|
#else
|
||||||
@ -259,6 +329,18 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
|
|||||||
if (!xs) {
|
if (!xs) {
|
||||||
return ret;
|
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,
|
snprintf(buf, sizeof buf,
|
||||||
"/local/domain/%d/device/vchan/%d/ring-ref", domain,
|
"/local/domain/%d/device/vchan/%d/ring-ref", domain,
|
||||||
devno);
|
devno);
|
||||||
@ -266,9 +348,9 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
|
|||||||
if (!ref)
|
if (!ref)
|
||||||
goto fail;
|
goto fail;
|
||||||
ctrl->ring_ref = atoi(ref);
|
ctrl->ring_ref = atoi(ref);
|
||||||
|
free(ref);
|
||||||
if (!ctrl->ring_ref)
|
if (!ctrl->ring_ref)
|
||||||
goto fail;
|
goto fail;
|
||||||
free(ref);
|
|
||||||
snprintf(buf, sizeof buf,
|
snprintf(buf, sizeof buf,
|
||||||
"/local/domain/%d/device/vchan/%d/event-channel", domain,
|
"/local/domain/%d/device/vchan/%d/event-channel", domain,
|
||||||
devno);
|
devno);
|
||||||
@ -276,9 +358,13 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
|
|||||||
if (!ref)
|
if (!ref)
|
||||||
goto fail;
|
goto fail;
|
||||||
remote_port = atoi(ref);
|
remote_port = atoi(ref);
|
||||||
|
free(ref);
|
||||||
if (!remote_port)
|
if (!remote_port)
|
||||||
goto fail;
|
goto fail;
|
||||||
free(ref);
|
|
||||||
|
switch (version) {
|
||||||
|
case 1:
|
||||||
|
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||||
xcfd = xc_interface_open(NULL, NULL, 0);
|
xcfd = xc_interface_open(NULL, NULL, 0);
|
||||||
if (!xcfd)
|
if (!xcfd)
|
||||||
@ -296,6 +382,19 @@ static int client_interface_init(struct libvchan *ctrl, int domain, int devno)
|
|||||||
#else
|
#else
|
||||||
close(xcfd);
|
close(xcfd);
|
||||||
#endif
|
#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)
|
if (ctrl->ring == 0 || ctrl->ring == MAP_FAILED)
|
||||||
goto fail;
|
goto fail;
|
||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||||
@ -340,3 +439,14 @@ struct libvchan *libvchan_client_init(int domain, int devno)
|
|||||||
ctrl->is_server = 0;
|
ctrl->is_server = 0;
|
||||||
return ctrl;
|
return ctrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// Windows domains can not be dom0
|
||||||
|
|
||||||
|
struct libvchan *libvchan_client_init(int domain, int devno)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
vchan/io.c
26
vchan/io.c
@ -20,10 +20,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libvchan.h"
|
#include "libvchan.h"
|
||||||
|
|
||||||
|
#ifndef WINNT
|
||||||
#include <xenctrl.h>
|
#include <xenctrl.h>
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\return How much data is immediately available for reading
|
\return How much data is immediately available for reading
|
||||||
*/
|
*/
|
||||||
@ -66,6 +71,22 @@ int libvchan_is_eof(struct libvchan *ctrl)
|
|||||||
/**
|
/**
|
||||||
\return -1 return value means peer has closed
|
\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 libvchan_wait(struct libvchan *ctrl)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -93,6 +114,7 @@ int libvchan_wait(struct libvchan *ctrl)
|
|||||||
return -1;
|
return -1;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
may sleep (only if no buffer space available);
|
may sleep (only if no buffer space available);
|
||||||
@ -166,7 +188,7 @@ int libvchan_close(struct libvchan *ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The fd to use for select() set
|
/// 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);
|
return xc_evtchn_fd(ctrl->evfd);
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,18 @@
|
|||||||
#ifndef _LIBVCHAN_H
|
#ifndef _LIBVCHAN_H
|
||||||
#define _LIBVCHAN_H
|
#define _LIBVCHAN_H
|
||||||
|
|
||||||
|
#ifdef WINNT
|
||||||
|
#include <windows.h>
|
||||||
|
#include <xen_gntmem.h>
|
||||||
|
#include <xs.h>
|
||||||
|
typedef HANDLE EVTCHN;
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
typedef int EVTCHN;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#include <xenctrl.h>
|
#include <xenctrl.h>
|
||||||
typedef uint32_t VCHAN_RING_IDX;
|
typedef uint32_t VCHAN_RING_IDX;
|
||||||
|
|
||||||
@ -44,7 +55,7 @@ struct libvchan {
|
|||||||
#ifdef XENCTRL_HAS_XC_INTERFACE
|
#ifdef XENCTRL_HAS_XC_INTERFACE
|
||||||
xc_evtchn *evfd;
|
xc_evtchn *evfd;
|
||||||
#else
|
#else
|
||||||
int evfd;
|
EVTCHN evfd;
|
||||||
#endif
|
#endif
|
||||||
int evport;
|
int evport;
|
||||||
int devno;
|
int devno;
|
||||||
@ -55,16 +66,16 @@ struct libvchan {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct libvchan *libvchan_server_init(int devno);
|
struct libvchan *libvchan_server_init(int devno);
|
||||||
int libvchan_server_handle_connected(struct libvchan *ctrl);
|
|
||||||
|
|
||||||
struct libvchan *libvchan_client_init(int domain, int devno);
|
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_write(struct libvchan *ctrl, char *data, int size);
|
||||||
int libvchan_read(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_wait(struct libvchan *ctrl);
|
||||||
int libvchan_close(struct libvchan *ctrl);
|
int libvchan_close(struct libvchan *ctrl);
|
||||||
void libvchan_prepare_to_select(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_is_eof(struct libvchan *ctrl);
|
||||||
int libvchan_data_ready(struct libvchan *ctrl);
|
int libvchan_data_ready(struct libvchan *ctrl);
|
||||||
int libvchan_buffer_space(struct libvchan *ctrl);
|
int libvchan_buffer_space(struct libvchan *ctrl);
|
||||||
|
24
vchan/sources
Normal file
24
vchan/sources
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
TARGETNAME=libvchan
|
||||||
|
TARGETTYPE=LIBRARY
|
||||||
|
TARGETPATH=..\win\libs
|
||||||
|
|
||||||
|
#BUILD_PASS0_CONSUMES=gntmem evtchn xenstore
|
||||||
|
#BUILD_PASS0_PRODUCES=vchan
|
||||||
|
|
||||||
|
USE_MSVCRT=1
|
||||||
|
|
||||||
|
DLLDEF=libvchan.def
|
||||||
|
|
||||||
|
C_DEFINES = $(C_DEFINES) /DCONFIG_STUBDOM
|
||||||
|
|
||||||
|
INCLUDES=$(INCLUDES); \
|
||||||
|
..\win\include;\
|
||||||
|
|
||||||
|
SOURCES=io.c init.c
|
||||||
|
|
||||||
|
TARGETLIBS=\
|
||||||
|
$(SDK_LIB_PATH)\setupapi.lib \
|
||||||
|
$(SDK_LIB_PATH)\kernel32.lib
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user