cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

process.c (2805B)


      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 = regs->u_regs[UREG_I1];
     21	long ret;
     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],
     26	};
     27
     28	ret = kernel_clone(&args);
     29
     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
     33	 * here.
     34	 */
     35	if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
     36		regs->u_regs[UREG_I1] = orig_i1;
     37
     38	return ret;
     39}
     40
     41asmlinkage long sparc_vfork(struct pt_regs *regs)
     42{
     43	unsigned long orig_i1 = regs->u_regs[UREG_I1];
     44	long ret;
     45
     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],
     51	};
     52
     53	ret = kernel_clone(&args);
     54
     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
     58	 * here.
     59	 */
     60	if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
     61		regs->u_regs[UREG_I1] = orig_i1;
     62
     63	return ret;
     64}
     65
     66asmlinkage long sparc_clone(struct pt_regs *regs)
     67{
     68	unsigned long orig_i1 = regs->u_regs[UREG_I1];
     69	unsigned int flags = lower_32_bits(regs->u_regs[UREG_I0]);
     70	long ret;
     71
     72	struct kernel_clone_args args = {
     73		.flags		= (flags & ~CSIGNAL),
     74		.exit_signal	= (flags & CSIGNAL),
     75		.tls		= regs->u_regs[UREG_I3],
     76	};
     77
     78#ifdef CONFIG_COMPAT
     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]);
     83	} else
     84#endif
     85	{
     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];
     89	}
     90
     91	/* Did userspace give setup a separate stack for the child or are we
     92	 * reusing the parent's?
     93	 */
     94	if (regs->u_regs[UREG_I1])
     95		args.stack = regs->u_regs[UREG_I1];
     96	else
     97		args.stack = regs->u_regs[UREG_FP];
     98
     99	ret = kernel_clone(&args);
    100
    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
    104	 * here.
    105	 */
    106	if ((unsigned long)ret >= -ERESTART_RESTARTBLOCK)
    107		regs->u_regs[UREG_I1] = orig_i1;
    108
    109	return ret;
    110}