WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] [xen-unstable] [ACM] Simpler interface to hypercalls

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] [ACM] Simpler interface to hypercalls
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 04 Jun 2007 03:15:21 -0700
Delivery-date: Mon, 04 Jun 2007 03:15:31 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kfraser@xxxxxxxxxxxxxxxxxxxxx
# Date 1179998335 -3600
# Node ID 96915ca8d5f239062f889970279c5d90296a8a96
# Parent  46095d5a59a9d268c247b2b1bf747024759b1f8e
[ACM] Simpler interface to hypercalls

Implement a simpler interface for the hypercalls to ACM. I put the
parameters to all hypercalls into a union. On top of this I have
implemented a shim layer for enabling ACM hypercalls on PPC.

Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
---
 tools/libxc/xc_acm.c                |   94 +++++++++++++++++++++++---
 tools/python/xen/lowlevel/acm/acm.c |    2 
 tools/security/secpol_tool.c        |    4 -
 xen/common/acm_ops.c                |  128 ++++++++++++------------------------
 xen/include/public/acm_ops.h        |    9 --
 xen/include/xen/hypercall.h         |    2 
 6 files changed, 130 insertions(+), 109 deletions(-)

diff -r 46095d5a59a9 -r 96915ca8d5f2 tools/libxc/xc_acm.c
--- a/tools/libxc/xc_acm.c      Thu May 24 10:14:05 2007 +0100
+++ b/tools/libxc/xc_acm.c      Thu May 24 10:18:55 2007 +0100
@@ -16,20 +16,96 @@
 
 int xc_acm_op(int xc_handle, int cmd, void *arg, unsigned long arg_size)
 {
-    int ret = -1;
+    int ret;
     DECLARE_HYPERCALL;
+    struct xen_acmctl acmctl;
+
+    switch (cmd) {
+        case ACMOP_setpolicy: {
+            struct acm_setpolicy *setpolicy = (struct acm_setpolicy *)arg;
+            memcpy(&acmctl.u.setpolicy,
+                   setpolicy,
+                   sizeof(struct acm_setpolicy));
+        }
+        break;
+
+        case ACMOP_getpolicy: {
+            struct acm_getpolicy *getpolicy = (struct acm_getpolicy *)arg;
+            memcpy(&acmctl.u.getpolicy,
+                   getpolicy,
+                   sizeof(struct acm_getpolicy));
+        }
+        break;
+
+        case ACMOP_dumpstats: {
+            struct acm_dumpstats *dumpstats = (struct acm_dumpstats *)arg;
+            memcpy(&acmctl.u.dumpstats,
+                   dumpstats,
+                   sizeof(struct acm_dumpstats));
+        }
+        break;
+
+        case ACMOP_getssid: {
+            struct acm_getssid *getssid = (struct acm_getssid *)arg;
+            memcpy(&acmctl.u.getssid,
+                   getssid,
+                   sizeof(struct acm_getssid));
+        }
+        break;
+
+        case ACMOP_getdecision: {
+            struct acm_getdecision *getdecision = (struct acm_getdecision 
*)arg;
+            memcpy(&acmctl.u.getdecision,
+                   getdecision,
+                   sizeof(struct acm_getdecision));
+        }
+        break;
+
+        case ACMOP_chgpolicy: {
+            struct acm_change_policy *change_policy = (struct 
acm_change_policy *)arg;
+            memcpy(&acmctl.u.change_policy,
+                   change_policy,
+                   sizeof(struct acm_change_policy));
+        }
+        break;
+
+        case ACMOP_relabeldoms: {
+            struct acm_relabel_doms *relabel_doms = (struct acm_relabel_doms 
*)arg;
+            memcpy(&acmctl.u.relabel_doms,
+                   relabel_doms,
+                   sizeof(struct acm_relabel_doms));
+        }
+        break;
+    }
+
+    acmctl.cmd = cmd;
+    acmctl.interface_version = ACM_INTERFACE_VERSION;
 
     hypercall.op = __HYPERVISOR_acm_op;
-    hypercall.arg[0] = cmd;
-    hypercall.arg[1] = (unsigned long) arg;
+    hypercall.arg[0] = (unsigned long)&acmctl;
+    if ( lock_pages(&acmctl, sizeof(acmctl)) != 0)
+    {
+        PERROR("Could not lock memory for Xen hypercall");
+        return -EFAULT;
+    }
+    if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0)
+    {
+        if ( errno == EACCES )
+            DPRINTF("acmctl operation failed -- need to"
+                    " rebuild the user-space tool set?\n");
+    }
+    unlock_pages(&acmctl, sizeof(acmctl));
 
-    if (lock_pages(arg, arg_size) != 0) {
-        PERROR("xc_acm_op: arg lock failed");
-        goto out;
+    switch (cmd) {
+        case ACMOP_getdecision: {
+            struct acm_getdecision *getdecision = (struct acm_getdecision 
*)arg;
+            memcpy(getdecision,
+                   &acmctl.u.getdecision,
+                   sizeof(struct acm_getdecision));
+            break;
+        }
     }
-    ret = do_xen_hypercall(xc_handle, &hypercall);
-    unlock_pages(arg, arg_size);
- out:
+
     return ret;
 }
 
diff -r 46095d5a59a9 -r 96915ca8d5f2 tools/python/xen/lowlevel/acm/acm.c
--- a/tools/python/xen/lowlevel/acm/acm.c       Thu May 24 10:14:05 2007 +0100
+++ b/tools/python/xen/lowlevel/acm/acm.c       Thu May 24 10:18:55 2007 +0100
@@ -53,7 +53,6 @@ void * __getssid(int domid, uint32_t *bu
         goto out2;
     }
     memset(buf, 0, SSID_BUFFER_SIZE);
-    getssid.interface_version = ACM_INTERFACE_VERSION;
     set_xen_guest_handle(getssid.ssidbuf, buf);
     getssid.ssidbuf_size = SSID_BUFFER_SIZE;
     getssid.get_ssid_by = ACM_GETBY_domainid;
@@ -163,7 +162,6 @@ static PyObject *getdecision(PyObject * 
     (strcmp(arg2_name, "domid") && strcmp(arg2_name, "ssidref")))
         return NULL;
 
-    getdecision.interface_version = ACM_INTERFACE_VERSION;
     getdecision.hook = ACMHOOK_sharing;
     if (!strcmp(arg1_name, "domid")) {
         getdecision.get_decision_by1 = ACM_GETBY_domainid;
diff -r 46095d5a59a9 -r 96915ca8d5f2 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c      Thu May 24 10:14:05 2007 +0100
+++ b/tools/security/secpol_tool.c      Thu May 24 10:18:55 2007 +0100
@@ -243,7 +243,6 @@ int acm_get_ssidref(int xc_handle, int d
     struct acm_getssid getssid;
     char buf[4096];
     struct acm_ssid_buffer *ssid = (struct acm_ssid_buffer *)buf;
-    getssid.interface_version = ACM_INTERFACE_VERSION;
     set_xen_guest_handle(getssid.ssidbuf, buf);
     getssid.ssidbuf_size = sizeof(buf);
     getssid.get_ssid_by = ACM_GETBY_domainid;
@@ -268,7 +267,6 @@ int acm_domain_getpolicy(int xc_handle)
     uint16_t chwall_ref, ste_ref;
 
     memset(pull_buffer, 0x00, sizeof(pull_buffer));
-    getpolicy.interface_version = ACM_INTERFACE_VERSION;
     set_xen_guest_handle(getpolicy.pullcache, pull_buffer);
     getpolicy.pullcache_size = sizeof(pull_buffer);
     ret = xc_acm_op(xc_handle, ACMOP_getpolicy, &getpolicy, sizeof(getpolicy));
@@ -323,7 +321,6 @@ int acm_domain_loadpolicy(int xc_handle,
         struct acm_setpolicy setpolicy;
         /* dump it and then push it down into xen/acm */
         acm_dump_policy_buffer(buffer, len, chwall_ssidref, ste_ssidref);
-        setpolicy.interface_version = ACM_INTERFACE_VERSION;
         set_xen_guest_handle(setpolicy.pushcache, buffer);
         setpolicy.pushcache_size = len;
         ret = xc_acm_op(xc_handle, ACMOP_setpolicy, &setpolicy, 
sizeof(setpolicy));
@@ -372,7 +369,6 @@ int acm_domain_dumpstats(int xc_handle)
     struct acm_stats_buffer *stats;
 
     memset(stats_buffer, 0x00, sizeof(stats_buffer));
-    dumpstats.interface_version = ACM_INTERFACE_VERSION;
     set_xen_guest_handle(dumpstats.pullcache, stats_buffer);
     dumpstats.pullcache_size = sizeof(stats_buffer);
     ret = xc_acm_op(xc_handle, ACMOP_dumpstats, &dumpstats, sizeof(dumpstats));
diff -r 46095d5a59a9 -r 96915ca8d5f2 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c      Thu May 24 10:14:05 2007 +0100
+++ b/xen/common/acm_ops.c      Thu May 24 10:18:55 2007 +0100
@@ -38,69 +38,54 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
 
 int acm_authorize_acm_ops(struct domain *d)
 {
+    /* currently, policy management functions are restricted to privileged 
domains */
     return (IS_PRIV(d) ? 0 : -EPERM);
 }
 
-long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg)
+
+long do_acm_op(XEN_GUEST_HANDLE(xen_acmctl_t) u_acmctl)
 {
     long rc = -EFAULT;
-
-    if ( acm_authorize_acm_ops(current->domain) )
+    struct xen_acmctl curop, *op = &curop;
+
+    if (acm_authorize_acm_ops(current->domain))
         return -EPERM;
 
-    switch ( cmd )
+    if ( copy_from_guest(op, u_acmctl, 1) )
+        return -EFAULT;
+
+    if (op->interface_version != ACM_INTERFACE_VERSION)
+        return -EACCES;
+
+    switch ( op->cmd )
     {
 
     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;
-
-        rc = acm_set_policy(setpolicy.pushcache,
-                            setpolicy.pushcache_size);
+        rc = acm_set_policy(op->u.setpolicy.pushcache,
+                            op->u.setpolicy.pushcache_size);
         break;
     }
 
     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);
+        rc = acm_get_policy(op->u.getpolicy.pullcache,
+                            op->u.getpolicy.pullcache_size);
         break;
     }
 
     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);
+        rc = acm_dump_statistics(op->u.dumpstats.pullcache,
+                                 op->u.dumpstats.pullcache_size);
         break;
     }
 
     case ACMOP_getssid: {
-        struct acm_getssid getssid;
         ssidref_t ssidref;
 
-        if (copy_from_guest(&getssid, arg, 1) != 0)
-            return -EFAULT;
-        if (getssid.interface_version != ACM_INTERFACE_VERSION)
-            return -EACCES;
-
-        if (getssid.get_ssid_by == ACM_GETBY_ssidref)
-            ssidref = getssid.id.ssidref;
-        else if (getssid.get_ssid_by == ACM_GETBY_domainid)
-        {
-            struct domain *subj = rcu_lock_domain_by_id(getssid.id.domainid);
+        if (op->u.getssid.get_ssid_by == ACM_GETBY_ssidref)
+            ssidref = op->u.getssid.id.ssidref;
+        else if (op->u.getssid.get_ssid_by == ACM_GETBY_domainid)
+        {
+            struct domain *subj = 
rcu_lock_domain_by_id(op->u.getssid.id.domainid);
             if (!subj)
             {
                 rc = -ESRCH; /* domain not found */
@@ -120,24 +105,19 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
             rc = -ESRCH;
             break;
         }
-        rc = acm_get_ssid(ssidref, getssid.ssidbuf, getssid.ssidbuf_size);
+        rc = acm_get_ssid(ssidref, op->u.getssid.ssidbuf,
+                          op->u.getssid.ssidbuf_size);
         break;
     }
 
     case ACMOP_getdecision: {
-        struct acm_getdecision getdecision;
         ssidref_t ssidref1, ssidref2;
 
-        if (copy_from_guest(&getdecision, arg, 1) != 0)
-            return -EFAULT;
-        if (getdecision.interface_version != ACM_INTERFACE_VERSION)
-            return -EACCES;
-
-        if (getdecision.get_decision_by1 == ACM_GETBY_ssidref)
-            ssidref1 = getdecision.id1.ssidref;
-        else if (getdecision.get_decision_by1 == ACM_GETBY_domainid)
-        {
-            struct domain *subj = 
rcu_lock_domain_by_id(getdecision.id1.domainid);
+        if (op->u.getdecision.get_decision_by1 == ACM_GETBY_ssidref)
+            ssidref1 = op->u.getdecision.id1.ssidref;
+        else if (op->u.getdecision.get_decision_by1 == ACM_GETBY_domainid)
+        {
+            struct domain *subj = 
rcu_lock_domain_by_id(op->u.getdecision.id1.domainid);
             if (!subj)
             {
                 rc = -ESRCH; /* domain not found */
@@ -157,11 +137,11 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
             rc = -ESRCH;
             break;
         }
-        if (getdecision.get_decision_by2 == ACM_GETBY_ssidref)
-            ssidref2 = getdecision.id2.ssidref;
-        else if (getdecision.get_decision_by2 == ACM_GETBY_domainid)
-        {
-            struct domain *subj = 
rcu_lock_domain_by_id(getdecision.id2.domainid);
+        if (op->u.getdecision.get_decision_by2 == ACM_GETBY_ssidref)
+            ssidref2 = op->u.getdecision.id2.ssidref;
+        else if (op->u.getdecision.get_decision_by2 == ACM_GETBY_domainid)
+        {
+            struct domain *subj = 
rcu_lock_domain_by_id(op->u.getdecision.id2.domainid);
             if (!subj)
             {
                 rc = -ESRCH; /* domain not found */
@@ -181,55 +161,33 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
             rc = -ESRCH;
             break;
         }
-        rc = acm_get_decision(ssidref1, ssidref2, getdecision.hook);
+        rc = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook);
 
         if (rc == ACM_ACCESS_PERMITTED)
         {
-            getdecision.acm_decision = ACM_ACCESS_PERMITTED;
+            op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED;
             rc = 0;
         }
         else if  (rc == ACM_ACCESS_DENIED)
         {
-            getdecision.acm_decision = ACM_ACCESS_DENIED;
+            op->u.getdecision.acm_decision = ACM_ACCESS_DENIED;
             rc = 0;
         }
         else
             rc = -ESRCH;
 
-        if ( (rc == 0) && (copy_to_guest(arg, &getdecision, 1) != 0) )
+        if ( (rc == 0) && (copy_to_guest(u_acmctl, op, 1) != 0) )
             rc = -EFAULT;
         break;
     }
 
     case ACMOP_chgpolicy: {
-        struct acm_change_policy chgpolicy;
-
-        if (copy_from_guest(&chgpolicy, arg, 1) != 0)
-            return -EFAULT;
-        if (chgpolicy.interface_version != ACM_INTERFACE_VERSION)
-            return -EACCES;
-
-        rc = acm_change_policy(&chgpolicy);
-
-        if (rc == 0)
-            if (copy_to_guest(arg, &chgpolicy, 1) != 0)
-                rc = -EFAULT;
+        rc = acm_change_policy(&op->u.change_policy);
         break;
     }
 
     case ACMOP_relabeldoms: {
-        struct acm_relabel_doms relabeldoms;
-
-        if (copy_from_guest(&relabeldoms, arg, 1) != 0)
-            return -EFAULT;
-        if (relabeldoms.interface_version != ACM_INTERFACE_VERSION)
-            return -EACCES;
-
-        rc = acm_relabel_domains(&relabeldoms);
-
-        if (rc == 0)
-            if (copy_to_guest(arg, &relabeldoms, 1) != 0)
-                rc = -EFAULT;
+        rc = acm_relabel_domains(&op->u.relabel_doms);
         break;
     }
 
@@ -241,7 +199,7 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE
     return rc;
 }
 
-#endif /* defined(ACM_SECURITY) */
+#endif
 
 /*
  * Local variables:
diff -r 46095d5a59a9 -r 96915ca8d5f2 xen/include/public/acm_ops.h
--- a/xen/include/public/acm_ops.h      Thu May 24 10:14:05 2007 +0100
+++ b/xen/include/public/acm_ops.h      Thu May 24 10:18:55 2007 +0100
@@ -34,7 +34,7 @@
  * 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   0xAAAA0009
+#define ACM_INTERFACE_VERSION   0xAAAA000A
 
 /************************************************************************/
 
@@ -49,7 +49,6 @@
 #define ACMOP_setpolicy         1
 struct acm_setpolicy {
     /* IN */
-    uint32_t interface_version;
     XEN_GUEST_HANDLE_64(void) pushcache;
     uint32_t pushcache_size;
 };
@@ -58,7 +57,6 @@ struct acm_setpolicy {
 #define ACMOP_getpolicy         2
 struct acm_getpolicy {
     /* IN */
-    uint32_t interface_version;
     XEN_GUEST_HANDLE_64(void) pullcache;
     uint32_t pullcache_size;
 };
@@ -67,7 +65,6 @@ struct acm_getpolicy {
 #define ACMOP_dumpstats         3
 struct acm_dumpstats {
     /* IN */
-    uint32_t interface_version;
     XEN_GUEST_HANDLE_64(void) pullcache;
     uint32_t pullcache_size;
 };
@@ -78,7 +75,6 @@ struct acm_dumpstats {
 #define ACM_GETBY_domainid 2
 struct acm_getssid {
     /* IN */
-    uint32_t interface_version;
     uint32_t get_ssid_by; /* ACM_GETBY_* */
     union {
         domaintype_t domainid;
@@ -91,7 +87,6 @@ struct acm_getssid {
 #define ACMOP_getdecision      5
 struct acm_getdecision {
     /* IN */
-    uint32_t interface_version;
     uint32_t get_decision_by1; /* ACM_GETBY_* */
     uint32_t get_decision_by2; /* ACM_GETBY_* */
     union {
@@ -111,7 +106,6 @@ struct acm_getdecision {
 #define ACMOP_chgpolicy        6
 struct acm_change_policy {
     /* IN */
-    uint32_t interface_version;
     XEN_GUEST_HANDLE_64(void) policy_pushcache;
     uint32_t policy_pushcache_size;
     XEN_GUEST_HANDLE_64(void) del_array;
@@ -127,7 +121,6 @@ struct acm_change_policy {
 #define ACMOP_relabeldoms       7
 struct acm_relabel_doms {
     /* IN */
-    uint32_t interface_version;
     XEN_GUEST_HANDLE_64(void) relabel_map;
     uint32_t relabel_map_size;
     /* OUT */
diff -r 46095d5a59a9 -r 96915ca8d5f2 xen/include/xen/hypercall.h
--- a/xen/include/xen/hypercall.h       Thu May 24 10:14:05 2007 +0100
+++ b/xen/include/xen/hypercall.h       Thu May 24 10:18:55 2007 +0100
@@ -98,7 +98,7 @@ do_vcpu_op(
 
 extern long
 do_acm_op(
-    int cmd, XEN_GUEST_HANDLE(void) arg);
+    XEN_GUEST_HANDLE(xen_acmctl_t) arg);
 
 extern long
 do_nmi_op(

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] [ACM] Simpler interface to hypercalls, Xen patchbot-unstable <=