direct-io.hg

changeset 10057:0f16f0871dc9

[ACM] Replace the union structure parameter of the ACM 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.

Signed-off by: Reiner Sailer <sailer@us.ibm.com>
author kaf24@firebug.cl.cam.ac.uk
date Sun May 21 19:05:31 2006 +0100 (2006-05-21)
parents e99987843336
children 14717dedba02
files tools/libxc/xc_acm.c tools/libxc/xenctrl.h tools/python/xen/lowlevel/acm/acm.c tools/security/secpol_tool.c xen/common/acm_ops.c xen/include/public/acm_ops.h xen/include/xen/hypercall.h
line diff
     1.1 --- a/tools/libxc/xc_acm.c	Sun May 21 18:57:42 2006 +0100
     1.2 +++ b/tools/libxc/xc_acm.c	Sun May 21 19:05:31 2006 +0100
     1.3 @@ -1,14 +1,11 @@
     1.4  /******************************************************************************
     1.5 + * xc_acm.c
     1.6   *
     1.7 - * Copyright (C) 2005 IBM Corporation
     1.8 + * Copyright (C) 2005, 2006 IBM Corporation, R Sailer
     1.9   *
    1.10   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
    1.11   * Use is subject to license terms.
    1.12   *
    1.13 - * Authors:
    1.14 - * Reiner Sailer <sailer@watson.ibm.com>
    1.15 - * Stefan Berger <stefanb@watson.ibm.com>
    1.16 - *
    1.17   * This program is free software; you can redistribute it and/or
    1.18   * modify it under the terms of the GNU General Public License as
    1.19   * published by the Free Software Foundation, version 2 of the
    1.20 @@ -17,29 +14,23 @@
    1.21  
    1.22  #include "xc_private.h"
    1.23  
    1.24 -int xc_acm_op(int xc_handle, struct acm_op *op)
    1.25 +
    1.26 +int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size)
    1.27  {
    1.28      int ret = -1;
    1.29      DECLARE_HYPERCALL;
    1.30  
    1.31 -    op->interface_version = ACM_INTERFACE_VERSION;
    1.32 -
    1.33      hypercall.op = __HYPERVISOR_acm_op;
    1.34 -    hypercall.arg[0] = (unsigned long) op;
    1.35 +    hypercall.arg[0] = cmd;
    1.36 +    hypercall.arg[1] = (unsigned long) arg;
    1.37  
    1.38 -    if (mlock(op, sizeof(*op)) != 0) {
    1.39 -        PERROR("Could not lock memory for Xen policy hypercall");
    1.40 -        goto out1;
    1.41 +    if (mlock(arg, arg_size) != 0) {
    1.42 +        PERROR("xc_acm_op: arg mlock failed");
    1.43 +        goto out;
    1.44      }
    1.45 -
    1.46      ret = do_xen_hypercall(xc_handle, &hypercall);
    1.47 -    ret = ioctl(xc_handle, IOCTL_PRIVCMD_HYPERCALL, &hypercall);
    1.48 -    if (ret < 0) {
    1.49 -        goto out2;
    1.50 -    }
    1.51 - out2:
    1.52 -    safe_munlock(op, sizeof(*op));
    1.53 - out1:
    1.54 +    safe_munlock(arg, arg_size);
    1.55 + out:
    1.56      return ret;
    1.57  }
    1.58  
     2.1 --- a/tools/libxc/xenctrl.h	Sun May 21 18:57:42 2006 +0100
     2.2 +++ b/tools/libxc/xenctrl.h	Sun May 21 19:05:31 2006 +0100
     2.3 @@ -594,6 +594,6 @@ int xc_add_mmu_update(int xc_handle, xc_
     2.4                     unsigned long long ptr, unsigned long long val);
     2.5  int xc_finish_mmu_updates(int xc_handle, xc_mmu_t *mmu);
     2.6  
     2.7 -int xc_acm_op(int xc_handle, struct acm_op *op);
     2.8 +int xc_acm_op(int xc_handle, int cmd, void *arg, size_t arg_size);
     2.9  
    2.10  #endif
     3.1 --- a/tools/python/xen/lowlevel/acm/acm.c	Sun May 21 18:57:42 2006 +0100
     3.2 +++ b/tools/python/xen/lowlevel/acm/acm.c	Sun May 21 19:05:31 2006 +0100
     3.3 @@ -38,7 +38,7 @@ fprintf(stderr, "ERROR: " _m " (%d = %s)
     3.4  /* generic shared function */
     3.5  void * __getssid(int domid, uint32_t *buflen)
     3.6  {
     3.7 -    struct acm_op op;
     3.8 +    struct acm_getssid getssid;
     3.9      int xc_handle;
    3.10      #define SSID_BUFFER_SIZE    4096
    3.11      void *buf = NULL;
    3.12 @@ -51,14 +51,13 @@ void * __getssid(int domid, uint32_t *bu
    3.13          goto out2;
    3.14      }
    3.15      memset(buf, 0, SSID_BUFFER_SIZE);
    3.16 -    op.cmd = ACM_GETSSID;
    3.17 -    op.interface_version = ACM_INTERFACE_VERSION;
    3.18 -    op.u.getssid.ssidbuf = buf;
    3.19 -    op.u.getssid.ssidbuf_size = SSID_BUFFER_SIZE;
    3.20 -    op.u.getssid.get_ssid_by = DOMAINID;
    3.21 -    op.u.getssid.id.domainid = domid;
    3.22 +    getssid.interface_version = ACM_INTERFACE_VERSION;
    3.23 +    getssid.ssidbuf = buf;
    3.24 +    getssid.ssidbuf_size = SSID_BUFFER_SIZE;
    3.25 +    getssid.get_ssid_by = DOMAINID;
    3.26 +    getssid.id.domainid = domid;
    3.27  
    3.28 -    if (xc_acm_op(xc_handle, &op) < 0) {
    3.29 +    if (xc_acm_op(xc_handle, ACMOP_getssid, &getssid, sizeof(getssid)) < 0) {
    3.30          if (errno == EACCES)
    3.31              PERROR("ACM operation failed.");
    3.32          free(buf);
    3.33 @@ -147,7 +146,7 @@ static PyObject *getssid(PyObject * self
    3.34  static PyObject *getdecision(PyObject * self, PyObject * args)
    3.35  {
    3.36      char *arg1_name, *arg1, *arg2_name, *arg2, *decision = NULL;
    3.37 -    struct acm_op op;
    3.38 +    struct acm_getdecision getdecision;
    3.39      int xc_handle;
    3.40  
    3.41      if (!PyArg_ParseTuple(args, "ssss", &arg1_name, &arg1, &arg2_name, &arg2)) {
    3.42 @@ -163,34 +162,33 @@ static PyObject *getdecision(PyObject * 
    3.43      (strcmp(arg2_name, "domid") && strcmp(arg2_name, "ssidref")))
    3.44          return NULL;
    3.45  
    3.46 -    op.cmd = ACM_GETDECISION;
    3.47 -    op.interface_version = ACM_INTERFACE_VERSION;
    3.48 -    op.u.getdecision.hook = SHARING;
    3.49 +    getdecision.interface_version = ACM_INTERFACE_VERSION;
    3.50 +    getdecision.hook = SHARING;
    3.51      if (!strcmp(arg1_name, "domid")) {
    3.52 -        op.u.getdecision.get_decision_by1 = DOMAINID;
    3.53 -        op.u.getdecision.id1.domainid = atoi(arg1);
    3.54 +        getdecision.get_decision_by1 = DOMAINID;
    3.55 +        getdecision.id1.domainid = atoi(arg1);
    3.56      } else {
    3.57 -        op.u.getdecision.get_decision_by1 = SSIDREF;
    3.58 -        op.u.getdecision.id1.ssidref = atol(arg1);
    3.59 +        getdecision.get_decision_by1 = SSIDREF;
    3.60 +        getdecision.id1.ssidref = atol(arg1);
    3.61      }
    3.62      if (!strcmp(arg2_name, "domid")) {
    3.63 -        op.u.getdecision.get_decision_by2 = DOMAINID;
    3.64 -        op.u.getdecision.id2.domainid = atoi(arg2);
    3.65 +        getdecision.get_decision_by2 = DOMAINID;
    3.66 +        getdecision.id2.domainid = atoi(arg2);
    3.67      } else {
    3.68 -        op.u.getdecision.get_decision_by2 = SSIDREF;
    3.69 -        op.u.getdecision.id2.ssidref = atol(arg2);
    3.70 +        getdecision.get_decision_by2 = SSIDREF;
    3.71 +        getdecision.id2.ssidref = atol(arg2);
    3.72      }
    3.73  
    3.74 -    if (xc_acm_op(xc_handle, &op) < 0) {
    3.75 +    if (xc_acm_op(xc_handle, ACMOP_getdecision, &getdecision, sizeof(getdecision)) < 0) {
    3.76          if (errno == EACCES)
    3.77              PERROR("ACM operation failed.");
    3.78      }
    3.79  
    3.80      xc_interface_close(xc_handle);
    3.81  
    3.82 -    if (op.u.getdecision.acm_decision == ACM_ACCESS_PERMITTED)
    3.83 +    if (getdecision.acm_decision == ACM_ACCESS_PERMITTED)
    3.84          decision = "PERMITTED";
    3.85 -    else if (op.u.getdecision.acm_decision == ACM_ACCESS_DENIED)
    3.86 +    else if (getdecision.acm_decision == ACM_ACCESS_DENIED)
    3.87          decision = "DENIED";
    3.88  
    3.89      return Py_BuildValue("s", decision);
     4.1 --- a/tools/security/secpol_tool.c	Sun May 21 18:57:42 2006 +0100
     4.2 +++ b/tools/security/secpol_tool.c	Sun May 21 19:05:31 2006 +0100
     4.3 @@ -231,14 +231,16 @@ void acm_dump_policy_buffer(void *buf, i
     4.4  uint8_t pull_buffer[PULL_CACHE_SIZE];
     4.5  int acm_domain_getpolicy(int xc_handle)
     4.6  {
     4.7 -    struct acm_op op;
     4.8 +    struct acm_getpolicy getpolicy;
     4.9      int ret;
    4.10  
    4.11      memset(pull_buffer, 0x00, sizeof(pull_buffer));
    4.12 -    op.cmd = ACM_GETPOLICY;
    4.13 -    op.u.getpolicy.pullcache = (void *) pull_buffer;
    4.14 -    op.u.getpolicy.pullcache_size = sizeof(pull_buffer);
    4.15 -    if ((ret = xc_acm_op(xc_handle, &op)) < 0) {
    4.16 +    getpolicy.interface_version = ACM_INTERFACE_VERSION;
    4.17 +    getpolicy.pullcache = (void *) pull_buffer;
    4.18 +    getpolicy.pullcache_size = sizeof(pull_buffer);
    4.19 +    ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
    4.20 +
    4.21 +    if (ret < 0) {
    4.22          printf("ACM operation failed: errno=%d\n", errno);
    4.23          if (errno == EACCES)
    4.24              fprintf(stderr, "ACM operation failed -- need to"
    4.25 @@ -275,13 +277,13 @@ int acm_domain_loadpolicy(int xc_handle,
    4.26          goto free_out;
    4.27      }
    4.28      if (len == read(fd, buffer, len)) {
    4.29 -        struct acm_op op;
    4.30 +        struct acm_setpolicy setpolicy;
    4.31          /* dump it and then push it down into xen/acm */
    4.32          acm_dump_policy_buffer(buffer, len);
    4.33 -        op.cmd = ACM_SETPOLICY;
    4.34 -        op.u.setpolicy.pushcache = (void *) buffer;
    4.35 -        op.u.setpolicy.pushcache_size = len;
    4.36 -        ret = xc_acm_op(xc_handle, &op);
    4.37 +        setpolicy.interface_version = ACM_INTERFACE_VERSION;
    4.38 +        setpolicy.pushcache = (void *) buffer;
    4.39 +        setpolicy.pushcache_size = len;
    4.40 +        ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, sizeof(setpolicy));
    4.41  
    4.42          if (ret)
    4.43              printf
    4.44 @@ -322,15 +324,15 @@ void dump_ste_stats(struct acm_ste_stats
    4.45  int acm_domain_dumpstats(int xc_handle)
    4.46  {
    4.47      uint8_t stats_buffer[PULL_STATS_SIZE];
    4.48 -    struct acm_op op;
    4.49 +    struct acm_dumpstats dumpstats;
    4.50      int ret;
    4.51      struct acm_stats_buffer *stats;
    4.52  
    4.53      memset(stats_buffer, 0x00, sizeof(stats_buffer));
    4.54 -    op.cmd = ACM_DUMPSTATS;
    4.55 -    op.u.dumpstats.pullcache = (void *) stats_buffer;
    4.56 -    op.u.dumpstats.pullcache_size = sizeof(stats_buffer);
    4.57 -    ret = xc_acm_op(xc_handle, &op);
    4.58 +    dumpstats.interface_version = ACM_INTERFACE_VERSION;
    4.59 +    dumpstats.pullcache = (void *) stats_buffer;
    4.60 +    dumpstats.pullcache_size = sizeof(stats_buffer);
    4.61 +    ret = xc_acm_op(xc_handle, ACMOP_dumpstats, &dumpstats, sizeof(dumpstats));
    4.62  
    4.63      if (ret < 0) {
    4.64          printf
     5.1 --- a/xen/common/acm_ops.c	Sun May 21 18:57:42 2006 +0100
     5.2 +++ b/xen/common/acm_ops.c	Sun May 21 19:05:31 2006 +0100
     5.3 @@ -32,100 +32,94 @@
     5.4  
     5.5  #ifndef ACM_SECURITY
     5.6  
     5.7 -long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
     5.8 +
     5.9 +long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
    5.10  {
    5.11      return -ENOSYS;
    5.12  }
    5.13  
    5.14 +
    5.15  #else
    5.16  
    5.17 -enum acm_operation {
    5.18 -    POLICY,                     /* access to policy interface (early drop) */
    5.19 -    GETPOLICY,                  /* dump policy cache */
    5.20 -    SETPOLICY,                  /* set policy cache (controls security) */
    5.21 -    DUMPSTATS,                  /* dump policy statistics */
    5.22 -    GETSSID,                    /* retrieve ssidref for domain id (decide inside authorized domains) */
    5.23 -    GETDECISION                 /* retrieve ACM decision from authorized domains */
    5.24 -};
    5.25  
    5.26 -int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops)
    5.27 +int acm_authorize_acm_ops(struct domain *d)
    5.28  {
    5.29      /* currently, policy management functions are restricted to privileged domains */
    5.30      if (!IS_PRIV(d))
    5.31          return -EPERM;
    5.32 -
    5.33      return 0;
    5.34  }
    5.35  
    5.36 -long do_acm_op(XEN_GUEST_HANDLE(acm_op_t) u_acm_op)
    5.37 +
    5.38 +long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
    5.39  {
    5.40 -    long ret = 0;
    5.41 -    struct acm_op curop, *op = &curop;
    5.42 +    long rc = -EFAULT;
    5.43  
    5.44 -    if (acm_authorize_acm_ops(current->domain, POLICY))
    5.45 +    if (acm_authorize_acm_ops(current->domain))
    5.46          return -EPERM;
    5.47  
    5.48 -    if (copy_from_guest(op, u_acm_op, 1))
    5.49 -        return -EFAULT;
    5.50 -
    5.51 -    if (op->interface_version != ACM_INTERFACE_VERSION)
    5.52 -        return -EACCES;
    5.53 -
    5.54 -    switch (op->cmd)
    5.55 -    {
    5.56 -    case ACM_SETPOLICY:
    5.57 -    {
    5.58 -        ret = acm_authorize_acm_ops(current->domain, SETPOLICY);
    5.59 -        if (!ret)
    5.60 -            ret = acm_set_policy(op->u.setpolicy.pushcache,
    5.61 -                                 op->u.setpolicy.pushcache_size, 1);
    5.62 -    }
    5.63 -    break;
    5.64 -
    5.65 -    case ACM_GETPOLICY:
    5.66 +    switch ( cmd )
    5.67      {
    5.68 -        ret = acm_authorize_acm_ops(current->domain, GETPOLICY);
    5.69 -        if (!ret)
    5.70 -            ret = acm_get_policy(op->u.getpolicy.pullcache,
    5.71 -                                 op->u.getpolicy.pullcache_size);
    5.72 -        if (!ret)
    5.73 -            copy_to_guest(u_acm_op, op, 1);
    5.74 -    }
    5.75 -    break;
    5.76  
    5.77 -    case ACM_DUMPSTATS:
    5.78 -    {
    5.79 -        ret = acm_authorize_acm_ops(current->domain, DUMPSTATS);
    5.80 -        if (!ret)
    5.81 -            ret = acm_dump_statistics(op->u.dumpstats.pullcache,
    5.82 -                                      op->u.dumpstats.pullcache_size);
    5.83 -        if (!ret)
    5.84 -            copy_to_guest(u_acm_op, op, 1);
    5.85 +    case ACMOP_setpolicy: {
    5.86 +        struct acm_setpolicy setpolicy;
    5.87 +        if (copy_from_guest(&setpolicy, arg, 1) != 0)
    5.88 +            return -EFAULT;
    5.89 +        if (setpolicy.interface_version != ACM_INTERFACE_VERSION)
    5.90 +            return -EACCES;
    5.91 +
    5.92 +        rc = acm_set_policy(setpolicy.pushcache,
    5.93 +                            setpolicy.pushcache_size, 1);
    5.94 +        break;
    5.95      }
    5.96 -    break;
    5.97  
    5.98 -    case ACM_GETSSID:
    5.99 -    {
   5.100 +    case ACMOP_getpolicy: {
   5.101 +        struct acm_getpolicy getpolicy;
   5.102 +        if (copy_from_guest(&getpolicy, arg, 1) != 0)
   5.103 +            return -EFAULT;
   5.104 +        if (getpolicy.interface_version != ACM_INTERFACE_VERSION)
   5.105 +            return -EACCES;
   5.106 +
   5.107 +        rc = acm_get_policy(getpolicy.pullcache,
   5.108 +                            getpolicy.pullcache_size);
   5.109 +        break;
   5.110 +    }
   5.111 +
   5.112 +    case ACMOP_dumpstats: {
   5.113 +        struct acm_dumpstats dumpstats;
   5.114 +        if (copy_from_guest(&dumpstats, arg, 1) != 0)
   5.115 +            return -EFAULT;
   5.116 +        if (dumpstats.interface_version != ACM_INTERFACE_VERSION)
   5.117 +            return -EACCES;
   5.118 +
   5.119 +        rc = acm_dump_statistics(dumpstats.pullcache,
   5.120 +                                 dumpstats.pullcache_size);
   5.121 +        break;
   5.122 +    }
   5.123 +
   5.124 +    case ACMOP_getssid: {
   5.125 +        struct acm_getssid getssid;
   5.126          ssidref_t ssidref;
   5.127  
   5.128 -        ret = acm_authorize_acm_ops(current->domain, GETSSID);
   5.129 -        if (ret)
   5.130 -            break;
   5.131 +        if (copy_from_guest(&getssid, arg, 1) != 0)
   5.132 +            return -EFAULT;
   5.133 +        if (getssid.interface_version != ACM_INTERFACE_VERSION)
   5.134 +            return -EACCES;
   5.135  
   5.136 -        if (op->u.getssid.get_ssid_by == SSIDREF)
   5.137 -            ssidref = op->u.getssid.id.ssidref;
   5.138 -        else if (op->u.getssid.get_ssid_by == DOMAINID)
   5.139 +        if (getssid.get_ssid_by == SSIDREF)
   5.140 +            ssidref = getssid.id.ssidref;
   5.141 +        else if (getssid.get_ssid_by == DOMAINID)
   5.142          {
   5.143 -            struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid);
   5.144 +            struct domain *subj = find_domain_by_id(getssid.id.domainid);
   5.145              if (!subj)
   5.146              {
   5.147 -                ret = -ESRCH; /* domain not found */
   5.148 +                rc = -ESRCH; /* domain not found */
   5.149                  break;
   5.150              }
   5.151              if (subj->ssid == NULL)
   5.152              {
   5.153                  put_domain(subj);
   5.154 -                ret = -ESRCH;
   5.155 +                rc = -ESRCH;
   5.156                  break;
   5.157              }
   5.158              ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
   5.159 @@ -133,39 +127,36 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
   5.160          }
   5.161          else
   5.162          {
   5.163 -            ret = -ESRCH;
   5.164 +            rc = -ESRCH;
   5.165              break;
   5.166          }
   5.167 -        ret = acm_get_ssid(ssidref,
   5.168 -                           op->u.getssid.ssidbuf,
   5.169 -                           op->u.getssid.ssidbuf_size);
   5.170 -        if (!ret)
   5.171 -            copy_to_guest(u_acm_op, op, 1);
   5.172 +        rc = acm_get_ssid(ssidref, getssid.ssidbuf, getssid.ssidbuf_size);
   5.173 +        break;
   5.174      }
   5.175 -    break;
   5.176  
   5.177 -    case ACM_GETDECISION:
   5.178 -    {
   5.179 +    case ACMOP_getdecision: {
   5.180 +        struct acm_getdecision getdecision;
   5.181          ssidref_t ssidref1, ssidref2;
   5.182  
   5.183 -        ret = acm_authorize_acm_ops(current->domain, GETDECISION);
   5.184 -        if (ret)
   5.185 -            break;
   5.186 +        if (copy_from_guest(&getdecision, arg, 1) != 0)
   5.187 +            return -EFAULT;
   5.188 +        if (getdecision.interface_version != ACM_INTERFACE_VERSION)
   5.189 +            return -EACCES;
   5.190  
   5.191 -        if (op->u.getdecision.get_decision_by1 == SSIDREF)
   5.192 -            ssidref1 = op->u.getdecision.id1.ssidref;
   5.193 -        else if (op->u.getdecision.get_decision_by1 == DOMAINID)
   5.194 +        if (getdecision.get_decision_by1 == SSIDREF)
   5.195 +            ssidref1 = getdecision.id1.ssidref;
   5.196 +        else if (getdecision.get_decision_by1 == DOMAINID)
   5.197          {
   5.198 -            struct domain *subj = find_domain_by_id(op->u.getdecision.id1.domainid);
   5.199 +            struct domain *subj = find_domain_by_id(getdecision.id1.domainid);
   5.200              if (!subj)
   5.201              {
   5.202 -                ret = -ESRCH; /* domain not found */
   5.203 +                rc = -ESRCH; /* domain not found */
   5.204                  break;
   5.205              }
   5.206              if (subj->ssid == NULL)
   5.207              {
   5.208                  put_domain(subj);
   5.209 -                ret = -ESRCH;
   5.210 +                rc = -ESRCH;
   5.211                  break;
   5.212              }
   5.213              ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
   5.214 @@ -173,23 +164,23 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
   5.215          }
   5.216          else
   5.217          {
   5.218 -            ret = -ESRCH;
   5.219 +            rc = -ESRCH;
   5.220              break;
   5.221          }
   5.222 -        if (op->u.getdecision.get_decision_by2 == SSIDREF)
   5.223 -            ssidref2 = op->u.getdecision.id2.ssidref;
   5.224 -        else if (op->u.getdecision.get_decision_by2 == DOMAINID)
   5.225 +        if (getdecision.get_decision_by2 == SSIDREF)
   5.226 +            ssidref2 = getdecision.id2.ssidref;
   5.227 +        else if (getdecision.get_decision_by2 == DOMAINID)
   5.228          {
   5.229 -            struct domain *subj = find_domain_by_id(op->u.getdecision.id2.domainid);
   5.230 +            struct domain *subj = find_domain_by_id(getdecision.id2.domainid);
   5.231              if (!subj)
   5.232              {
   5.233 -                ret = -ESRCH; /* domain not found */
   5.234 +                rc = -ESRCH; /* domain not found */
   5.235                  break;;
   5.236              }
   5.237              if (subj->ssid == NULL)
   5.238              {
   5.239                  put_domain(subj);
   5.240 -                ret = -ESRCH;
   5.241 +                rc = -ESRCH;
   5.242                  break;
   5.243              }
   5.244              ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref;
   5.245 @@ -197,34 +188,35 @@ long do_acm_op(XEN_GUEST_HANDLE(acm_op_t
   5.246          }
   5.247          else
   5.248          {
   5.249 -            ret = -ESRCH;
   5.250 +            rc = -ESRCH;
   5.251              break;
   5.252          }
   5.253 -        ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
   5.254 +        rc = acm_get_decision(ssidref1, ssidref2, getdecision.hook);
   5.255  
   5.256 -        if (ret == ACM_ACCESS_PERMITTED)
   5.257 +        if (rc == ACM_ACCESS_PERMITTED)
   5.258          {
   5.259 -            op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
   5.260 -            ret = 0;
   5.261 +            getdecision.acm_decision = ACM_ACCESS_PERMITTED;
   5.262 +            rc = 0;
   5.263          }
   5.264 -        else if  (ret == ACM_ACCESS_DENIED)
   5.265 +        else if  (rc == ACM_ACCESS_DENIED)
   5.266          {
   5.267 -            op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
   5.268 -            ret = 0;
   5.269 +            getdecision.acm_decision = ACM_ACCESS_DENIED;
   5.270 +            rc = 0;
   5.271          }
   5.272          else
   5.273 -            ret = -ESRCH;
   5.274 +            rc = -ESRCH;
   5.275  
   5.276 -        if (!ret)
   5.277 -            copy_to_guest(u_acm_op, op, 1);
   5.278 +        if ( (rc == 0) && (copy_to_guest(arg, &getdecision, 1) != 0) )
   5.279 +            rc = -EFAULT;
   5.280 +        break;
   5.281      }
   5.282 -    break;
   5.283  
   5.284      default:
   5.285 -        ret = -ESRCH;
   5.286 +        rc = -ENOSYS;
   5.287 +        break;
   5.288      }
   5.289  
   5.290 -    return ret;
   5.291 +    return rc;
   5.292  }
   5.293  
   5.294  #endif
     6.1 --- a/xen/include/public/acm_ops.h	Sun May 21 18:57:42 2006 +0100
     6.2 +++ b/xen/include/public/acm_ops.h	Sun May 21 19:05:31 2006 +0100
     6.3 @@ -2,7 +2,7 @@
     6.4   * acm_ops.h: Xen access control module hypervisor commands
     6.5   *
     6.6   * Reiner Sailer <sailer@watson.ibm.com>
     6.7 - * Copyright (c) 2005, International Business Machines Corporation.
     6.8 + * Copyright (c) 2005,2006 International Business Machines Corporation.
     6.9   */
    6.10  
    6.11  #ifndef __XEN_PUBLIC_ACM_OPS_H__
    6.12 @@ -17,36 +17,50 @@
    6.13   * This makes sure that old versions of acm tools will stop working in a
    6.14   * well-defined way (rather than crashing the machine, for instance).
    6.15   */
    6.16 -#define ACM_INTERFACE_VERSION   0xAAAA0006
    6.17 +#define ACM_INTERFACE_VERSION   0xAAAA0007
    6.18  
    6.19  /************************************************************************/
    6.20  
    6.21 -#define ACM_SETPOLICY         4
    6.22 +/*
    6.23 + * Prototype for this hypercall is:
    6.24 + *  int acm_op(int cmd, void *args)
    6.25 + * @cmd  == ACMOP_??? (access control module operation).
    6.26 + * @args == Operation-specific extra arguments (NULL if none).
    6.27 + */
    6.28 +
    6.29 +
    6.30 +#define ACMOP_setpolicy         1
    6.31  struct acm_setpolicy {
    6.32 -    /* OUT variables */
    6.33 +    /* IN */
    6.34 +    uint32_t interface_version;
    6.35      void *pushcache;
    6.36      uint32_t pushcache_size;
    6.37  };
    6.38  
    6.39  
    6.40 -#define ACM_GETPOLICY         5
    6.41 +#define ACMOP_getpolicy         2
    6.42  struct acm_getpolicy {
    6.43 -    /* OUT variables */
    6.44 +    /* IN */
    6.45 +    uint32_t interface_version;
    6.46      void *pullcache;
    6.47      uint32_t pullcache_size;
    6.48  };
    6.49  
    6.50  
    6.51 -#define ACM_DUMPSTATS         6
    6.52 +#define ACMOP_dumpstats         3
    6.53  struct acm_dumpstats {
    6.54 +    /* IN */
    6.55 +    uint32_t interface_version;
    6.56      void *pullcache;
    6.57      uint32_t pullcache_size;
    6.58  };
    6.59  
    6.60  
    6.61 -#define ACM_GETSSID           7
    6.62 +#define ACMOP_getssid           4
    6.63  enum get_type {UNSET=0, SSIDREF, DOMAINID};
    6.64  struct acm_getssid {
    6.65 +    /* IN */
    6.66 +    uint32_t interface_version;
    6.67      enum get_type get_ssid_by;
    6.68      union {
    6.69          domaintype_t domainid;
    6.70 @@ -56,9 +70,11 @@ struct acm_getssid {
    6.71      uint32_t ssidbuf_size;
    6.72  };
    6.73  
    6.74 -#define ACM_GETDECISION        8
    6.75 +#define ACMOP_getdecision      5
    6.76  struct acm_getdecision {
    6.77 -    enum get_type get_decision_by1; /* in */
    6.78 +    /* IN */
    6.79 +    uint32_t interface_version;
    6.80 +    enum get_type get_decision_by1;
    6.81      enum get_type get_decision_by2;
    6.82      union {
    6.83          domaintype_t domainid;
    6.84 @@ -69,24 +85,11 @@ struct acm_getdecision {
    6.85          ssidref_t    ssidref;
    6.86      } id2;
    6.87      enum acm_hook_type hook;
    6.88 -    int acm_decision;           /* out */
    6.89 +    /* OUT */
    6.90 +    int acm_decision;
    6.91  };
    6.92  
    6.93 -struct acm_op {
    6.94 -    uint32_t cmd;
    6.95 -    uint32_t interface_version;      /* ACM_INTERFACE_VERSION */
    6.96 -    union {
    6.97 -        struct acm_setpolicy setpolicy;
    6.98 -        struct acm_getpolicy getpolicy;
    6.99 -        struct acm_dumpstats dumpstats;
   6.100 -        struct acm_getssid getssid;
   6.101 -        struct acm_getdecision getdecision;
   6.102 -    } u;
   6.103 -};
   6.104 -typedef struct acm_op acm_op_t;
   6.105 -DEFINE_XEN_GUEST_HANDLE(acm_op_t);
   6.106 -
   6.107 -#endif                          /* __XEN_PUBLIC_ACM_OPS_H__ */
   6.108 +#endif /* __XEN_PUBLIC_ACM_OPS_H__ */
   6.109  
   6.110  /*
   6.111   * Local variables:
     7.1 --- a/xen/include/xen/hypercall.h	Sun May 21 18:57:42 2006 +0100
     7.2 +++ b/xen/include/xen/hypercall.h	Sun May 21 19:05:31 2006 +0100
     7.3 @@ -80,7 +80,7 @@ do_vcpu_op(
     7.4  
     7.5  extern long
     7.6  do_acm_op(
     7.7 -    XEN_GUEST_HANDLE(acm_op_t) u_acm_op);
     7.8 +    int cmd, XEN_GUEST_HANDLE(void) arg);
     7.9  
    7.10  extern long
    7.11  do_nmi_op(