Merge branch 'hvm' of git://gitpro.qubes-os.org/alex/core into hvm

This commit is contained in:
Marek Marczykowski 2012-06-02 00:46:41 +02:00
commit 2e9fcbbc1f
4 changed files with 204 additions and 37 deletions

View File

@ -19,6 +19,8 @@
*
*/
#ifndef WINNT
#include <sys/types.h>
#include <sys/unistd.h>
#include <sys/stat.h>
@ -27,18 +29,66 @@
#include <fcntl.h>
#include <sys/ioctl.h>
#include <malloc.h>
#include <xs.h>
#include <string.h>
#include <xenctrl.h>
#include <unistd.h>
#include <stdlib.h>
#include "libvchan.h"
#ifndef CONFIG_STUBDOM
#include "../u2mfn/u2mfnlib.h"
#else
#include <mm.h>
#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)
{
int mfn;
@ -52,7 +102,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,17 +109,13 @@ static int ring_init(struct libvchan *ctrl)
if (u2mfn_get_last_mfn (&mfn) < 0)
return -1;
close(u2mfn);
#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;
@ -88,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;
}
@ -119,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)))
@ -153,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);
@ -199,20 +256,29 @@ struct libvchan *libvchan_server_init(int devno)
return ctrl;
}
int libvchan_server_handle_connected(struct libvchan *ctrl)
{
struct xs_handle *xs;
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);
@ -232,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);
@ -243,14 +311,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
@ -259,6 +329,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);
@ -266,9 +348,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);
@ -276,26 +358,43 @@ 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);
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
@ -314,7 +413,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;
@ -340,3 +439,14 @@ struct libvchan *libvchan_client_init(int domain, int devno)
ctrl->is_server = 0;
return ctrl;
}
#else
// Windows domains can not be dom0
struct libvchan *libvchan_client_init(int domain, int devno)
{
return NULL;
}
#endif

View File

@ -20,10 +20,15 @@
*/
#include "libvchan.h"
#ifndef WINNT
#include <xenctrl.h>
#include <string.h>
#include <errno.h>
#include <sys/select.h>
#endif
#include <string.h>
/**
\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
*/
#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;
@ -93,6 +114,7 @@ int libvchan_wait(struct libvchan *ctrl)
return -1;
return ret;
}
#endif
/**
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
int libvchan_fd_for_select(struct libvchan *ctrl)
EVTCHN libvchan_fd_for_select(struct libvchan *ctrl)
{
return xc_evtchn_fd(ctrl->evfd);
}

View File

@ -22,7 +22,18 @@
#ifndef _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>
typedef int EVTCHN;
#endif
#include <xenctrl.h>
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);

24
vchan/sources Normal file
View 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