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 (7608B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
      4 *
      5 * Amit Bhor, Kanika Nema: Codito Technologies 2004
      6 */
      7
      8#include <linux/errno.h>
      9#include <linux/module.h>
     10#include <linux/sched.h>
     11#include <linux/sched/task.h>
     12#include <linux/sched/task_stack.h>
     13
     14#include <linux/mm.h>
     15#include <linux/fs.h>
     16#include <linux/unistd.h>
     17#include <linux/ptrace.h>
     18#include <linux/slab.h>
     19#include <linux/syscalls.h>
     20#include <linux/elf.h>
     21#include <linux/tick.h>
     22
     23#include <asm/fpu.h>
     24
     25SYSCALL_DEFINE1(arc_settls, void *, user_tls_data_ptr)
     26{
     27	task_thread_info(current)->thr_ptr = (unsigned int)user_tls_data_ptr;
     28	return 0;
     29}
     30
     31/*
     32 * We return the user space TLS data ptr as sys-call return code
     33 * Ideally it should be copy to user.
     34 * However we can cheat by the fact that some sys-calls do return
     35 * absurdly high values
     36 * Since the tls dat aptr is not going to be in range of 0xFFFF_xxxx
     37 * it won't be considered a sys-call error
     38 * and it will be loads better than copy-to-user, which is a definite
     39 * D-TLB Miss
     40 */
     41SYSCALL_DEFINE0(arc_gettls)
     42{
     43	return task_thread_info(current)->thr_ptr;
     44}
     45
     46SYSCALL_DEFINE3(arc_usr_cmpxchg, int __user *, uaddr, int, expected, int, new)
     47{
     48	struct pt_regs *regs = current_pt_regs();
     49	u32 uval;
     50	int ret;
     51
     52	/*
     53	 * This is only for old cores lacking LLOCK/SCOND, which by definition
     54	 * can't possibly be SMP. Thus doesn't need to be SMP safe.
     55	 * And this also helps reduce the overhead for serializing in
     56	 * the UP case
     57	 */
     58	WARN_ON_ONCE(IS_ENABLED(CONFIG_SMP));
     59
     60	/* Z indicates to userspace if operation succeeded */
     61	regs->status32 &= ~STATUS_Z_MASK;
     62
     63	ret = access_ok(uaddr, sizeof(*uaddr));
     64	if (!ret)
     65		 goto fail;
     66
     67again:
     68	preempt_disable();
     69
     70	ret = __get_user(uval, uaddr);
     71	if (ret)
     72		 goto fault;
     73
     74	if (uval != expected)
     75		 goto out;
     76
     77	ret = __put_user(new, uaddr);
     78	if (ret)
     79		 goto fault;
     80
     81	regs->status32 |= STATUS_Z_MASK;
     82
     83out:
     84	preempt_enable();
     85	return uval;
     86
     87fault:
     88	preempt_enable();
     89
     90	if (unlikely(ret != -EFAULT))
     91		 goto fail;
     92
     93	mmap_read_lock(current->mm);
     94	ret = fixup_user_fault(current->mm, (unsigned long) uaddr,
     95			       FAULT_FLAG_WRITE, NULL);
     96	mmap_read_unlock(current->mm);
     97
     98	if (likely(!ret))
     99		 goto again;
    100
    101fail:
    102	force_sig(SIGSEGV);
    103	return ret;
    104}
    105
    106#ifdef CONFIG_ISA_ARCV2
    107
    108void arch_cpu_idle(void)
    109{
    110	/* Re-enable interrupts <= default irq priority before committing SLEEP */
    111	const unsigned int arg = 0x10 | ARCV2_IRQ_DEF_PRIO;
    112
    113	__asm__ __volatile__(
    114		"sleep %0	\n"
    115		:
    116		:"I"(arg)); /* can't be "r" has to be embedded const */
    117}
    118
    119#else	/* ARC700 */
    120
    121void arch_cpu_idle(void)
    122{
    123	/* sleep, but enable both set E1/E2 (levels of interrupts) before committing */
    124	__asm__ __volatile__("sleep 0x3	\n");
    125}
    126
    127#endif
    128
    129asmlinkage void ret_from_fork(void);
    130
    131/*
    132 * Copy architecture-specific thread state
    133 *
    134 * Layout of Child kernel mode stack as setup at the end of this function is
    135 *
    136 * |     ...        |
    137 * |     ...        |
    138 * |    unused      |
    139 * |                |
    140 * ------------------
    141 * |     r25        |   <==== top of Stack (thread.ksp)
    142 * ~                ~
    143 * |    --to--      |   (CALLEE Regs of kernel mode)
    144 * |     r13        |
    145 * ------------------
    146 * |     fp         |
    147 * |    blink       |   @ret_from_fork
    148 * ------------------
    149 * |                |
    150 * ~                ~
    151 * ~                ~
    152 * |                |
    153 * ------------------
    154 * |     r12        |
    155 * ~                ~
    156 * |    --to--      |   (scratch Regs of user mode)
    157 * |     r0         |
    158 * ------------------
    159 * |      SP        |
    160 * |    orig_r0     |
    161 * |    event/ECR   |
    162 * |    user_r25    |
    163 * ------------------  <===== END of PAGE
    164 */
    165int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
    166{
    167	unsigned long clone_flags = args->flags;
    168	unsigned long usp = args->stack;
    169	unsigned long tls = args->tls;
    170	struct pt_regs *c_regs;        /* child's pt_regs */
    171	unsigned long *childksp;       /* to unwind out of __switch_to() */
    172	struct callee_regs *c_callee;  /* child's callee regs */
    173	struct callee_regs *parent_callee;  /* paren't callee */
    174	struct pt_regs *regs = current_pt_regs();
    175
    176	/* Mark the specific anchors to begin with (see pic above) */
    177	c_regs = task_pt_regs(p);
    178	childksp = (unsigned long *)c_regs - 2;  /* 2 words for FP/BLINK */
    179	c_callee = ((struct callee_regs *)childksp) - 1;
    180
    181	/*
    182	 * __switch_to() uses thread.ksp to start unwinding stack
    183	 * For kernel threads we don't need to create callee regs, the
    184	 * stack layout nevertheless needs to remain the same.
    185	 * Also, since __switch_to anyways unwinds callee regs, we use
    186	 * this to populate kernel thread entry-pt/args into callee regs,
    187	 * so that ret_from_kernel_thread() becomes simpler.
    188	 */
    189	p->thread.ksp = (unsigned long)c_callee;	/* THREAD_KSP */
    190
    191	/* __switch_to expects FP(0), BLINK(return addr) at top */
    192	childksp[0] = 0;			/* fp */
    193	childksp[1] = (unsigned long)ret_from_fork; /* blink */
    194
    195	if (unlikely(args->fn)) {
    196		memset(c_regs, 0, sizeof(struct pt_regs));
    197
    198		c_callee->r13 = (unsigned long)args->fn_arg;
    199		c_callee->r14 = (unsigned long)args->fn;
    200
    201		return 0;
    202	}
    203
    204	/*--------- User Task Only --------------*/
    205
    206	/* __switch_to expects FP(0), BLINK(return addr) at top of stack */
    207	childksp[0] = 0;				/* for POP fp */
    208	childksp[1] = (unsigned long)ret_from_fork;	/* for POP blink */
    209
    210	/* Copy parents pt regs on child's kernel mode stack */
    211	*c_regs = *regs;
    212
    213	if (usp)
    214		c_regs->sp = usp;
    215
    216	c_regs->r0 = 0;		/* fork returns 0 in child */
    217
    218	parent_callee = ((struct callee_regs *)regs) - 1;
    219	*c_callee = *parent_callee;
    220
    221	if (unlikely(clone_flags & CLONE_SETTLS)) {
    222		/*
    223		 * set task's userland tls data ptr from 4th arg
    224		 * clone C-lib call is difft from clone sys-call
    225		 */
    226		task_thread_info(p)->thr_ptr = tls;
    227	} else {
    228		/* Normal fork case: set parent's TLS ptr in child */
    229		task_thread_info(p)->thr_ptr =
    230		task_thread_info(current)->thr_ptr;
    231	}
    232
    233
    234	/*
    235	 * setup usermode thread pointer #1:
    236	 * when child is picked by scheduler, __switch_to() uses @c_callee to
    237	 * populate usermode callee regs: this works (despite being in a kernel
    238	 * function) since special return path for child @ret_from_fork()
    239	 * ensures those regs are not clobbered all the way to RTIE to usermode
    240	 */
    241	c_callee->r25 = task_thread_info(p)->thr_ptr;
    242
    243#ifdef CONFIG_ARC_CURR_IN_REG
    244	/*
    245	 * setup usermode thread pointer #2:
    246	 * however for this special use of r25 in kernel, __switch_to() sets
    247	 * r25 for kernel needs and only in the final return path is usermode
    248	 * r25 setup, from pt_regs->user_r25. So set that up as well
    249	 */
    250	c_regs->user_r25 = c_callee->r25;
    251#endif
    252
    253	return 0;
    254}
    255
    256/*
    257 * Do necessary setup to start up a new user task
    258 */
    259void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp)
    260{
    261	regs->sp = usp;
    262	regs->ret = pc;
    263
    264	/*
    265	 * [U]ser Mode bit set
    266	 * [L] ZOL loop inhibited to begin with - cleared by a LP insn
    267	 * Interrupts enabled
    268	 */
    269	regs->status32 = STATUS_U_MASK | STATUS_L_MASK | ISA_INIT_STATUS_BITS;
    270
    271	fpu_init_task(regs);
    272
    273	/* bogus seed values for debugging */
    274	regs->lp_start = 0x10;
    275	regs->lp_end = 0x80;
    276}
    277
    278/*
    279 * Some archs flush debug and FPU info here
    280 */
    281void flush_thread(void)
    282{
    283}
    284
    285int elf_check_arch(const struct elf32_hdr *x)
    286{
    287	unsigned int eflags;
    288
    289	if (x->e_machine != EM_ARC_INUSE) {
    290		pr_err("ELF not built for %s ISA\n",
    291			is_isa_arcompact() ? "ARCompact":"ARCv2");
    292		return 0;
    293	}
    294
    295	eflags = x->e_flags;
    296	if ((eflags & EF_ARC_OSABI_MSK) != EF_ARC_OSABI_CURRENT) {
    297		pr_err("ABI mismatch - you need newer toolchain\n");
    298		force_fatal_sig(SIGSEGV);
    299		return 0;
    300	}
    301
    302	return 1;
    303}
    304EXPORT_SYMBOL(elf_check_arch);