Commit 6053f260 authored by Yathindra Naik's avatar Yathindra Naik

- Event channels can be specified by guest config files.

- Event channels are alloc'ed and capabilties are granted.
- Tested for 2 domains which want to communicate with each other.
- Need to introduce a new event channel state so that we can use
  the already allocated capability event channels.
parent 1d8445b3
......@@ -95,7 +95,7 @@ xc_evtchn_getcaps(xc_interface *xch, uint32_t dom, evtchn_port_t port)
rc = do_evtchn_op(xch, EVTCHNOP_getcaps, &cap_arg, sizeof(cap_arg), 0);
if (rc == 0)
return &cap_arg.caps;
return &(cap_arg.caps);
else
return NULL;
}
......
......@@ -958,9 +958,8 @@ int libxl_domain_evtchn(libxl_ctx *ctx, libxl_capabilities *info, uint32_t domid
int port = -1;
char *tok, *sub_tok, *str, *s;
struct capability *cap;
// xc_evtchn *xce_handle = NULL;
// xce_handle = xc_evtchn_open(NULL,0);
xc_dominfo_t dom_info;
xc_evtchn_status_t status;
printf ("Splitting string \"%s\" into tokens:\n",info->cap_values);
tok = strtok (info->cap_values," ,.\n\t");
......@@ -995,12 +994,64 @@ int libxl_domain_evtchn(libxl_ctx *ctx, libxl_capabilities *info, uint32_t domid
num_ports = x;
}
}
}
for ( ;num_ports >= 0; num_ports--)
// Check if the remote domain exists.
// If yes, grant caps and then return.
if (xc_domain_getinfo(ctx->xch,remote_domain,1,&dom_info) > 0)
{
if (dom_info.running || dom_info.paused || dom_info.blocked)
printf("Remote domain %d introduced!\n",remote_domain);
if (dom_info.shutdown || dom_info.dying)
{
printf("Remote domain %d shutdown\n!",remote_domain);
return 0;
}
if (dom_info.cap_flag)
{
printf("Remote domain's cap_flag is set!\n");
for (port = 0; ; port++)
{
status.dom = remote_domain;
status.port = port;
ret = xc_evtchn_status(ctx->xch, &status);
if (ret < 0)
return 0;
if ( status.status != EVTCHNSTAT_unbound && status.cap_flag != 1)
continue;
if ( status.status == EVTCHNSTAT_unbound)
printf("Unbound connection waiting for domain: %d\n",status.u.unbound.dom);
if ( status.u.unbound.dom != domid)
continue;
printf("Getting caps from domid: %d and port: %d\n",remote_domain,port);
cap = xc_evtchn_getcaps(ctx->xch, remote_domain, 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");
}
}
}
printf("returning 0 from libxl_evtchn()\n");
return 0;
}
for ( ;num_ports > 0; num_ports--)
{
if ( (port = xc_evtchn_alloc_unbound(ctx->xch, domid, remote_domain, 1)) != -1)
{
printf("Calling xc_evtchn_getcaps\n");
cap = xc_evtchn_getcaps(ctx->xch, domid, port);
if (cap == NULL)
......@@ -1016,10 +1067,12 @@ int libxl_domain_evtchn(libxl_ctx *ctx, libxl_capabilities *info, uint32_t domid
else
printf("xc_evtchn_alloc_unbound failed\n");
}
printf("remote_domain %d and num_ports %d\n",remote_domain,num_ports);
}
return ret;
printf("returning 0 from libxl_evtchn()\n");
return 0;
}
int libxl_domain_setcapfiles(libxl_ctx *ctx, libxl_capabilities *info, uint32_t domid)
......
......@@ -176,20 +176,25 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc)
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;
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 = NULL;
#endif
TT_DBG("calling xsm_evtchn_unbound\n");
rc = xsm_evtchn_unbound(d, chn, alloc->remote_dom);
if ( rc )
{
TT_ERR("xsm_evtchn_unbound failed\n");
goto out;
}
TT_DBG("chn->cap is %p\n",(long *)chn->cap);
chn->state = ECS_UNBOUND;
if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF )
chn->u.unbound.remote_domid = current->domain->domain_id;
alloc->port = port;
out:
spin_unlock(&d->event_lock);
rcu_unlock_domain(d);
......@@ -853,6 +858,9 @@ static long evtchn_status(evtchn_status_t *status)
BUG();
}
#ifdef CONFIG_XENCAP
status->cap_flag = chn->cap_flag;
#endif
status->vcpu = chn->notify_vcpu_id;
out:
......@@ -983,14 +991,25 @@ int evtchn_getcaps(evtchn_getcaps_t *t)
struct capability *caps = NULL;
int rc = 0;
TT_DBG("Domain: %d, Port: %d\n",dom,t->port);
rc = rcu_lock_target_domain_by_id(dom, &d);
if (rc)
goto out;
if ( unlikely(!port_is_valid(d, t->port)) )
{
TT_ERR("port is not valid!\n");
goto out;
}
chn = evtchn_from_port(d, t->port);
if ( chn == NULL || chn->cap_flag == 0)
{
TT_ERR("channel is NULL or chn->cap_flag is not set\n");
goto out;
}
if ( chn->cap == NULL)
TT_ERR("Capability for channel is NULL\n");
caps = chn->cap;
if (caps == NULL)
rc = -1;
......@@ -1113,10 +1132,16 @@ long do_event_channel_op(int cmd, XEN_GUEST_HANDLE(void) arg)
case EVTCHNOP_getcaps: {
struct evtchn_getcaps getcaps;
if ( copy_from_guest(&getcaps, arg, 1) != 0 )
{
TT_ERR("copy_from_guest failed\n");
return -EFAULT;
}
rc = evtchn_getcaps(&getcaps);
if ( (rc == 0) && (copy_to_guest(arg, &getcaps, 1) != 0) )
{
TT_ERR("copy_to_guest failed!\n");
rc = -EFAULT; /* Cleaning up here would be a mess! */
}
break;
}
......
......@@ -248,6 +248,9 @@ int cap_grant(struct domain *to, struct capability *list, int size)
struct domain *from = current->domain;
int ret = 0; /* success */
if (from->domain_id < 0 || from->domain_id > 100)
TT_ERR("current domain is %d\n",from->domain_id);
if (to->cap_flag == 0)
{
TT_DBG("Domain %d not in capability mode!\n",to->domain_id);
......
......@@ -213,6 +213,9 @@ struct evtchn_status {
#define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */
uint32_t status;
uint32_t vcpu; /* VCPU to which this channel is bound. */
#ifdef CONFIG_XENCAP
uint32_t cap_flag; /* Is this channel capability protected */
#endif
union {
struct {
domid_t dom;
......
......@@ -1550,34 +1550,43 @@ static int cap_evtchn_unbound (struct domain *d, struct evtchn *chn,
struct capability *cap;
if ( IS_PRIV(current->domain) )
return 0;
// if ( IS_PRIV(current->domain) )
// return 0;
if( current->domain->domain_id > 100 )
{
TT_DBG("returning\n");
return 0;
if ( current->domain->cap_flag == 0 || d->cap_flag == 0 )
return 0;
}
// if ( current->domain->cap_flag == 0 || d->cap_flag == 0 )
// return 0;
TT_DBG_ON(cap_debug,"In cap_evtchn_unbound()\n");
TT_DBG("\n");
cap = &(CAP_BOOT_INFO->cap_hypercalls[46]);
if ( (ret = cap_check(current->domain, cap)) == 1 )
if ( (ret = cap_check(current->domain, cap)) == 1 )
{
TT_DBG_ON(cap_debug,"cap_check success\n");
TT_DBG("cap_check success\n");
if (chn->cap_flag == 0)
return 0;
if ( chn->cap == NULL)
{
TT_DBG("alloc cap for channel\n");
chn->cap = xmalloc(struct capability);
}
if ( !cap_create(chn->cap) )
{
TT_DBG_ON(cap_debug, "cap_create returned 0x%x\n",chn->cap->magic);
TT_DBG("cap_create returned 0x%x\n",chn->cap->magic);
return 0;
}
else
return 1;
}
else
{
TT_DBG_ON(cap_debug,"cap_check failed!\nLeaving cap_evtchn_unbound()\n");
TT_DBG("cap_check failed!\nLeaving cap_evtchn_unbound()\n");
return 1;
}
......@@ -1756,7 +1765,13 @@ static void cap_free_security_evtchn (struct evtchn *chn)
if ( (ret = cap_check(current->domain, cap)) == 1 )
{
TT_DBG_ON(cap_debug,"cap_check success\nLeaving cap_free_security_evtchn()\n");
TT_DBG_ON(cap_debug,"cap_check success\n");
if (chn->cap != NULL)
{
TT_DBG("freeing chn->cap\n");
xfree(chn->cap);
}
return;
}
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