Commit 206dece6 authored by Yathindra Naik's avatar Yathindra Naik

Checkpoint - preliminary capability flow sketched.

Changes include -

1) xl recognizes setcap command for capabilities.
2) Domain0 has all the capabilities now.
3) New domain is granted capabilities from domain 0.
parent af26f94d
......@@ -1524,11 +1524,11 @@ int xc_domain_set_virq_handler(xc_interface *xch, uint32_t domid, int virq)
int xc_cap_create(xc_interface *xch, uint32_t domid, struct capability *cap)
{
DECLARE_DOMCTL;
DPRINTF("In xc_cap_create().\n");
domctl.cmd = XEN_DOMCTL_cap_create;
domctl.domain = (domid_t)domid;
domctl.u.cap_create.cap = cap;
DPRINTF("Leaving xc_cap_create().\n");
return do_domctl(xch, &domctl);
}
......@@ -1541,6 +1541,7 @@ int xc_cap_grant(xc_interface *xch,
{
DECLARE_DOMCTL;
DPRINTF("In xc_cap_grant().\n");
domctl.cmd = XEN_DOMCTL_cap_grant;
/* Not sure if I should init the domid here as we
* are not using it in domctl.c
......@@ -1551,7 +1552,7 @@ int xc_cap_grant(xc_interface *xch,
domctl.u.cap_grant.type = type;
domctl.u.cap_grant.list = list;
domctl.u.cap_grant.size = size;
DPRINTF("Leaving xc_cap_grant().\n");
return do_domctl(xch, &domctl);
}
......@@ -1561,12 +1562,12 @@ int xc_cap_check(xc_interface *xch,
struct capability *cap)
{
DECLARE_DOMCTL;
DPRINTF("In xc_cap_check().\n");
domctl.cmd = XEN_DOMCTL_cap_check;
domctl.domain = (domid_t)domid;
domctl.u.cap_check.type = type;
domctl.u.cap_check.cap = cap;
DPRINTF("Leaving xc_cap_check().\n");
return do_domctl(xch, &domctl);
}
#endif /* CONFIG_XENCAP */
......
......@@ -17,7 +17,7 @@
#include "libxl_osdeps.h"
#include "libxl_internal.h"
#include <stdio.h>
#define PAGE_TO_MEMKB(pages) ((pages) * 4)
#define BACKEND_STRING_SIZE 5
......@@ -869,6 +869,48 @@ int libxl_domain_unpause(libxl_ctx *ctx, uint32_t domid)
return rc;
}
#ifdef CONFIG_XENCAP
int libxl_domain_setcap(libxl_ctx *ctx, libxl_domain_cap_info *info, uint32_t domid)
{
int ret = 0;
/* TO-DO
*
* 1) Parse the list of hypercalls if info->hypercalls != NULL
* 2) Parse the list of pci_devices if info->pci_devices != NULL
* 3) Parse the list of memory pages if info->memory != NULL
*/
char *tok;
int size = 0;
int list[64];
printf ("Splitting string \"%s\" into tokens:\n",info->hypercalls);
tok = strtok (info->hypercalls," ,.-");
while (tok != NULL)
{
printf ("%s\n",tok);
switch(tok[0])
{
case 'f':
list[0] = 1;
break;
case 'b':
list[1] = 2;
break;
}
++size;
tok = strtok (NULL, " ,.-");
}
printf("Calling xc_cap_grant().\n");
ret = xc_cap_grant(ctx->xch,0,domid,1,list,size);
return ret;
}
#endif
int libxl__domain_pvcontrol_available(libxl__gc *gc, uint32_t domid)
{
libxl_ctx *ctx = libxl__gc_owner(gc);
......
......@@ -537,7 +537,12 @@ int libxl_domain_remus_start(libxl_ctx *ctx, libxl_domain_remus_info *info,
uint32_t domid, int send_fd, int recv_fd,
const libxl_asyncop_how *ao_how)
LIBXL_EXTERNAL_CALLERS_ONLY;
#ifdef CONFIG_XENCAP
int libxl_domain_setcap(libxl_ctx *ctx, libxl_domain_cap_info *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);
int libxl_domain_destroy(libxl_ctx *ctx, uint32_t domid,
......
......@@ -468,6 +468,13 @@ libxl_domain_remus_info = Struct("domain_remus_info",[
("compression", bool),
])
#ifdef CONFIG_XENCAP
libxl_domain_cap_info = Struct("domain_cap_info",[
("hypercalls", string),
("pci_devices", string),
("memory", string),
])
#endif
libxl_event_type = Enumeration("event_type", [
(1, "DOMAIN_SHUTDOWN"),
(2, "DOMAIN_DEATH"),
......
......@@ -101,6 +101,10 @@ int main_getenforce(int argc, char **argv);
int main_setenforce(int argc, char **argv);
int main_loadpolicy(int argc, char **argv);
int main_remus(int argc, char **argv);
#ifdef CONFIG_XENCAP
int main_setcap(int argc, char **argv);
int main_capinfo(int argc, char **argv);
#endif
void help(const char *command);
......
......@@ -6786,6 +6786,54 @@ int main_remus(int argc, char **argv)
return -ERROR_FAIL;
}
#ifdef CONFIG_XENCAP
int main_setcap(int argc, char **argv)
{
uint32_t domid;
int opt;
int ret = 0;
libxl_domain_cap_info c_info;
memset(&c_info, 0, sizeof(libxl_domain_cap_info));
while ((opt = def_getopt(argc, argv, "h:p:m:", "setcap", 1)) != -1) {
switch (opt) {
case 0: case 2:
return opt;
case 'h':
c_info.hypercalls = optarg;
break;
case 'p':
c_info.pci_devices = optarg;
break;
case 'm':
c_info.memory = optarg;
break;
}
}
printf("c_info.hypercalls : %s \n",c_info.hypercalls);
printf("c_info.pci_devices : %s \n",c_info.pci_devices);
printf("c_info.memory : %s \n",c_info.memory);
domid = find_domain(argv[optind]);
printf("Domid : %d\n",domid);
printf("Calling libxl_domain_setcap()\n");
ret = libxl_domain_setcap(ctx, &c_info, domid);
return ret;
}
int main_capinfo(int argc, char **argv)
{
int ret;
printf("This is capinfo.\n");
printf("argc is %d and optind=%d and argv[optind]=%s",argc,optind,argv[optind]);
ret = 0;
return ret;
}
#endif
/*
* Local variables:
* mode: C
......
......@@ -460,6 +460,22 @@ struct cmd_spec cmd_table[] = {
" of the domain."
},
#ifdef CONFIG_XENCAP
{ "setcap",
&main_setcap, 0, 1,
"Sets the capabilities on a particular domain",
"[options] <Domain>",
"-h Allow these hypercalls.\n"
"-p Allow access to these pci_devices.\n"
"-m Allow R/W to these pages of memory.\n"
},
{ "capinfo",
&main_capinfo, 0, 1,
"Tells if the domain is in capability mode",
},
#endif
};
int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
......
......@@ -257,6 +257,7 @@ struct domain *domain_create(
printk("setting d->cap_flag\n");
d->cap_flag = 1;
}
d->cap_space = NULL;
#endif
printk("Before is_idle_domain()\n");
if ( !is_idle_domain(d) )
......@@ -317,6 +318,8 @@ struct domain *domain_create(
spin_unlock(&domlist_update_lock);
}
printk("After is_idle_domain()\n");
return d;
fail:
printk("In fail\n");
d->is_dying = DOMDYING_dead;
......
......@@ -1060,6 +1060,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
struct domain *d;
struct capability *cap;
printk("In XEN_DOMCTL_cap_create().\n");
ret = -ESRCH;
d = rcu_lock_domain_by_id(op->domain);
if ( d == NULL )
......@@ -1070,9 +1071,10 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
cap = op->u.cap_create.cap;
ret = cap_create(d, cap);
printk("Leaving XEN_DOMCTL_cap_create().\n");
rcu_unlock_domain(d);
}
break;
......@@ -1085,11 +1087,13 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
void *list;
int size;
printk("In XEN_DOMCTL_cap_grant().\n");
ret = -ESRCH;
d = rcu_lock_domain_by_id(op->domain);
if ( d == NULL )
{
TT_ERR("Failed to rcu_lock_dom_by_id:%d\n", op->domain);
rcu_unlock_domain(d);
break;
}
......@@ -1097,24 +1101,54 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
if ( from == NULL )
{
TT_ERR("Failed to rcu_lock_dom_by_id:%d\n", op->domain);
rcu_unlock_domain(from);
break;
}
if ( from->cap_space == NULL )
{
TT_ERR("cap_space is NULL in from domain in cap_grant()\n");
rcu_unlock_domain(from);
break;
}
to = rcu_lock_domain_by_id(op->u.cap_grant.to);
if ( to == NULL )
{
TT_ERR("Failed to rcu_lock_dom_by_id:%d\n", op->domain);
rcu_unlock_domain(to);
break;
}
/* create the cap space for the to domain */
if ( (ret = xsm_domain_create(to, 1234)) != 0 )
{
if ( to->cap_space == NULL )
{
TT_ERR("xsm_domain_create failed to create cap_space for to_domain in xc_cap_grant().\n");
rcu_unlock_domain(to);
break;
}
}
type = op->u.cap_grant.type;
list = op->u.cap_grant.list;
size = op->u.cap_grant.size;
ret = cap_grant(from,to,type,list,size);
if ( (ret = cap_grant(from,to,type,list,size)) != 0 )
{
TT_ERR("cap_grant failed when called from xc_cap_grant().\n");
rcu_unlock_domain(to);
rcu_unlock_domain(from);
rcu_unlock_domain(d);
break;
}
printk("Leaving XEN_DOMCTL_cap_grant().\n");
rcu_unlock_domain(d);
rcu_unlock_domain(from);
rcu_unlock_domain(to);
}
break;
......@@ -1124,6 +1158,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
int type;
struct capability *cap;
printk("In XEN_DOMCTL_cap_check().\n");
ret = -ESRCH;
d = rcu_lock_domain_by_id(op->domain);
if ( d == NULL )
......@@ -1136,7 +1171,8 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
type = op->u.cap_check.type;
ret = cap_check(d,type,cap);
printk("Leaving XEN_DOMCTL_cap_check().\n");
rcu_unlock_domain(d);
}
......
......@@ -31,7 +31,21 @@ static int cap_domain_create(struct domain *d, u32 ssidref)
{
int rc = 0;
struct cap_space *dom0_cap_space = (struct cap_space *)xmalloc(struct cap_space);
struct cap_space *dom_cap_space = xmalloc(struct cap_space);
if ( dom_cap_space == NULL )
{
printk("dom_cap_space allocation failed in cap_domain_create()!\n");
return -1;
}
dom_cap_space->cap_hypercalls = xmalloc_array(struct capability, NUM_HYPERCALLS);
if ( dom_cap_space->cap_hypercalls == NULL )
{
xfree(dom_cap_space);
printk("dom_cap_space->cap_hypercalls allocation failed in cap_domain_create()!\n");
return -1;
}
printk("In cap_domain_create\n");
......@@ -41,16 +55,24 @@ static int cap_domain_create(struct domain *d, u32 ssidref)
* simply point the dom0's cap_space pointer to the
* CAP_BOOT_INFO's capability list for various resources.
*/
if ( IS_PRIV(d) )
/* Hack: IS_PRIV don't recognize domain 0 as priv ; so
* using domid instead.
*/
if ( d->domain_id == 0 )
{
dom0_cap_space->cap_hypercalls = CAP_BOOT_INFO->cap_hypercalls;
d->cap_space = dom0_cap_space;
printk("Init'ing capabilities for domain %d\n",d->domain_id);
dom_cap_space->cap_hypercalls = CAP_BOOT_INFO->cap_hypercalls;
d->cap_space = dom_cap_space;
return rc;
}
else
xfree(dom0_cap_space);
printk("Init'ing cap_space for guest domain: %d\n",d->domain_id);
/* Guest domain */
d->cap_space = dom_cap_space;
printk("Returning from cap_domain_create\n");
return rc;
......
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