This patch replaces the union structure parameter of the Access Control Module
hypercalls with command-specific request structures. It aligns the ACM
hypercalls with the way parameters are passed in the event channel hypercalls.
Advantages include backward-compatibility regarding old guests when new calls
are added and clarity of the code.
Regards
Reiner
Signed-off by: Reiner Sailer <sailer@xxxxxxxxxx>
---
tools/libxc/xc_acm.c | 31 ++---
tools/libxc/xenctrl.h | 2
tools/python/xen/lowlevel/acm/acm.c | 44 ++++----
tools/security/secpol_tool.c | 32 +++---
xen/common/acm_ops.c | 188 +++++++++++++++++-------------------
xen/include/public/acm_ops.h | 54 +++++-----
xen/include/xen/hypercall.h | 2
7 files changed, 169 insertions(+), 184 deletions(-)
Index: xen-unstable.hg-shype/tools/libxc/xc_acm.c
===================================================================
--- xen-unstable.hg-shype.orig/tools/libxc/xc_acm.c
+++ xen-unstable.hg-shype/tools/libxc/xc_acm.c
@@ -1,14 +1,11 @@
/******************************************************************************
+ * xc_acm.c
*
- * Copyright (C) 2005 IBM Corporation
+ * Copyright (C) 2005, 2006 IBM Corporation, R Sailer
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
- * Authors:
- * Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- * Stefan Berger <stefanb@xxxxxxxxxxxxxx>
- *
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2 of the
@@ -17,29 +14,23 @@
#include "xc_private.h"
-int xc_acm_op(int xc_handle, struct acm_op *op)
+
+int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size)
{
int ret = -1;
DECLARE_HYPERCALL;
- op->interface_version = ACM_INTERFACE_VERSION;
-
hypercall.op = __HYPERVISOR_acm_op;
- hypercall.arg[0] = (unsigned long) op;
+ hypercall.arg[0] = cmd;
+ hypercall.arg[1] = (unsigned long) arg;
- if (mlock(op, sizeof(*op)) != 0) {
- PERROR("Could not lock memory for Xen policy hypercall");
- goto out1;
+ if (mlock(arg, arg_size) != 0) {
+ PERROR("xc_acm_op: arg mlock failed");
+ goto out;
}
-
ret = do_xen_hypercall(xc_handle, &hypercall);
- ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, &hypercall);
- if (ret < 0) {
- goto out2;
- }
- out2:
- safe_munlock(op, sizeof(*op));
- out1:
+ safe_munlock(arg, arg_size);
+ out:
return ret;
}
Index: xen-unstable.hg-shype/tools/libxc/xenctrl.h
===================================================================
--- xen-unstable.hg-shype.orig/tools/libxc/xenctrl.h
+++ xen-unstable.hg-shype/tools/libxc/xenctrl.h
@@ -594,6 +594,6 @@ int xc_add_mmu_update(int xc_handle, xc_
unsigned long long ptr, unsigned long long val);
int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu);
-int xc_acm_op(int xc_handle, struct acm_op *op);
+int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size);
#endif
Index: xen-unstable.hg-shype/tools/python/xen/lowlevel/acm/acm.c
===================================================================
--- xen-unstable.hg-shype.orig/tools/python/xen/lowlevel/acm/acm.c
+++ xen-unstable.hg-shype/tools/python/xen/lowlevel/acm/acm.c
@@ -38,7 +38,7 @@ fprintf(stderr, "ERROR: " _m " (%d = %s)
/* generic shared function */
void * __getssid(int domid, uint32_t *buflen)
{
- struct acm_op op;
+ struct acm_getssid getssid;
int xc_handle;
#define SSID_BUFFER_SIZE 4096
void *buf = NULL;
@@ -51,14 +51,13 @@ void * __getssid(int domid, uint32_t *bu
goto out2;
}
memset(buf, 0, SSID_BUFFER_SIZE);
- op.cmd = ACM_GETSSID;
- op.interface_version = ACM_INTERFACE_VERSION;
- op.u.getssid.ssidbuf = buf;
- op.u.getssid.ssidbuf_size = SSID_BUFFER_SIZE;
- op.u.getssid.get_ssid_by = DOMAINID;
- op.u.getssid.id.domainid = domid;
+ getssid.interface_version = ACM_INTERFACE_VERSION;
+ getssid.ssidbuf = buf;
+ getssid.ssidbuf_size = SSID_BUFFER_SIZE;
+ getssid.get_ssid_by = DOMAINID;
+ getssid.id.domainid = domid;
- if (xc_acm_op(xc_handle, &op) < 0) {
+ if (xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid)) < 0) {
if (errno == EACCES)
PERROR("ACM operation failed.");
free(buf);
@@ -147,7 +146,7 @@ static PyObject *getssid(PyObject * self
static PyObject *getdecision(PyObject * self, PyObject * args)
{
char *arg1_name, *arg1, *arg2_name, *arg2, *decision = NULL;
- struct acm_op op;
+ struct acm_getdecision getdecision;
int xc_handle;
if (!PyArg_ParseTuple(args, "ssss", &arg1_name, &arg1, &arg2_name, &arg2))
{
@@ -163,34 +162,33 @@ static PyObject *getdecision(PyObject *
(strcmp(arg2_name, "domid") && strcmp(arg2_name, "ssidref")))
return NULL;
- op.cmd = ACM_GETDECISION;
- op.interface_version = ACM_INTERFACE_VERSION;
- op.u.getdecision.hook = SHARING;
+ getdecision.interface_version = ACM_INTERFACE_VERSION;
+ getdecision.hook = SHARING;
if (!strcmp(arg1_name, "domid")) {
- op.u.getdecision.get_decision_by1 = DOMAINID;
- op.u.getdecision.id1.domainid = atoi(arg1);
+ getdecision.get_decision_by1 = DOMAINID;
+ getdecision.id1.domainid = atoi(arg1);
} else {
- op.u.getdecision.get_decision_by1 = SSIDREF;
- op.u.getdecision.id1.ssidref = atol(arg1);
+ getdecision.get_decision_by1 = SSIDREF;
+ getdecision.id1.ssidref = atol(arg1);
}
if (!strcmp(arg2_name, "domid")) {
- op.u.getdecision.get_decision_by2 = DOMAINID;
- op.u.getdecision.id2.domainid = atoi(arg2);
+ getdecision.get_decision_by2 = DOMAINID;
+ getdecision.id2.domainid = atoi(arg2);
} else {
- op.u.getdecision.get_decision_by2 = SSIDREF;
- op.u.getdecision.id2.ssidref = atol(arg2);
+ getdecision.get_decision_by2 = SSIDREF;
+ getdecision.id2.ssidref = atol(arg2);
}
- if (xc_acm_op(xc_handle, &op) < 0) {
+ if (xc_acm_op(xc_handle, ACMOP_getdecision, &getdecision,
sizeof(getdecision)) < 0) {
if (errno == EACCES)
PERROR("ACM operation failed.");
}
xc_interface_close(xc_handle);
- if (op.u.getdecision.acm_decision == ACM_ACCESS_PERMITTED)
+ if (getdecision.acm_decision == ACM_ACCESS_PERMITTED)
decision = "PERMITTED";
- else if (op.u.getdecision.acm_decision == ACM_ACCESS_DENIED)
+ else if (getdecision.acm_decision == ACM_ACCESS_DENIED)
decision = "DENIED";
return Py_BuildValue("s", decision);
Index: xen-unstable.hg-shype/tools/security/secpol_tool.c
===================================================================
--- xen-unstable.hg-shype.orig/tools/security/secpol_tool.c
+++ xen-unstable.hg-shype/tools/security/secpol_tool.c
@@ -231,14 +231,16 @@ void acm_dump_policy_buffer(void *buf, i
uint8_t pull_buffer[PULL_CACHE_SIZE];
int acm_domain_getpolicy(int xc_handle)
{
- struct acm_op op;
+ struct acm_getpolicy getpolicy;
int ret;
memset(pull_buffer, 0x00, sizeof(pull_buffer));
- op.cmd = ACM_GETPOLICY;
- op.u.getpolicy.pullcache = (void *) pull_buffer;
- op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
- if ((ret = xc_acm_op(xc_handle, &op)) < 0) {
+ getpolicy.interface_version = ACM_INTERFACE_VERSION;
+ getpolicy.pullcache = (void *) pull_buffer;
+ getpolicy.pullcache_size = sizeof(pull_buffer);
+ ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
+
+ if (ret < 0) {
printf("ACM operation failed: errno=%d\n", errno);
if (errno == EACCES)
fprintf(stderr, "ACM operation failed -- need to"
@@ -275,13 +277,13 @@ int acm_domain_loadpolicy(int xc_handle,
goto free_out;
}
if (len == read(fd, buffer, len)) {
- struct acm_op op;
+ struct acm_setpolicy setpolicy;
/* dump it and then push it down into xen/acm */
acm_dump_policy_buffer(buffer, len);
- op.cmd = ACM_SETPOLICY;
- op.u.setpolicy.pushcache = (void *) buffer;
- op.u.setpolicy.pushcache_size = len;
- ret = xc_acm_op(xc_handle, &op);
+ setpolicy.interface_version = ACM_INTERFACE_VERSION;
+ setpolicy.pushcache = (void *) buffer;
+ setpolicy.pushcache_size = len;
+ ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy,
sizeof(setpolicy));
if (ret)
printf
@@ -322,15 +324,15 @@ void dump_ste_stats(struct acm_ste_stats
int acm_domain_dumpstats(int xc_handle)
{
uint8_t stats_buffer[PULL_STATS_SIZE];
- struct acm_op op;
+ struct acm_dumpstats dumpstats;
int ret;
struct acm_stats_buffer *stats;
memset(stats_buffer, 0x00, sizeof(stats_buffer));
- op.cmd = ACM_DUMPSTATS;
- op.u.dumpstats.pullcache = (void *) stats_buffer;
- op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
- ret = xc_acm_op(xc_handle, &op);
+ dumpstats.interface_version = ACM_INTERFACE_VERSION;
+ dumpstats.pullcache = (void *) stats_buffer;
+ dumpstats.pullcache_size = sizeof(stats_buffer);
+ ret = xc_acm_op(xc_handle, ACMOP_dumpstats, &dumpstats, sizeof(dumpstats));
if (ret < 0) {
printf
Index: xen-unstable.hg-shype/xen/common/acm_ops.c
===================================================================
--- xen-unstable.hg-shype.orig/xen/common/acm_ops.c
+++ xen-unstable.hg-shype/xen/common/acm_ops.c
@@ -32,100 +32,94 @@
#ifndef ACM_SECURITY
-long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
+
+long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
return -ENOSYS;
}
+
#else
-enum acm_operation {
- POLICY, /* access to policy interface (early drop) */
- GETPOLICY, /* dump policy cache */
- SETPOLICY, /* set policy cache (controls security) */
- DUMPSTATS, /* dump policy statistics */
- GETSSID, /* retrieve ssidref for domain id (decide
inside authorized domains) */
- GETDECISION /* retrieve ACM decision from authorized
domains */
-};
-int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops)
+int acm_authorize_acm_ops(struct domain *d)
{
/* currently, policy management functions are restricted to privileged
domains */
if (!IS_PRIV(d))
return -EPERM;
-
return 0;
}
-long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
+
+long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
- long ret = 0;
- struct acm_op curop, *op = &curop;
+ long rc = -EFAULT;
- if (acm_authorize_acm_ops(current->domain, POLICY))
+ if (acm_authorize_acm_ops(current->domain))
return -EPERM;
- if (copy_from_guest(op, u_acm_op, 1))
- return -EFAULT;
+ switch ( cmd )
+ {
- if (op->interface_version != ACM_INTERFACE_VERSION)
- return -EACCES;
+ case ACMOP_setpolicy: {
+ struct acm_setpolicy setpolicy;
+ if (copy_from_guest(&setpolicy, arg, 1) != 0)
+ return -EFAULT;
+ if (setpolicy.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
- switch (op->cmd)
- {
- case ACM_SETPOLICY:
- {
- ret = acm_authorize_acm_ops(current->domain, SETPOLICY);
- if (!ret)
- ret = acm_set_policy(op->u.setpolicy.pushcache,
- op->u.setpolicy.pushcache_size, 1);
+ rc = acm_set_policy(setpolicy.pushcache,
+ setpolicy.pushcache_size, 1);
+ break;
}
- break;
- case ACM_GETPOLICY:
- {
- ret = acm_authorize_acm_ops(current->domain, GETPOLICY);
- if (!ret)
- ret = acm_get_policy(op->u.getpolicy.pullcache,
- op->u.getpolicy.pullcache_size);
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
+ case ACMOP_getpolicy: {
+ struct acm_getpolicy getpolicy;
+ if (copy_from_guest(&getpolicy, arg, 1) != 0)
+ return -EFAULT;
+ if (getpolicy.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ rc = acm_get_policy(getpolicy.pullcache,
+ getpolicy.pullcache_size);
+ break;
}
- break;
- case ACM_DUMPSTATS:
- {
- ret = acm_authorize_acm_ops(current->domain, DUMPSTATS);
- if (!ret)
- ret = acm_dump_statistics(op->u.dumpstats.pullcache,
- op->u.dumpstats.pullcache_size);
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
+ case ACMOP_dumpstats: {
+ struct acm_dumpstats dumpstats;
+ if (copy_from_guest(&dumpstats, arg, 1) != 0)
+ return -EFAULT;
+ if (dumpstats.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ rc = acm_dump_statistics(dumpstats.pullcache,
+ dumpstats.pullcache_size);
+ break;
}
- break;
- case ACM_GETSSID:
- {
+ case ACMOP_getssid: {
+ struct acm_getssid getssid;
ssidref_t ssidref;
- ret = acm_authorize_acm_ops(current->domain, GETSSID);
- if (ret)
- break;
-
- if (op->u.getssid.get_ssid_by == SSIDREF)
- ssidref = op->u.getssid.id.ssidref;
- else if (op->u.getssid.get_ssid_by == DOMAINID)
+ if (copy_from_guest(&getssid, arg, 1) != 0)
+ return -EFAULT;
+ if (getssid.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ if (getssid.get_ssid_by == SSIDREF)
+ ssidref = getssid.id.ssidref;
+ else if (getssid.get_ssid_by == DOMAINID)
{
- struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
+ struct domain *subj = find_domain_by_id(getssid.id.domainid);
if (!subj)
{
- ret = -ESRCH; /* domain not found */
+ rc = -ESRCH; /* domain not found */
break;
}
if (subj->ssid == NULL)
{
put_domain(subj);
- ret = -ESRCH;
+ rc = -ESRCH;
break;
}
ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
@@ -133,39 +127,36 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
}
else
{
- ret = -ESRCH;
+ rc = -ESRCH;
break;
}
- ret = acm_get_ssid(ssidref,
- op->u.getssid.ssidbuf,
- op->u.getssid.ssidbuf_size);
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
+ rc = acm_get_ssid(ssidref, getssid.ssidbuf, getssid.ssidbuf_size);
+ break;
}
- break;
- case ACM_GETDECISION:
- {
+ case ACMOP_getdecision: {
+ struct acm_getdecision getdecision;
ssidref_t ssidref1, ssidref2;
- ret = acm_authorize_acm_ops(current->domain, GETDECISION);
- if (ret)
- break;
-
- if (op->u.getdecision.get_decision_by1 == SSIDREF)
- ssidref1 = op->u.getdecision.id1.ssidref;
- else if (op->u.getdecision.get_decision_by1 == DOMAINID)
+ if (copy_from_guest(&getdecision, arg, 1) != 0)
+ return -EFAULT;
+ if (getdecision.interface_version != ACM_INTERFACE_VERSION)
+ return -EACCES;
+
+ if (getdecision.get_decision_by1 == SSIDREF)
+ ssidref1 = getdecision.id1.ssidref;
+ else if (getdecision.get_decision_by1 == DOMAINID)
{
- struct domain *subj =
find_domain_by_id(op->u.getdecision.id1.domainid);
+ struct domain *subj = find_domain_by_id(getdecision.id1.domainid);
if (!subj)
{
- ret = -ESRCH; /* domain not found */
+ rc = -ESRCH; /* domain not found */
break;
}
if (subj->ssid == NULL)
{
put_domain(subj);
- ret = -ESRCH;
+ rc = -ESRCH;
break;
}
ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
@@ -173,23 +164,23 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
}
else
{
- ret = -ESRCH;
+ rc = -ESRCH;
break;
}
- if (op->u.getdecision.get_decision_by2 == SSIDREF)
- ssidref2 = op->u.getdecision.id2.ssidref;
- else if (op->u.getdecision.get_decision_by2 == DOMAINID)
+ if (getdecision.get_decision_by2 == SSIDREF)
+ ssidref2 = getdecision.id2.ssidref;
+ else if (getdecision.get_decision_by2 == DOMAINID)
{
- struct domain *subj =
find_domain_by_id(op->u.getdecision.id2.domainid);
+ struct domain *subj = find_domain_by_id(getdecision.id2.domainid);
if (!subj)
{
- ret = -ESRCH; /* domain not found */
+ rc = -ESRCH; /* domain not found */
break;;
}
if (subj->ssid == NULL)
{
put_domain(subj);
- ret = -ESRCH;
+ rc = -ESRCH;
break;
}
ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
@@ -197,34 +188,35 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
}
else
{
- ret = -ESRCH;
+ rc = -ESRCH;
break;
}
- ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
+ rc = acm_get_decision(ssidref1, ssidref2, getdecision.hook);
- if (ret == ACM_ACCESS_PERMITTED)
+ if (rc == ACM_ACCESS_PERMITTED)
{
- op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
- ret = 0;
+ getdecision.acm_decision = ACM_ACCESS_PERMITTED;
+ rc = 0;
}
- else if (ret == ACM_ACCESS_DENIED)
+ else if (rc == ACM_ACCESS_DENIED)
{
- op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
- ret = 0;
+ getdecision.acm_decision = ACM_ACCESS_DENIED;
+ rc = 0;
}
else
- ret = -ESRCH;
+ rc = -ESRCH;
- if (!ret)
- copy_to_guest(u_acm_op, op, 1);
+ if ( (rc == 0) && (copy_to_guest(arg, &getdecision, 1) != 0) )
+ rc = -EFAULT;
+ break;
}
- break;
default:
- ret = -ESRCH;
+ rc = -ENOSYS;
+ break;
}
- return ret;
+ return rc;
}
#endif
Index: xen-unstable.hg-shype/xen/include/public/acm_ops.h
===================================================================
--- xen-unstable.hg-shype.orig/xen/include/public/acm_ops.h
+++ xen-unstable.hg-shype/xen/include/public/acm_ops.h
@@ -2,7 +2,7 @@
* acm_ops.h: Xen access control module hypervisor commands
*
* Reiner Sailer <sailer@xxxxxxxxxxxxxx>
- * Copyright (c) 2005, International Business Machines Corporation.
+ * Copyright (c) 2005,2006 International Business Machines Corporation.
*/
#ifndef __XEN_PUBLIC_ACM_OPS_H__
@@ -17,36 +17,50 @@
* This makes sure that old versions of acm tools will stop working in a
* well-defined way (rather than crashing the machine, for instance).
*/
-#define ACM_INTERFACE_VERSION 0xAAAA0006
+#define ACM_INTERFACE_VERSION 0xAAAA0007
/************************************************************************/
-#define ACM_SETPOLICY 4
+/*
+ * Prototype for this hypercall is:
+ * int acm_op(int cmd, void *args)
+ * @cmd == ACMOP_??? (access control module operation).
+ * @args == Operation-specific extra arguments (NULL if none).
+ */
+
+
+#define ACMOP_setpolicy 1
struct acm_setpolicy {
- /* OUT variables */
+ /* IN */
+ uint32_t interface_version;
void *pushcache;
uint32_t pushcache_size;
};
-#define ACM_GETPOLICY 5
+#define ACMOP_getpolicy 2
struct acm_getpolicy {
- /* OUT variables */
+ /* IN */
+ uint32_t interface_version;
void *pullcache;
uint32_t pullcache_size;
};
-#define ACM_DUMPSTATS 6
+#define ACMOP_dumpstats 3
struct acm_dumpstats {
+ /* IN */
+ uint32_t interface_version;
void *pullcache;
uint32_t pullcache_size;
};
-#define ACM_GETSSID 7
+#define ACMOP_getssid 4
enum get_type {UNSET=0, SSIDREF, DOMAINID};
struct acm_getssid {
+ /* IN */
+ uint32_t interface_version;
enum get_type get_ssid_by;
union {
domaintype_t domainid;
@@ -56,9 +70,11 @@ struct acm_getssid {
uint32_t ssidbuf_size;
};
-#define ACM_GETDECISION 8
+#define ACMOP_getdecision 5
struct acm_getdecision {
- enum get_type get_decision_by1; /* in */
+ /* IN */
+ uint32_t interface_version;
+ enum get_type get_decision_by1;
enum get_type get_decision_by2;
union {
domaintype_t domainid;
@@ -69,30 +85,16 @@ struct acm_getdecision {
ssidref_t ssidref;
} id2;
enum acm_hook_type hook;
- int acm_decision; /* out */
+ /* OUT */
+ int acm_decision;
};
-typedef struct acm_op {
- uint32_t cmd;
- uint32_t interface_version; /* ACM_INTERFACE_VERSION */
- union {
- struct acm_setpolicy setpolicy;
- struct acm_getpolicy getpolicy;
- struct acm_dumpstats dumpstats;
- struct acm_getssid getssid;
- struct acm_getdecision getdecision;
- } u;
-} acm_op_t;
-DEFINE_XEN_GUEST_HANDLE(acm_op_t);
-
#endif /* __XEN_PUBLIC_ACM_OPS_H__ */
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
* indent-tabs-mode: nil
* End:
*/
Index: xen-unstable.hg-shype/xen/include/xen/hypercall.h
===================================================================
--- xen-unstable.hg-shype.orig/xen/include/xen/hypercall.h
+++ xen-unstable.hg-shype/xen/include/xen/hypercall.h
@@ -80,7 +80,7 @@ do_vcpu_op(
extern long
do_acm_op(
- XEN_GUEST_HANDLE(acm_op_t) u_acm_op);
+ int cmd, XEN_GUEST_HANDLE(void) arg);
extern long
do_nmi_op(
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|