FILE
process.c
File preview with syntax highlighting.
linux-6.19.14/arch/sparc/kernel/process.c
1// SPDX-License-Identifier: GPL-2.0 2 3/* 4 * This file handles the architecture independent parts of process handling.. 5 */ 6 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> 15 16#include "kernel.h" 17 18asmlinkage long sparc_fork(struct pt_regs *regs) 19{ 20 unsigned long orig_i1; 21 long ret; 22 struct kernel_clone_args args = { 23 .exit_signal = SIGCHLD, 24 }; 25 26 synchronize_user_stack(); 27 28 orig_i1 = regs->u_regs[UREG_I1]; 29 /* Reuse the parent's stack for the child. */ 30 args.stack = regs->u_regs[UREG_FP]; 31 32 ret = kernel_clone(&args); 33 34 /* If we get an error and potentially restart the system 35 * call, we're screwed because copy_thread() clobbered 36 * the parent's %o1. So detect that case and restore it 37 * here. 38 */ 39 if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) 40 regs->u_regs[UREG_I1] = orig_i1; 41 42 return ret; 43} 44 45asmlinkage long sparc_vfork(struct pt_regs *regs) 46{ 47 unsigned long orig_i1; 48 long ret; 49 struct kernel_clone_args args = { 50 .flags = CLONE_VFORK | CLONE_VM, 51 .exit_signal = SIGCHLD, 52 }; 53 54 synchronize_user_stack(); 55 56 orig_i1 = regs->u_regs[UREG_I1]; 57 /* Reuse the parent's stack for the child. */ 58 args.stack = regs->u_regs[UREG_FP]; 59 60 ret = kernel_clone(&args); 61 62 /* If we get an error and potentially restart the system 63 * call, we're screwed because copy_thread() clobbered 64 * the parent's %o1. So detect that case and restore it 65 * here. 66 */ 67 if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) 68 regs->u_regs[UREG_I1] = orig_i1; 69 70 return ret; 71} 72 73asmlinkage long sparc_clone(struct pt_regs *regs) 74{ 75 unsigned long orig_i1; 76 unsigned int flags; 77 long ret; 78 struct kernel_clone_args args = {0}; 79 80 synchronize_user_stack(); 81 82 orig_i1 = regs->u_regs[UREG_I1]; 83 flags = lower_32_bits(regs->u_regs[UREG_I0]); 84 args.flags = (flags & ~CSIGNAL); 85 args.exit_signal = (flags & CSIGNAL); 86 args.tls = regs->u_regs[UREG_I3]; 87 88#ifdef CONFIG_COMPAT 89 if (test_thread_flag(TIF_32BIT)) { 90 args.pidfd = compat_ptr(regs->u_regs[UREG_I2]); 91 args.child_tid = compat_ptr(regs->u_regs[UREG_I4]); 92 args.parent_tid = compat_ptr(regs->u_regs[UREG_I2]); 93 } else 94#endif 95 { 96 args.pidfd = (int __user *)regs->u_regs[UREG_I2]; 97 args.child_tid = (int __user *)regs->u_regs[UREG_I4]; 98 args.parent_tid = (int __user *)regs->u_regs[UREG_I2]; 99 } 100 101 /* Did userspace give setup a separate stack for the child or are we 102 * reusing the parent's? 103 */ 104 if (regs->u_regs[UREG_I1]) 105 args.stack = regs->u_regs[UREG_I1]; 106 else 107 args.stack = regs->u_regs[UREG_FP]; 108 109 ret = kernel_clone(&args); 110 111 /* If we get an error and potentially restart the system 112 * call, we're screwed because copy_thread() clobbered 113 * the parent's %o1. So detect that case and restore it 114 * here. 115 */ 116 if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK) 117 regs->u_regs[UREG_I1] = orig_i1; 118 119 return ret; 120}
~/
Read-only file preview.