1 // SPDX-License-Identifier: GPL-2.0
4 * This file handles the architecture independent parts of process handling..
7 #include <linux/compat.h>
8 #include <linux/errno.h>
9 #include <linux/kernel.h>
10 #include <linux/ptrace.h>
11 #include <linux/sched.h>
12 #include <linux/sched/task.h>
13 #include <linux/sched/task_stack.h>
14 #include <linux/signal.h>
18 asmlinkage
long sparc_fork(struct pt_regs
*regs
)
20 unsigned long orig_i1
= regs
->u_regs
[UREG_I1
];
22 struct kernel_clone_args args
= {
23 .exit_signal
= SIGCHLD
,
24 /* Reuse the parent's stack for the child. */
25 .stack
= regs
->u_regs
[UREG_FP
],
28 ret
= kernel_clone(&args
);
30 /* If we get an error and potentially restart the system
31 * call, we're screwed because copy_thread() clobbered
32 * the parent's %o1. So detect that case and restore it
35 if ((unsigned long)ret
>= -ERESTART_RESTARTBLOCK
)
36 regs
->u_regs
[UREG_I1
] = orig_i1
;
41 asmlinkage
long sparc_vfork(struct pt_regs
*regs
)
43 unsigned long orig_i1
= regs
->u_regs
[UREG_I1
];
46 struct kernel_clone_args args
= {
47 .flags
= CLONE_VFORK
| CLONE_VM
,
48 .exit_signal
= SIGCHLD
,
49 /* Reuse the parent's stack for the child. */
50 .stack
= regs
->u_regs
[UREG_FP
],
53 ret
= kernel_clone(&args
);
55 /* If we get an error and potentially restart the system
56 * call, we're screwed because copy_thread() clobbered
57 * the parent's %o1. So detect that case and restore it
60 if ((unsigned long)ret
>= -ERESTART_RESTARTBLOCK
)
61 regs
->u_regs
[UREG_I1
] = orig_i1
;
66 asmlinkage
long sparc_clone(struct pt_regs
*regs
)
68 unsigned long orig_i1
= regs
->u_regs
[UREG_I1
];
69 unsigned int flags
= lower_32_bits(regs
->u_regs
[UREG_I0
]);
72 struct kernel_clone_args args
= {
73 .flags
= (flags
& ~CSIGNAL
),
74 .exit_signal
= (flags
& CSIGNAL
),
75 .tls
= regs
->u_regs
[UREG_I3
],
79 if (test_thread_flag(TIF_32BIT
)) {
80 args
.pidfd
= compat_ptr(regs
->u_regs
[UREG_I2
]);
81 args
.child_tid
= compat_ptr(regs
->u_regs
[UREG_I4
]);
82 args
.parent_tid
= compat_ptr(regs
->u_regs
[UREG_I2
]);
86 args
.pidfd
= (int __user
*)regs
->u_regs
[UREG_I2
];
87 args
.child_tid
= (int __user
*)regs
->u_regs
[UREG_I4
];
88 args
.parent_tid
= (int __user
*)regs
->u_regs
[UREG_I2
];
91 /* Did userspace give setup a separate stack for the child or are we
92 * reusing the parent's?
94 if (regs
->u_regs
[UREG_I1
])
95 args
.stack
= regs
->u_regs
[UREG_I1
];
97 args
.stack
= regs
->u_regs
[UREG_FP
];
99 ret
= kernel_clone(&args
);
101 /* If we get an error and potentially restart the system
102 * call, we're screwed because copy_thread() clobbered
103 * the parent's %o1. So detect that case and restore it
106 if ((unsigned long)ret
>= -ERESTART_RESTARTBLOCK
)
107 regs
->u_regs
[UREG_I1
] = orig_i1
;