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-ppc-devel

[XenPPC] [ppc/linux-2.6.18-xen.hg] [XEN][LINUX][POWERPC] Implement xenco

Changeset 696817986e68 : 
http://xenbits.xensource.com/ext/ppc/linux-2.6.18-xen.hg?cmd=changeset;node=696817986e68

        [XEN][LINUX][POWERPC] Implement xencomm translation for ACM hypercalls.
        Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxx>
        Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx>

diffstat:

1 files changed, 143 insertions(+), 3 deletions(-)
arch/powerpc/platforms/xen/hcall.c |  146 +++++++++++++++++++++++++++++++++++-

diffs (172 lines):

diff -r 9debaf360905 -r 696817986e68 arch/powerpc/platforms/xen/hcall.c
--- a/arch/powerpc/platforms/xen/hcall.c        Fri Jul 13 16:15:37 2007 +0100
+++ b/arch/powerpc/platforms/xen/hcall.c        Fri Jul 13 14:01:30 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/interface/kexec.h>
 #include <xen/public/privcmd.h>
 #include <asm/hypercall.h>
@@ -680,6 +681,145 @@ static int xenppc_privcmd_event_channel_
        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
  * pointers to something the hypervisor can make sense of. */
@@ -698,11 +838,11 @@ int privcmd_hypercall(privcmd_hypercall_
                return xenppc_privcmd_version(hypercall);
        case __HYPERVISOR_event_channel_op:
                return xenppc_privcmd_event_channel_op(hypercall);
+       case __HYPERVISOR_acm_op:
+               return xenppc_acmcmd_op(hypercall);
        default:
                printk(KERN_ERR "%s: unknown hcall (%ld)\n", __func__, 
hypercall->op);
-               /* fallthru */
-               /* below are the hcalls we know will fail and its ok */
-       case __HYPERVISOR_acm_op:
+               /* maybe we'll get lucky and the hcall needs no translation. */
                return plpar_hcall_norets(XEN_MARK(hypercall->op),
                                hypercall->arg[0],
                                hypercall->arg[1],

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

<Prev in Thread] Current Thread [Next in Thread>
  • [XenPPC] [ppc/linux-2.6.18-xen.hg] [XEN][LINUX][POWERPC] Implement xencom..., patchbot <=