Signed-off-by: Nathan Lynch <[email protected]>
---
 clone_ppc.c  |   43 ++++++++++++++++++++++++++++++++
 clone_ppc_.S |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 120 insertions(+), 0 deletions(-)

diff --git a/clone_ppc.c b/clone_ppc.c
index 49797fd..c9eee8b 100644
--- a/clone_ppc.c
+++ b/clone_ppc.c
@@ -56,3 +56,46 @@ int clone_with_pids(int (*fn)(void *), void *child_stack, 
int flags,
 }
 
 #endif
+
+#include "eclone.h"
+
+extern int __eclone(int (*fn)(void *arg),
+                   void *child_sp,
+                   int flags,
+                   void *fn_arg,
+                   struct clone_args *args,
+                   size_t args_size,
+                   pid_t *pids);
+
+int eclone(int (*fn)(void *), void *fn_arg, int clone_flags_low,
+          struct clone_args *clone_args, pid_t *pids)
+{
+       struct clone_args my_args;
+       unsigned long child_sp;
+       int newpid;
+
+       if (clone_args->child_stack)
+               child_sp = clone_args->child_stack +
+                       clone_args->child_stack_size - 1;
+       else
+               child_sp = 0;
+
+       my_args = *clone_args;
+       my_args.child_stack = child_sp;
+       my_args.child_stack_size = 0;
+
+       newpid = __eclone(fn,
+                         (void *)child_sp,
+                         clone_flags_low,
+                         fn_arg,
+                         &my_args,
+                         sizeof(my_args),
+                         pids);
+
+       if (newpid < 0) {
+               errno = -newpid;
+               newpid = -1;
+       }
+
+       return newpid;
+}
diff --git a/clone_ppc_.S b/clone_ppc_.S
index cb3e053..fa89c31 100644
--- a/clone_ppc_.S
+++ b/clone_ppc_.S
@@ -88,3 +88,80 @@ parent:
        neg     r3,r3
        blr
 
+#ifndef __NR_eclone
+#define __NR_eclone     323
+#endif
+
+/* int [r3] eclone(int (*fn)(void *arg) [r3],
+ *                          void *child_sp [r4],
+ *                          int flags [r5],
+ *                          void *fn_arg [r6],
+ *                          struct clone_args *args [r7],
+ *                          size_t args_size [r8],
+ *                          pid_t *pids [r9]);
+ * Creates a child task with the pids specified by pids.
+ * Returns to parent only, child execution and exit is handled here.
+ * On error, returns negated errno.  On success, returns the pid of the child
+ * created.
+ */
+
+.globl __eclone
+__eclone:
+
+       /* No argument validation. */
+
+       /* Set up parent's stack frame. */
+       stwu    r1,-32(r1)
+
+       /* Save non-volatiles (r28-r31) which we plan to use. */
+       stmw    r28,16(r1)
+
+       /* Set up child's stack frame. */
+       clrrwi  r4,r4,4
+       li      r0,0
+       stw     r0,-16(r4)
+
+       /* Save fn, stack pointer, flags, and fn_arg across system call. */
+       mr      r28,r3
+       mr      r29,r4
+       mr      r30,r5
+       mr      r31,r6
+
+       /* Set up arguments for system call. */
+       mr      r3,r5   /* flags */
+       mr      r4,r7   /* clone_args */
+       mr      r5,r8   /* clone_args' size */
+       mr      r6,r9   /* pids */
+
+       /* Do the system call */
+       li      r0,__NR_eclone
+       sc
+
+       /* Parent or child? */
+       cmpwi   cr1,r3,0
+       crandc  4*cr1+eq,4*cr1+eq,4*cr0+so
+       bne     cr1,eclone_parent
+
+       /* Child. Call fn. */
+       mtctr   r28
+       mr      r3,r31
+       bctrl
+
+       /* Assume result of fn in r3 and exit. */
+       li      r0,__NR_exit
+       sc
+
+eclone_parent:
+       /* Restore non-volatiles. */
+       lmw     r28,16(r1)
+
+       addi    r1,r1,32
+
+       /* Return to caller on success. */
+       bnslr
+
+       /* Handle error.  Negate the return value to signal an error
+        * to the caller, which must set errno.
+        */
+       neg     r3,r3
+       blr
-- 
1.6.2.5

_______________________________________________
Containers mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/containers

_______________________________________________
Devel mailing list
[email protected]
https://openvz.org/mailman/listinfo/devel

Reply via email to