Commit 6913a2ba authored by Yathindra Naik's avatar Yathindra Naik

Testing changes made to event channel.

parent 57361ae3
......@@ -22,6 +22,8 @@
#include "xc_private.h"
struct evtchn_getcaps cap_arg;
static int do_evtchn_op(xc_interface *xch, int cmd, void *arg,
size_t arg_size, int silently_fail)
{
......@@ -47,15 +49,26 @@ static int do_evtchn_op(xc_interface *xch, int cmd, void *arg,
return ret;
}
#ifdef CONFIG_XENCAP
evtchn_port_or_error_t
xc_evtchn_alloc_unbound(xc_interface *xch,
uint32_t dom,
uint32_t remote_dom,
int cap_flag)
#else
evtchn_port_or_error_t
xc_evtchn_alloc_unbound(xc_interface *xch,
uint32_t dom,
uint32_t remote_dom)
#endif
{
int rc;
struct evtchn_alloc_unbound arg = {
.dom = (domid_t)dom,
.remote_dom = (domid_t)remote_dom
.remote_dom = (domid_t)remote_dom,
#ifdef CONFIG_XENCAP
.cap_flag = cap_flag
#endif
};
rc = do_evtchn_op(xch, EVTCHNOP_alloc_unbound, &arg, sizeof(arg), 0);
......@@ -72,6 +85,22 @@ int xc_evtchn_reset(xc_interface *xch,
return do_evtchn_op(xch, EVTCHNOP_reset, &arg, sizeof(arg), 0);
}
#ifdef CONFIG_XENCAP
evtchn_cap_t *
xc_evtchn_getcaps(xc_interface *xch, uint32_t dom, evtchn_port_t port)
{
int rc;
cap_arg.dom = (domid_t)dom;
cap_arg.port = port;
rc = do_evtchn_op(xch, EVTCHNOP_getcaps, &cap_arg, sizeof(cap_arg), 0);
if (rc == 0)
return &cap_arg.caps;
else
return NULL;
}
#endif
int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status)
{
return do_evtchn_op(xch, EVTCHNOP_status, status,
......
......@@ -901,13 +901,28 @@ typedef int evtchn_port_or_error_t;
* @parm remote_dom the ID of the domain who will later bind
* @return allocated port (in @dom) on success, -1 on failure
*/
#ifdef CONFIG_XENCAP
evtchn_port_or_error_t
xc_evtchn_alloc_unbound(xc_interface *xch,
uint32_t dom,
uint32_t remote_dom,
int cap_flag);
#else
evtchn_port_or_error_t
xc_evtchn_alloc_unbound(xc_interface *xch,
uint32_t dom,
uint32_t remote_dom);
#endif
int xc_evtchn_reset(xc_interface *xch,
uint32_t dom);
/*
* Return capabilities for a given event channel.
*/
#ifdef CONFIG_XENCAP
evtchn_cap_t *
xc_evtchn_getcaps(xc_interface *xch, uint32_t dom, evtchn_port_t port);
#endif
typedef struct evtchn_status xc_evtchn_status_t;
int xc_evtchn_status(xc_interface *xch, xc_evtchn_status_t *status);
......
......@@ -104,6 +104,9 @@ struct xc_osdep_ops
evtchn_port_or_error_t (*pending)(xc_evtchn *xce, xc_osdep_handle h);
int (*unmask)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port);
#ifdef CONFIG_XENCAP
int (*get_evtchn_caps)(xc_evtchn *xce, xc_osdep_handle h, evtchn_port_t port);
#endif
} evtchn;
struct {
#define XC_GRANT_MAP_SINGLE_DOMAIN 0x1
......
......@@ -950,6 +950,77 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
}
#ifdef CONFIG_XENCAP
int libxl_domain_evtchn(libxl_ctx *ctx, libxl_capabilities *info, uint32_t domid)
{
int ret = 0, x = 0;
uint32_t remote_domain = -1;
int num_ports = -1;
int port = -1;
char *tok, *sub_tok, *str, *s;
struct capability *cap;
// xc_evtchn *xce_handle = NULL;
// xce_handle = xc_evtchn_open(NULL,0);
printf ("Splitting string \"%s\" into tokens:\n",info->cap_values);
tok = strtok (info->cap_values," ,.\n\t");
/*
* 1. Parse the config file
* 2. For each Domid:Num_Port pair, alloc Num_Port evtchns
* 3.
*/
while (tok != NULL)
{
printf("%s\n",tok);
str = strdup(tok);
tok = strtok(NULL," ,.\n\t");
sub_tok = strtok(str,":");
s = strdup(sub_tok);
// simple string to int conversion with error checking
for (x=0; (unsigned)*s-'0'<10; s++)
x=10*x+(*s-'0');
remote_domain = x;
while (sub_tok != NULL)
{
sub_tok = strtok(NULL, ":");
if (sub_tok != NULL)
{
s = strdup(sub_tok);
// simple string to int conversion with error checking
for (x=0; (unsigned)*s-'0'<10; s++)
x=10*x+(*s-'0');
num_ports = x;
}
}
for ( ;num_ports >= 0; num_ports--)
{
if ( (port = xc_evtchn_alloc_unbound(ctx->xch, domid, remote_domain, 1)) != -1)
{
cap = xc_evtchn_getcaps(ctx->xch, domid, port);
if (cap == NULL)
printf("xc_evtchn_getcaps returned NULL\n");
else
{
printf("Calling xc_cap_grant().\n");
ret = xc_cap_grant(ctx->xch,domid,cap,1);
if (ret)
printf("xc_cap_grant failed!\n");
}
}
else
printf("xc_evtchn_alloc_unbound failed\n");
}
printf("remote_domain %d and num_ports %d\n",remote_domain,num_ports);
}
return ret;
}
int libxl_domain_setcapfiles(libxl_ctx *ctx, libxl_capabilities *info, uint32_t domid)
{
......
......@@ -491,6 +491,7 @@ typedef struct {
#ifdef CONFIG_XENCAP
libxl_capabilities *cap;
libxl_capabilities *cap_files;
libxl_capabilities *cap_evtchn;
#endif
libxl_action_on_shutdown on_poweroff;
......@@ -551,6 +552,8 @@ int libxl_domain_setcap(libxl_ctx *ctx, libxl_capabilities *info,
int libxl_domain_setcapfiles(libxl_ctx *ctx, libxl_capabilities *info,
uint32_t domid);
int libxl_domain_evtchn(libxl_ctx *ctx, libxl_capabilities *info, uint32_t domid);
#endif
int libxl_domain_shutdown(libxl_ctx *ctx, uint32_t domid);
int libxl_domain_reboot(libxl_ctx *ctx, uint32_t domid);
......
......@@ -759,6 +759,14 @@ static void initiate_domain_create(libxl__egc *egc,
ret = ERROR_FAIL;
goto error_out;
}
libxl_capabilities *cap_evtchn = d_config->cap_evtchn;
ret = libxl_domain_evtchn(ctx, cap_evtchn, domid);
if (ret) {
LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot make evt_chn: %d", ret);
ret = ERROR_FAIL;
goto error_out;
}
#endif
dcs->guest_domid = domid;
dcs->dmss.dm.guest_domid = 0; /* means we haven't spawned */
......
......@@ -284,10 +284,14 @@ int libxl__build_pre(libxl__gc *gc, uint32_t domid,
state->console_domid = con_domid ? atoi(con_domid) : 0;
free(con_domid);
#ifdef CONFIG_XENCAP
state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid, 0);
state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid, 0);
#else
state->store_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->store_domid);
state->console_port = xc_evtchn_alloc_unbound(ctx->xch, domid, state->console_domid);
state->vm_generationid_addr = 0;
#endif
return 0;
}
......
......@@ -1067,6 +1067,13 @@ static void parse_config_data(const char *config_source,
d_config->cap_files->cap_type = LIBXL_CAP_TYPE_FILES;
d_config->cap_files->cap_values = strdup(buf);
}
if (!xlu_cfg_get_string(config, "cap_evtchn", &buf, 0)) {
printf("In parse_config_data: parsing cap_evtchn ...\n");
d_config->cap_evtchn = (libxl_capabilities *) realloc(d_config->cap_evtchn, sizeof (libxl_capabilities));
d_config->cap_evtchn->cap_type = LIBXL_CAP_TYPE_EVTCHN;
d_config->cap_evtchn->cap_values = strdup(buf);
}
#endif
if (!xlu_cfg_get_list (config, "vif", &nics, 0, 0)) {
......
......@@ -504,8 +504,13 @@ CAMLprim value stub_xc_evtchn_alloc_unbound(value xch,
uint32_t c_remote_domid = _D(remote_domid);
caml_enter_blocking_section();
#ifdef CONFIG_XENCAP
result = xc_evtchn_alloc_unbound(_H(xch), c_local_domid,
c_remote_domid, 0);
#else
result = xc_evtchn_alloc_unbound(_H(xch), c_local_domid,
c_remote_domid);
#endif
caml_leave_blocking_section();
if (result < 0)
......
......@@ -1101,8 +1101,11 @@ static PyObject *pyxc_evtchn_alloc_unbound(XcObject *self,
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list,
&dom, &remote_dom) )
return NULL;
#ifdef CONFIG_XENCAP
if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom, 0)) < 0 )
#else
if ( (port = xc_evtchn_alloc_unbound(self->xc_handle, dom, remote_dom)) < 0 )
#endif
return pyxc_error_to_exception(self->xc_handle);
return PyInt_FromLong(port);
......
......@@ -118,7 +118,7 @@ static u32 adjust_vmx_controls(
return ctl;
}
static bool_t cap_check(const char *name, u32 expected, u32 saw)
static bool_t cap_check_t(const char *name, u32 expected, u32 saw)
{
if ( saw != expected )
printk("VMX %s: saw %#x expected %#x\n", name, saw, expected);
......@@ -286,25 +286,25 @@ static int vmx_init_vmcs_config(void)
else
{
/* Globals are already initialised: re-check them. */
mismatch |= cap_check(
mismatch |= cap_check_t(
"VMCS revision ID",
vmcs_revision_id, vmx_basic_msr_low);
mismatch |= cap_check(
mismatch |= cap_check_t(
"Pin-Based Exec Control",
vmx_pin_based_exec_control, _vmx_pin_based_exec_control);
mismatch |= cap_check(
mismatch |= cap_check_t(
"CPU-Based Exec Control",
vmx_cpu_based_exec_control, _vmx_cpu_based_exec_control);
mismatch |= cap_check(
mismatch |= cap_check_t(
"Secondary Exec Control",
vmx_secondary_exec_control, _vmx_secondary_exec_control);
mismatch |= cap_check(
mismatch |= cap_check_t(
"VMExit Control",
vmx_vmexit_control, _vmx_vmexit_control);
mismatch |= cap_check(
mismatch |= cap_check_t(
"VMEntry Control",
vmx_vmentry_control, _vmx_vmentry_control);
mismatch |= cap_check(
mismatch |= cap_check_t(
"EPT and VPID Capability",
vmx_ept_vpid_cap, _vmx_ept_vpid_cap);
if ( cpu_has_vmx_ins_outs_instr_info !=
......
......@@ -175,6 +175,11 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
ERROR_EXIT_DOM(port, d);
chn = evtchn_from_port(d, port);
#ifdef CONFIG_XENCAP
TT_DBG("cap_flag for channel: %d, Domain:%d, Port: %d, Remote_Domain:%d\n",alloc->cap_flag,(int)alloc->dom,port,alloc->remote_dom);
chn->cap_flag = alloc->cap_flag;
#endif
rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom);
if ( rc )
goto out;
......@@ -227,6 +232,7 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind)
if ( !port_is_valid(rd, rport) )
ERROR_EXIT_DOM(-EINVAL, rd);
rchn = evtchn_from_port(rd, rport);
TT_DBG("rchn->state:%d, Domain:%d, port:%d, remoter_domain:%d, remote_port:%d\n",rchn->state,current->domain->domain_id,lport,rdom,rport);
if ( (rchn->state != ECS_UNBOUND) ||
(rchn->u.unbound.remote_domid != ld->domain_id) )
ERROR_EXIT_DOM(-EINVAL, rd);
......@@ -943,7 +949,6 @@ int evtchn_unmask(unsigned int port)
return 0;
}
static long evtchn_reset(evtchn_reset_t *r)
{
domid_t dom = r->dom;
......@@ -969,6 +974,33 @@ out:
return rc;
}
#ifdef CONFIG_XENCAP
int evtchn_getcaps(evtchn_getcaps_t *t)
{
domid_t dom = t->dom;
struct domain *d;
struct evtchn *chn;
struct capability *caps = NULL;
int rc = 0;
rc = rcu_lock_target_domain_by_id(dom, &d);
if (rc)
goto out;
if ( unlikely(!port_is_valid(d, t->port)) )
goto out;
chn = evtchn_from_port(d, t->port);
caps = chn->cap;
if (caps == NULL)
rc = -1;
else
t->caps = *caps;
out:
rcu_unlock_domain(d);
return rc;
}
#endif
long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
......@@ -1078,6 +1110,16 @@ long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
break;
}
case EVTCHNOP_getcaps: {
struct evtchn_getcaps getcaps;
if ( copy_from_guest(&getcaps, arg, 1) != 0 )
return -EFAULT;
rc = evtchn_getcaps(&getcaps);
if ( (rc == 0) && (copy_to_guest(arg, &getcaps, 1) != 0) )
rc = -EFAULT; /* Cleaning up here would be a mess! */
break;
}
default:
rc = -ENOSYS;
break;
......
/**
* common/xen-cap.c
*
* This file is a part of Flux Xen Capabilites
* This file is a part of Flux Xen Capabilities
*
* Capabilities Interface for Xen
*
......@@ -164,13 +164,13 @@ int cap_create(struct capability *cap)
num_caps = d->cap_space->num_caps;
else
{
TT_DBG("cap_create: Domain: %d cap_space not init'ed\n",d->domain_id);
TT_ERR("cap_create: Domain: %d cap_space not init'ed\n",d->domain_id);
return 1;
}
if ( cap == NULL )
{
TT_DBG("cap_create: Domain: %d cap is NULL!\n",d->domain_id);
TT_ERR("cap_create: Domain: %d cap is NULL!\n",d->domain_id);
return 1;
}
......
......@@ -28,6 +28,7 @@
#define __XEN_PUBLIC_EVENT_CHANNEL_H__
#include "xen.h"
#include "xen-cap.h"
/*
* `incontents 150 evtchn Event Channels
......@@ -71,11 +72,17 @@
#define EVTCHNOP_bind_vcpu 8
#define EVTCHNOP_unmask 9
#define EVTCHNOP_reset 10
#ifdef CONFIG_XENCAP
#define EVTCHNOP_getcaps 11
#endif
/* ` } */
typedef uint32_t evtchn_port_t;
DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
typedef struct capability evtchn_cap_t;
DEFINE_XEN_GUEST_HANDLE(evtchn_cap_t);
/*
* EVTCHNOP_alloc_unbound: Allocate a port in domain <dom> and mark as
* accepting interdomain bindings from domain <remote_dom>. A fresh port
......@@ -87,6 +94,10 @@ DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
struct evtchn_alloc_unbound {
/* IN parameters */
domid_t dom, remote_dom;
#ifdef CONFIG_XENCAP
/* IN parameters */
uint32_t cap_flag;
#endif
/* OUT parameters */
evtchn_port_t port;
};
......@@ -245,6 +256,21 @@ struct evtchn_unmask {
};
typedef struct evtchn_unmask evtchn_unmask_t;
#ifdef CONFIG_XENCAP
/*
* EVTCHNOP_getcaps: Return capability associated with an
* event-channel
*/
struct evtchn_getcaps {
/* IN parameters. */
domid_t dom;
evtchn_port_t port;
/* OUT parameters. */
evtchn_cap_t caps;
};
typedef struct evtchn_getcaps evtchn_getcaps_t;
#endif
/*
* EVTCHNOP_reset: Close all event channels associated with specified domain.
* NOTES:
......@@ -276,6 +302,9 @@ struct evtchn_op {
struct evtchn_status status;
struct evtchn_bind_vcpu bind_vcpu;
struct evtchn_unmask unmask;
#ifdef CONFIG_XENCAP
struct evtchn_getcaps getcaps;
#endif
} u;
};
typedef struct evtchn_op evtchn_op_t;
......
......@@ -71,6 +71,10 @@ struct evtchn
#ifdef FLASK_ENABLE
void *ssid;
#endif
#ifdef CONFIG_XENCAP
u8 cap_flag;
struct capability *cap;
#endif
};
int evtchn_init(struct domain *d); /* from domain_create */
......
......@@ -1562,8 +1562,18 @@ static int cap_evtchn_unbound (struct domain *d, struct evtchn *chn,
if ( (ret = cap_check(current->domain, cap)) == 1 )
{
TT_DBG_ON(cap_debug,"cap_check success\nLeaving cap_evtchn_unbound()\n");
return 0;
TT_DBG_ON(cap_debug,"cap_check success\n");
if (chn->cap_flag == 0)
return 0;
if ( !cap_create(chn->cap) )
{
TT_DBG_ON(cap_debug, "cap_create returned 0x%x\n",chn->cap->magic);
return 0;
}
else
return 1;
}
else
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment