This time the patch is attached.

This patch provides the implementation of the shim layer for ACM
hypercalls on PPC.

Signed-off-by: Stefan Berger <[EMAIL PROTECTED]>

diff -r 04f6ad5d9232 arch/powerpc/platforms/xen/hcall.c
--- a/arch/powerpc/platforms/xen/hcall.c	Mon Mar 05 13:23:38 2007 -0600
+++ b/arch/powerpc/platforms/xen/hcall.c	Fri Apr 27 21:50:12 2007 -0500
@@ -34,6 +34,7 @@
 #include <xen/interface/event_channel.h>
 #include <xen/interface/physdev.h>
 #include <xen/interface/vcpu.h>
+#include <xen/interface/acm_ops.h>
 #include <xen/public/privcmd.h>
 #include <asm/hypercall.h>
 #include <asm/page.h>
@@ -637,6 +638,146 @@ static int xenppc_privcmd_event_channel_
 	xencomm_free(desc);
 	return ret;
 }
+
+static int xenppc_acmcmd_op(privcmd_hypercall_t *hypercall)
+{
+	xen_acmctl_t kern_op;
+	xen_acmctl_t __user *user_op = (xen_acmctl_t __user *)hypercall->arg[0];
+	void *op_desc;
+	void *desc = NULL, *desc2 = NULL, *desc3 = NULL, *desc4 = NULL;
+	int ret = 0;
+
+	if (copy_from_user(&kern_op, user_op, sizeof(xen_acmctl_t)))
+		return -EFAULT;
+
+	if (kern_op.interface_version != ACM_INTERFACE_VERSION) {
+		printk(KERN_WARNING "%s: %s %x != %x\n", __func__, current->comm,
+				kern_op.interface_version, ACM_INTERFACE_VERSION);
+		return -EACCES;
+	}
+
+	op_desc = xencomm_map(&kern_op, sizeof(xen_acmctl_t));
+	if (op_desc == NULL)
+		return -ENOMEM;
+
+	switch (kern_op.cmd) {
+	case ACMOP_setpolicy:
+		desc = xencomm_map(
+			xen_guest_handle(kern_op.u.setpolicy.pushcache),
+			kern_op.u.setpolicy.pushcache_size);
+
+		if (desc == NULL)
+			ret = -ENOMEM;
+
+		set_xen_guest_handle(kern_op.u.setpolicy.pushcache,
+				     desc);
+		break;
+	case ACMOP_getpolicy:
+		desc = xencomm_map(
+			xen_guest_handle(kern_op.u.getpolicy.pullcache),
+			kern_op.u.getpolicy.pullcache_size);
+
+		if (desc == NULL)
+			ret = -ENOMEM;
+
+		set_xen_guest_handle(kern_op.u.getpolicy.pullcache,
+				     desc);
+		break;
+	case ACMOP_dumpstats:
+		desc = xencomm_map(
+			xen_guest_handle(kern_op.u.dumpstats.pullcache),
+			kern_op.u.dumpstats.pullcache_size);
+
+		if (desc == NULL)
+			ret = -ENOMEM;
+
+		set_xen_guest_handle(kern_op.u.dumpstats.pullcache,
+		                     desc);
+		break;
+	case ACMOP_getssid:
+		desc = xencomm_map(
+			xen_guest_handle(kern_op.u.getssid.ssidbuf),
+			kern_op.u.getssid.ssidbuf_size);
+
+		if (desc == NULL)
+			ret = -ENOMEM;
+
+		set_xen_guest_handle(kern_op.u.getssid.ssidbuf,
+		                     desc);
+		break;
+	case ACMOP_getdecision:
+		break;
+	case ACMOP_chgpolicy:
+		desc = xencomm_map(
+			xen_guest_handle(kern_op.u.change_policy.policy_pushcache),
+			kern_op.u.change_policy.policy_pushcache_size);
+		desc2 = xencomm_map(
+		 	 xen_guest_handle(kern_op.u.change_policy.del_array),
+		 	 kern_op.u.change_policy.delarray_size);
+		desc3 = xencomm_map(
+		 	 xen_guest_handle(kern_op.u.change_policy.chg_array),
+		 	 kern_op.u.change_policy.chgarray_size);
+		desc4 = xencomm_map(
+		 	 xen_guest_handle(kern_op.u.change_policy.err_array),
+		 	 kern_op.u.change_policy.errarray_size);
+
+		if (desc  == NULL || desc2 == NULL ||
+		    desc3 == NULL || desc4 == NULL) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		set_xen_guest_handle(kern_op.u.change_policy.policy_pushcache,
+		                     desc);
+		set_xen_guest_handle(kern_op.u.change_policy.del_array,
+		                     desc2);
+		set_xen_guest_handle(kern_op.u.change_policy.chg_array,
+		                     desc3);
+		set_xen_guest_handle(kern_op.u.change_policy.err_array,
+		                     desc4);
+		break;
+	case ACMOP_relabeldoms:
+		desc = xencomm_map(
+			xen_guest_handle(kern_op.u.relabel_doms.relabel_map),
+			kern_op.u.relabel_doms.relabel_map_size);
+		desc2 = xencomm_map(
+			xen_guest_handle(kern_op.u.relabel_doms.err_array),
+			kern_op.u.relabel_doms.errarray_size);
+
+		if (desc  == NULL || desc2 == NULL) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		set_xen_guest_handle(kern_op.u.relabel_doms.relabel_map,
+		                     desc);
+		set_xen_guest_handle(kern_op.u.relabel_doms.err_array,
+		                     desc2);
+		break;
+	default:
+		printk(KERN_ERR "%s: unknown/unsupported acmctl cmd %d\n",
+		       __func__, kern_op.cmd);
+		return -ENOSYS;
+	}
+
+	if (ret)
+		goto out; /* error mapping the nested pointer */
+
+	ret = plpar_hcall_norets(XEN_MARK(hypercall->op),op_desc);
+
+	if (copy_to_user(user_op, &kern_op, sizeof(xen_acmctl_t))) {
+		ret = -EFAULT;
+	}
+
+out:
+	xencomm_free(desc);
+	xencomm_free(desc2);
+	xencomm_free(desc3);
+	xencomm_free(desc4);
+	xencomm_free(op_desc);
+	return ret;
+}
+
 
 /* The PowerPC hypervisor runs in a separate address space from Linux
  * kernel/userspace, i.e. real mode. We must therefore translate userspace
@@ -661,12 +802,7 @@ int arch_privcmd_hypercall(privcmd_hyper
 		/* fallthru */
 		/* below are the hcalls we know will fail and its ok */
 	case __HYPERVISOR_acm_op:
-		return plpar_hcall_norets(XEN_MARK(hypercall->op),
-				hypercall->arg[0],
-				hypercall->arg[1],
-				hypercall->arg[2],
-				hypercall->arg[3],
-				hypercall->arg[4]);
+	        return xenppc_acmcmd_op(hypercall);
 	}
 }
 
diff -r 04f6ad5d9232 include/xen/interface/acm_ops.h
--- a/include/xen/interface/acm_ops.h	Mon Mar 05 13:23:38 2007 -0600
+++ b/include/xen/interface/acm_ops.h	Thu Apr 26 17:39:00 2007 -0500
@@ -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   0xAAAA0008
+#define ACM_INTERFACE_VERSION   0xAAAA000A
 
 /************************************************************************/
 
@@ -49,8 +49,7 @@
 #define ACMOP_setpolicy         1
 struct acm_setpolicy {
     /* IN */
-    uint32_t interface_version;
-    XEN_GUEST_HANDLE(void) pushcache;
+    XEN_GUEST_HANDLE_64(void) pushcache;
     uint32_t pushcache_size;
 };
 
@@ -58,8 +57,7 @@ struct acm_setpolicy {
 #define ACMOP_getpolicy         2
 struct acm_getpolicy {
     /* IN */
-    uint32_t interface_version;
-    XEN_GUEST_HANDLE(void) pullcache;
+    XEN_GUEST_HANDLE_64(void) pullcache;
     uint32_t pullcache_size;
 };
 
@@ -67,8 +65,7 @@ struct acm_getpolicy {
 #define ACMOP_dumpstats         3
 struct acm_dumpstats {
     /* IN */
-    uint32_t interface_version;
-    XEN_GUEST_HANDLE(void) pullcache;
+    XEN_GUEST_HANDLE_64(void) pullcache;
     uint32_t pullcache_size;
 };
 
@@ -78,20 +75,18 @@ 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;
         ssidref_t    ssidref;
     } id;
-    XEN_GUEST_HANDLE(void) ssidbuf;
+    XEN_GUEST_HANDLE_64(void) ssidbuf;
     uint32_t ssidbuf_size;
 };
 
 #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 {
@@ -107,6 +102,50 @@ struct acm_getdecision {
     uint32_t acm_decision;
 };
 
+
+#define ACMOP_chgpolicy        6
+struct acm_change_policy {
+    /* IN */
+    XEN_GUEST_HANDLE_64(void) policy_pushcache;
+    uint32_t policy_pushcache_size;
+    XEN_GUEST_HANDLE_64(void) del_array;
+    uint32_t delarray_size;
+    XEN_GUEST_HANDLE_64(void) chg_array;
+    uint32_t chgarray_size;
+    /* OUT */
+    /* array with error code */
+    XEN_GUEST_HANDLE_64(void) err_array;
+    uint32_t errarray_size;
+};
+
+#define ACMOP_relabeldoms       7
+struct acm_relabel_doms {
+    /* IN */
+    XEN_GUEST_HANDLE_64(void) relabel_map;
+    uint32_t relabel_map_size;
+    /* OUT */
+    XEN_GUEST_HANDLE_64(void) err_array;
+    uint32_t errarray_size;
+};
+
+/* future interface to Xen */
+struct xen_acmctl {
+    uint32_t cmd;
+    uint32_t interface_version;
+    union {
+        struct acm_setpolicy     setpolicy;
+        struct acm_getpolicy     getpolicy;
+        struct acm_dumpstats     dumpstats;
+        struct acm_getssid       getssid;
+        struct acm_getdecision   getdecision;
+        struct acm_change_policy change_policy;
+        struct acm_relabel_doms  relabel_doms;
+    } u;
+};
+
+typedef struct xen_acmctl xen_acmctl_t;
+DEFINE_XEN_GUEST_HANDLE(xen_acmctl_t);
+
 #endif /* __XEN_PUBLIC_ACM_OPS_H__ */
 
 /*
_______________________________________________
Xen-ppc-devel mailing list
Xen-ppc-devel@lists.xensource.com
http://lists.xensource.com/xen-ppc-devel

Reply via email to