0001
0002
0003
0004
0005
0006
0007 #include <linux/compat.h>
0008 #include <linux/errno.h>
0009 #include <linux/kernel.h>
0010 #include <linux/ptrace.h>
0011 #include <linux/sched.h>
0012 #include <linux/sched/task.h>
0013 #include <linux/sched/task_stack.h>
0014 #include <linux/signal.h>
0015
0016 #include "kernel.h"
0017
0018 asmlinkage long sparc_fork(struct pt_regs *regs)
0019 {
0020 unsigned long orig_i1 = regs->u_regs[UREG_I1];
0021 long ret;
0022 struct kernel_clone_args args = {
0023 .exit_signal = SIGCHLD,
0024
0025 .stack = regs->u_regs[UREG_FP],
0026 };
0027
0028 ret = kernel_clone(&args);
0029
0030
0031
0032
0033
0034
0035 if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
0036 regs->u_regs[UREG_I1] = orig_i1;
0037
0038 return ret;
0039 }
0040
0041 asmlinkage long sparc_vfork(struct pt_regs *regs)
0042 {
0043 unsigned long orig_i1 = regs->u_regs[UREG_I1];
0044 long ret;
0045
0046 struct kernel_clone_args args = {
0047 .flags = CLONE_VFORK | CLONE_VM,
0048 .exit_signal = SIGCHLD,
0049
0050 .stack = regs->u_regs[UREG_FP],
0051 };
0052
0053 ret = kernel_clone(&args);
0054
0055
0056
0057
0058
0059
0060 if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
0061 regs->u_regs[UREG_I1] = orig_i1;
0062
0063 return ret;
0064 }
0065
0066 asmlinkage long sparc_clone(struct pt_regs *regs)
0067 {
0068 unsigned long orig_i1 = regs->u_regs[UREG_I1];
0069 unsigned int flags = lower_32_bits(regs->u_regs[UREG_I0]);
0070 long ret;
0071
0072 struct kernel_clone_args args = {
0073 .flags = (flags & ~CSIGNAL),
0074 .exit_signal = (flags & CSIGNAL),
0075 .tls = regs->u_regs[UREG_I3],
0076 };
0077
0078 #ifdef CONFIG_COMPAT
0079 if (test_thread_flag(TIF_32BIT)) {
0080 args.pidfd = compat_ptr(regs->u_regs[UREG_I2]);
0081 args.child_tid = compat_ptr(regs->u_regs[UREG_I4]);
0082 args.parent_tid = compat_ptr(regs->u_regs[UREG_I2]);
0083 } else
0084 #endif
0085 {
0086 args.pidfd = (int __user *)regs->u_regs[UREG_I2];
0087 args.child_tid = (int __user *)regs->u_regs[UREG_I4];
0088 args.parent_tid = (int __user *)regs->u_regs[UREG_I2];
0089 }
0090
0091
0092
0093
0094 if (regs->u_regs[UREG_I1])
0095 args.stack = regs->u_regs[UREG_I1];
0096 else
0097 args.stack = regs->u_regs[UREG_FP];
0098
0099 ret = kernel_clone(&args);
0100
0101
0102
0103
0104
0105
0106 if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
0107 regs->u_regs[UREG_I1] = orig_i1;
0108
0109 return ret;
0110 }