Commit 8e351ea5 authored by Yathindra Naik's avatar Yathindra Naik

- Introduced do_cap_op hypercall for capability operations (domctl before)

- Shared do_cap_op with Linux-3.7.5 kernel
- xc_cap_* interface remains the same except its not a domctl op now
- Backend drivers now use the do_cap_op to grant caps to guest domain
- Xenstore runs fully on capabilities at this point
- Guest recognizes the virtual disk now; boots without causing a headache
parent 336cd518
......@@ -14,6 +14,9 @@ CTRL_SRCS-y += xc_evtchn.c
CTRL_SRCS-y += xc_gnttab.c
CTRL_SRCS-y += xc_misc.c
CTRL_SRCS-y += xc_flask.c
#ifdef CONFIG_XENCAP
CTRL_SRCS-y += xc_cap_op.c
#endif
CTRL_SRCS-y += xc_physdev.c
CTRL_SRCS-y += xc_private.c
CTRL_SRCS-y += xc_sedf.c
......
/*
* xc_cap_op.c
* xc interface to capability operations
*/
#include "xc_private.h"
int xc_cap_create(xc_interface *xch, /*uint32_t domid,*/ struct capability *cap)
{
DECLARE_CAP_OP;
DPRINTF("xc_cap_op: xc_cap_create().\n");
cap_op.cmd = XEN_CAP_OP_cap_create;
/*cap_op.domain = domid;*/
cap_op.u.cap_create.cap = cap;
return do_cap_op(xch, &cap_op);
}
int xc_cap_grant(xc_interface *xch,
/*uint32_t from_domid,*/
uint32_t to_domid,
int type,
void *list,
int size)
{
DECLARE_CAP_OP;
DPRINTF("xc_cap_op: xc_cap_grant().\n");
cap_op.cmd = XEN_CAP_OP_cap_grant;
/* Not sure if I should init the domid here as we
* are not using it in cap_op.c
*/
/*cap_op.domain = (domid_t)from_domid;*/
/*cap_op.u.cap_grant.from = (domid_t)from_domid;*/
cap_op.u.cap_grant.to = (domid_t)to_domid;
cap_op.u.cap_grant.type = type;
cap_op.u.cap_grant.list = list;
cap_op.u.cap_grant.size = size;
return do_cap_op(xch, &cap_op);
}
int xc_cap_check(xc_interface *xch,
uint32_t domid,
int type,
struct capability *cap)
{
DECLARE_CAP_OP;
DPRINTF("xc_cap_op: xc_cap_check().\n");
cap_op.cmd = XEN_CAP_OP_cap_check;
cap_op.domain = (domid_t)domid;
cap_op.u.cap_check.type = type;
cap_op.u.cap_check.cap = cap;
return do_cap_op(xch, &cap_op);
}
......@@ -1517,7 +1517,7 @@ int xc_domain_set_virq_handler(xc_interface *xch, uint32_t domid, int virq)
}
#ifdef CONFIG_XENCAP
#if 0
int xc_cap_create(xc_interface *xch, /*uint32_t domid,*/ struct capability *cap)
{
DECLARE_DOMCTL;
......@@ -1567,6 +1567,7 @@ int xc_cap_check(xc_interface *xch,
DPRINTF("Leaving xc_cap_check().\n");
return do_domctl(xch, &domctl);
}
#endif
#endif /* CONFIG_XENCAP */
/*
......
......@@ -43,12 +43,18 @@
#define DECLARE_SYSCTL struct xen_sysctl sysctl = { 0 }
#define DECLARE_PHYSDEV_OP struct physdev_op physdev_op = { 0 }
#define DECLARE_FLASK_OP struct xen_flask_op op = { 0 }
#ifdef CONFIG_XENCAP
#define DECLARE_CAP_OP struct xen_cap_op cap_op = { 0 }
#endif
#else
#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall
#define DECLARE_DOMCTL struct xen_domctl domctl
#define DECLARE_SYSCTL struct xen_sysctl sysctl
#define DECLARE_PHYSDEV_OP struct physdev_op physdev_op
#define DECLARE_FLASK_OP struct xen_flask_op op
#ifdef CONFIG_XENCAP
#define DECLARE_CAP_OP struct xen_cap_op cap_op
#endif
#endif
#undef PAGE_SHIFT
......@@ -261,6 +267,37 @@ static inline int do_domctl(xc_interface *xch, struct xen_domctl *domctl)
return ret;
}
#ifdef CONFIG_XENCAP
static inline int do_cap_op(xc_interface *xch, struct xen_cap_op *cap_op)
{
int ret = -1;
DECLARE_HYPERCALL;
DECLARE_HYPERCALL_BOUNCE(cap_op, sizeof(*cap_op), XC_HYPERCALL_BUFFER_BOUNCE_BOTH);
cap_op->interface_version = XEN_CAP_OP_INTERFACE_VERSION;
if ( xc_hypercall_bounce_pre(xch, cap_op) )
{
PERROR("Could not bounce buffer for cap_op hypercall");
goto out1;
}
hypercall.op = __HYPERVISOR_cap_op;
hypercall.arg[0] = HYPERCALL_BUFFER_AS_ARG(cap_op);
if ( (ret = do_xen_hypercall(xch, &hypercall)) < 0 )
{
if ( errno == EACCES )
DPRINTF("cap_op operation failed -- need to"
" rebuild the user-space tool set?\n");
}
xc_hypercall_bounce_post(xch, cap_op);
out1:
return ret;
}
#endif
static inline int do_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
{
int ret = -1;
......
......@@ -48,7 +48,7 @@
#include <xen/tmem.h>
#ifdef CONFIG_XENCAP
#include <xen/xsm/cap.h>
#include <xen/cap_op.h>
#endif
#include "xentoollog.h"
......
......@@ -166,6 +166,13 @@ retry_transaction:
if (xc_cap_grant(ctx->xch, device->domid, 2, &list, 1))
LOG(DEBUG, "Granting caps for %s failed\n",frontend_child);
}
if (!xc_cap_check(ctx->xch, device->domid, 2, &caps[1])) {
list[0] = caps[1];
LOG(DEBUG, "Granting caps for domid %d for %s\n",device->domid, frontend_child);
LOG(DEBUG, "caps[1]: %d\n",caps[1].magic);
if (xc_cap_grant(ctx->xch, device->domid, 2, &list, 1))
LOG(DEBUG, "Granting caps for %s failed\n",frontend_child);
}
#endif
#ifdef CONFIG_XENCAP
libxl__xs_writev(gc, t, frontend_path, fents, device->domid, 'b');
......@@ -192,7 +199,7 @@ retry_transaction:
}
#endif
#ifdef CONFIG_XENCAP
libxl__xs_writev(gc, t, backend_path, bents, device->domid, 'b');
libxl__xs_writev(gc, t, backend_path, bents, device->domid, 'r');
#else
libxl__xs_writev(gc, t, backend_path, bents);
#endif
......
......@@ -77,7 +77,7 @@ int libxl__xs_writev(libxl__gc *gc, xs_transaction_t t,
}
if (perm == 'w' || perm == 'b') {
list[0] = caps[1];
if (!xc_cap_check(ctx->xch, domid, 2, &list[1])) {
if (!xc_cap_check(ctx->xch, domid, 2, &list[0])) {
LOG(DEBUG, "Granting caps for domain %d for %s/%s", domid, dir, kvs[i]);
LOG(DEBUG, "caps[0]: %d and caps[1]: %d", caps[0].magic, caps[1].magic);
if (xc_cap_grant(ctx->xch, domid, 2, &list, 1))
......
......@@ -11,7 +11,7 @@
XEN_ROOT = $(CURDIR)/../..
include $(XEN_ROOT)/tools/Rules.mk
PROGRAMS = xc_restore xc_save readnotes lsevtchn
PROGRAMS = xc_restore xc_save readnotes lsevtchn
CFLAGS += -Werror
......
......@@ -1299,8 +1299,9 @@ static struct node *construct_node(struct connection *conn, const char *name)
struct node *parent, *node;
char *children, *parentname = get_parent(name);
xc_interface *xch;
struct capability list[2];
#ifdef CONFIG_XENCAP
//int domid = get_domid(conn);
int domid = get_domid(conn);
xch = xc_interface_open(0,0,0);
if(xch == 0)
......@@ -1354,6 +1355,8 @@ static struct node *construct_node(struct connection *conn, const char *name)
node->num_caps = 2;
node->caps = talloc_array(node, struct capability, 2);
log("Target of conn: %p, Node: %s, conn->id:%d conn->domain:%p\n",conn->target, node->name, conn->id, conn->domain);
if (xc_cap_create(xch, &node->caps[0]))
{
xc_interface_close(xch);
......@@ -1368,37 +1371,24 @@ static struct node *construct_node(struct connection *conn, const char *name)
// should return err
}
#endif
#if 0
/* Say node's parent has "n0 r1".
This says dom0 is the owner, dom1 has read perms.
Now say this node happens to have domid 1, then
check if it has caps to parents and then grant
them to this node. */
/* Grant read/write caps to the creating domain. */
/* Grant read/write caps to the creating domain.
* Note: If a guest domain is creating this node,
* we grant it both read/write caps since it must
* be the owner of this node.
*/
if (domid != -1 && domid != 0 && conn->cap_flag)
{
if (xc_cap_check(xch,domid,2,&node->caps[0]))
{
log("construct_node: Granting read cap to node: %s\n",node->name);
node->caps[0] = parent->caps[0];
//if (xc_cap_grant(xch, domid, 2, &list, 2) == 1)
// log("construct_node: Error in xc_cap_grant.\n");
}
log("Construct_node: Guest domain: %d is making an entry in Xenstore\n",domid);
list[0] = node->caps[0];
log("construct_node: Granting read cap to domain:%d for node: %s\n",domid,node->name);
if (xc_cap_grant(xch, domid, 2, &list, 1) == 1)
log("construct_node: Error in xc_cap_grant.\n");
if (xc_cap_check(xch,domid,2,&parent->caps[1]))
{
log("construct_node: Granting write cap to node: %s\n",node->name);
node->caps[1] = parent->caps[1];
}
list[0] = node->caps[1];
log("construct_node: Granting write cap to domain:%d for node: %s\n",domid,node->name);
if (xc_cap_grant(xch, domid, 2, &list, 1) == 1)
log("construct_node: Error in xc_cap_grant.\n");
}
else
log("construct_node: Not granting, either domid == -1, domid == 0 or conn->cap_flag not set!\n");
#endif
if (domain_is_unprivileged(conn))
node->perms[0].id = conn->id;
......@@ -1497,6 +1487,7 @@ static void do_write(struct connection *conn, struct buffered_data *in)
} else {
node->data = in->buffer + offset;
node->datalen = datalen;
log("writing node: %s and conn->id: %d\n",node->name, conn->id);
if (!write_node(conn, node)){
log("do_write: error in write_node\n");
send_error(conn, errno);
......@@ -1780,9 +1771,11 @@ static void do_set_perms(struct connection *conn, struct buffered_data *in)
static void do_get_caps(struct connection *conn, const char *name)
{
struct node *node;
char *path;
struct capability *caps = NULL;
node = get_node(conn, name, XS_PERM_NONE);
path = canonicalize(conn, name);
node = get_node(conn, path, XS_PERM_NONE);
if (!node) {
send_error(conn, errno);
return;
......
......@@ -418,12 +418,12 @@ static struct domain *new_domain(void *context, unsigned int domid,
domain->conn = new_connection(writechn, readchn);
domain->conn->domain = domain;
domain->conn->id = domid;
xprintf("Domain_id: %d gets connection:%p\n",domain->domid, domain->conn);
domain->remote_port = port;
domain->nbentry = 0;
domain->nbwatch = 0;
xprintf("new_domain: returning domain 0x%x\n",domain);
return domain;
}
......
......@@ -6,9 +6,6 @@
#include <stdarg.h>
#include <string.h>
#include "xenstore_lib.h"
#ifdef CONFIG_XENCAP
#include <xenctrl.h>
#endif
#include "tdb.h"
#include "talloc.h"
#include "utils.h"
......@@ -17,27 +14,16 @@ struct record_hdr {
uint32_t num_perms;
uint32_t datalen;
uint32_t childlen;
#ifdef CONFIG_XENCAP
uint32_t num_caps;
#endif
struct xs_permissions perms[0];
#ifdef CONFIG_XENCAP
struct capability caps[0];
#endif
};
static uint32_t total_size(struct record_hdr *hdr)
{
#ifdef CONFIG_XENCAP
return sizeof(*hdr) + hdr->num_perms * sizeof(struct xs_permissions) + hdr->num_caps * sizeof(struct capability)
+ hdr->datalen + hdr->childlen;
#else
return sizeof(*hdr) + hdr->num_perms * sizeof(struct xs_permissions)
+ hdr->datalen + hdr->childlen;
#endif
}
/*
static char perm_to_char(enum xs_perm_type perm)
{
return perm == XS_PERM_READ ? 'r' :
......@@ -46,7 +32,7 @@ static char perm_to_char(enum xs_perm_type perm)
perm == (XS_PERM_READ|XS_PERM_WRITE) ? 'b' :
'?';
}
*/
int main(int argc, char *argv[])
{
TDB_DATA key;
......@@ -70,20 +56,20 @@ int main(int argc, char *argv[])
fprintf(stderr, "%.*s: BAD truncated\n",
(int)key.dsize, key.dptr);
else if (data.dsize != total_size(hdr))
fprintf(stderr, "%.*s: BAD length %i for %i/%i/%i/%i (%i)\n",
fprintf(stderr, "%.*s: BAD length %i for %i/%i/%i (%i)\n",
(int)key.dsize, key.dptr, (int)data.dsize,
hdr->num_perms, hdr->datalen,
hdr->childlen, hdr->num_caps, total_size(hdr));
hdr->childlen, total_size(hdr));
else {
unsigned int i;
char *p;
printf("%.*s: ", (int)key.dsize, key.dptr);
/*for (i = 0; i < hdr->num_perms; i++)
for (i = 0; i < hdr->num_perms; i++)
printf("%s%c%i",
i == 0 ? "" : ",",
perm_to_char(hdr->perms[i].perms),
hdr->perms[i].id);*/
hdr->perms[i].id);
p = (void *)&hdr->perms[hdr->num_perms];
printf(" %.*s\n", hdr->datalen, p);
p += hdr->datalen;
......
......@@ -414,6 +414,7 @@ ENTRY(compat_hypercall_table)
.quad do_domctl
.quad compat_kexec_op
.quad do_tmem_op
.quad do_cap_op
.rept __HYPERVISOR_arch_0-((.-compat_hypercall_table)/8)
.quad compat_ni_hypercall
.endr
......@@ -462,6 +463,7 @@ ENTRY(compat_hypercall_args_table)
.byte 1 /* do_domctl */
.byte 2 /* compat_kexec_op */
.byte 1 /* do_tmem_op */
.byte 1 /* do_cap_op */
.rept __HYPERVISOR_arch_0-(.-compat_hypercall_args_table)
.byte 0 /* compat_ni_hypercall */
.endr
......
......@@ -707,6 +707,7 @@ ENTRY(hypercall_table)
.quad do_domctl
.quad do_kexec_op
.quad do_tmem_op
.quad do_cap_op
.rept __HYPERVISOR_arch_0-((.-hypercall_table)/8)
.quad do_ni_hypercall
.endr
......@@ -755,6 +756,7 @@ ENTRY(hypercall_args_table)
.byte 1 /* do_domctl */
.byte 2 /* do_kexec */
.byte 1 /* do_tmem_op */
.byte 1 /* do_cap_op */
.rept __HYPERVISOR_arch_0-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
......
......@@ -56,6 +56,7 @@ obj-$(CONFIG_XENCOMM) += xencomm.o
# Flux Xen Capabilities
obj-$(CONFIG_XENCAP) += xen-cap.o
obj-$(CONFIG_XENCAP) += cap_op.o
subdir-$(CONFIG_COMPAT) += compat
......
/*
* This file contains Capability hypercall definitions.
*
*/
#include <xen/sched.h>
#include <xen/hypercall.h>
#include <xen/guest_access.h>
#include <asm/current.h>
#include <public/cap_op.h>
#include <xen/xen-cap.h>
static DEFINE_SPINLOCK(cap_lock);
long do_cap_op(XEN_GUEST_HANDLE(xen_cap_op_t) u_cap_op)
{
long ret = 0;
struct xen_cap_op curop, *op = &curop;
if (op->domain < 0 || op->domain > 100)
op->domain = current->domain->domain_id;
if ( copy_from_guest(op, u_cap_op, 1) ){
TT_ERR("Copy from guest failed\n");
return -EFAULT;
}
if ( op->interface_version != XEN_CAP_OP_INTERFACE_VERSION )
return -EACCES;
spin_lock(&cap_lock);
switch ( op->cmd )
{
case XEN_CAP_OP_cap_create:
{
/* struct domain *d; */
struct capability *cap;
TT_DBG("XEN_CAP_OP_cap_create hypercall: domid:%d\n", op->domain);
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);
break;
}
*/
cap = op->u.cap_create.cap;
if ((ret = cap_create(cap)) == 1)
TT_ERR("cap_create failed\n");
// rcu_unlock_domain(d);
}
break;
case XEN_CAP_OP_cap_grant:
{
//struct domain *d;
struct domain *to;
int type;
void *list;
int size;
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);
break;
}
*/
TT_DBG("XEN_CAP_OP_cap_grant hypercall: domid:%d\n", op->domain);
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", to->domain_id);
break;
}
type = op->u.cap_grant.type;
list = op->u.cap_grant.list;
size = op->u.cap_grant.size;
if ( (ret = cap_grant(to,type,list,size)) != 0 )
{
TT_ERR("cap_grant failed when called from xc_cap_grant().\n");
rcu_unlock_domain(to);
//rcu_unlock_domain(d);
break;
}
//rcu_unlock_domain(d);
rcu_unlock_domain(to);
}
break;
case XEN_CAP_OP_cap_check:
{
struct domain *d;
int type;
struct capability *cap;
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);
break;
}
cap = op->u.cap_check.cap;
type = op->u.cap_check.type;
ret = cap_check(d,type,cap);
rcu_unlock_domain(d);
}
break;
}
spin_unlock(&cap_lock);
return ret;
}
......@@ -29,9 +29,11 @@
#include <public/domctl.h>
#include <xsm/xsm.h>
/*
#ifdef CONFIG_XENCAP
#include <xen/xen-cap.h>
#endif
*/
static DEFINE_SPINLOCK(domctl_lock);
DEFINE_SPINLOCK(vcpu_alloc_lock);
......@@ -1059,6 +1061,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
break;
#ifdef CONFIG_XENCAP
#if 0
case XEN_DOMCTL_cap_create:
{
/* struct domain *d; */
......@@ -1148,6 +1151,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl)
}
break;
#endif
#endif /* CONFIG_XENCAP */
default:
......
......@@ -367,6 +367,7 @@ DO(ni_hypercall)(void)
return -ENOSYS;
}
/*
* Local variables:
* mode: C
......
......@@ -9,6 +9,8 @@
* Date: September 2012
*/
#include <xen/mm.h>
#include <xen/xmalloc.h>
#include <xen/sched.h>
......
......@@ -96,6 +96,15 @@ do_set_callbacks(
unsigned long failsafe_address,
unsigned long syscall_address);
#ifdef CONFIG_XENCAP
#if 0
extern long
do_cap_op(
int cmd,
XEN_GUEST_HANDLE(void) arg);
#endif
#endif
extern long
do_set_segment_base(
unsigned int which,
......
/*
* cap_op.h
*
* This declares Capability related hypercalls.
*
*/
#ifndef __XEN_CAP_OP_H__
#define __XEN_CAP_OP_H__
#include "xen.h"
#include <xen/xen-cap.h>
#define XEN_CAP_OP_INTERFACE_VERSION 1
struct xen_cap_op_cap_create {
struct capability *cap;
};
typedef struct xen_cap_op_cap_create xen_cap_op_cap_create_t;
DEFINE_XEN_GUEST_HANDLE(xen_cap_op_cap_create_t);
struct xen_cap_op_cap_grant {
int to;
int type;
void *list;
int size;
};
typedef struct xen_cap_op_cap_grant xen_cap_op_cap_grant_t;
DEFINE_XEN_GUEST_HANDLE(xen_cap_op_cap_grant_t);
struct xen_cap_op_cap_check {
struct capability *cap;
int type;
};
typedef struct xen_cap_op_cap_check xen_cap_op_cap_check_t;
DEFINE_XEN_GUEST_HANDLE(xen_cap_op_cap_check_t);
struct xen_cap_op {
uint32_t cmd;
#define XEN_CAP_OP_cap_create 1
#define XEN_CAP_OP_cap_grant 2
#define XEN_CAP_OP_cap_check 3
uint32_t interface_version; /* XEN_CAP_OP_INTERFACE_VERSION */
domid_t domain;
union {
struct xen_cap_op_cap_create cap_create;
struct xen_cap_op_cap_grant cap_grant;
struct xen_cap_op_cap_check cap_check;
} u;
};
typedef struct xen_cap_op xen_cap_op_t;
DEFINE_XEN_GUEST_HANDLE(xen_cap_op_t);
#endif /* __XEN_CAP_OP_H__ */
......@@ -845,6 +845,7 @@ typedef struct xen_domctl_set_access_required xen_domctl_set_access_required_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_set_access_required_t);
#ifdef CONFIG_XENCAP
#if 0
struct xen_domctl_cap_create {
struct capability *cap;
......@@ -868,6 +869,7 @@ struct xen_domctl_cap_check {
};
typedef struct xen_domctl_cap_check xen_domctl_cap_check_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_cap_check_t);
#endif
#endif /* CONFIG_XENCAP */
struct xen_domctl {
......@@ -940,9 +942,11 @@ struct xen_domctl {
#define XEN_DOMCTL_gdbsx_unpausevcpu 1002
#define XEN_DOMCTL_gdbsx_domstatus 1003
#ifdef CONFIG_XENCAP
#if 0
#define XEN_DOMCTL_cap_create 100
#define XEN_DOMCTL_cap_grant 101
#define XEN_DOMCTL_cap_check 102
#endif
#endif /* CONFIG_XENCAP */
uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
domid_t domain;
......@@ -998,9 +1002,11 @@ struct xen_domctl {
struct xen_domctl_gdbsx_pauseunp_vcpu gdbsx_pauseunp_vcpu;
struct xen_domctl_gdbsx_domstatus gdbsx_domstatus;
#ifdef CONFIG_XENCAP
#if 0
struct xen_domctl_cap_create cap_create;
struct xen_domctl_cap_grant cap_grant;
struct xen_domctl_cap_check cap_check;
#endif
#endif /* CONFIG_XENCAP */
uint8_t pad[128];
} u;
......
......@@ -97,7 +97,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t);
#define __HYPERVISOR_domctl 36
#define __HYPERVISOR_kexec_op 37
#define __HYPERVISOR_tmem_op 38
#define __HYPERVISOR_xc_reserved_op 39 /* reserved for XenClient */
#define __HYPERVISOR_cap_op 39
#define __HYPERVISOR_xc_reserved_op 40 /* reserved for XenClient */
/* Architecture-specific hypercall definitions. */
#define __HYPERVISOR_arch_0 48
......
......@@ -9,6 +9,9 @@
#include <xen/time.h>
#include <public/xen.h>
#include <public/domctl.h>
#ifdef CONFIG_XENCAP
#include <public/cap_op.h>
#endif
#include <public/sysctl.h>
#include <public/platform.h>
#include <public/event_channel.h>
......@@ -35,6 +38,12 @@ extern long
do_domctl(
XEN_GUEST_HANDLE(xen_domctl_t) u_domctl);
#ifdef CONFIG_XENCAP
extern long
do_cap_op(
XEN_GUEST_HANDLE(xen_cap_op_t) u_cap_op);
#endif
extern long
arch_do_domctl(
struct xen_domctl *domctl,
......
......@@ -10,7 +10,7 @@
#ifndef __XEN_CAP_H__
#define __XEN_CAP_H__