| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 5 | | - * it under the terms of the GNU General Public License version 2 as |
|---|
| 6 | | - * published by the Free Software Foundation. |
|---|
| 7 | 4 | * |
|---|
| 8 | 5 | * Amit Bhor, Kanika Nema: Codito Technologies 2004 |
|---|
| 9 | 6 | */ |
|---|
| .. | .. |
|---|
| 22 | 19 | #include <linux/syscalls.h> |
|---|
| 23 | 20 | #include <linux/elf.h> |
|---|
| 24 | 21 | #include <linux/tick.h> |
|---|
| 22 | + |
|---|
| 23 | +#include <asm/fpu.h> |
|---|
| 25 | 24 | |
|---|
| 26 | 25 | SYSCALL_DEFINE1(arc_settls, void *, user_tls_data_ptr) |
|---|
| 27 | 26 | { |
|---|
| .. | .. |
|---|
| 44 | 43 | return task_thread_info(current)->thr_ptr; |
|---|
| 45 | 44 | } |
|---|
| 46 | 45 | |
|---|
| 47 | | -SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new) |
|---|
| 46 | +SYSCALL_DEFINE3(arc_usr_cmpxchg, int __user *, uaddr, int, expected, int, new) |
|---|
| 48 | 47 | { |
|---|
| 49 | 48 | struct pt_regs *regs = current_pt_regs(); |
|---|
| 50 | 49 | u32 uval; |
|---|
| .. | .. |
|---|
| 61 | 60 | /* Z indicates to userspace if operation succeded */ |
|---|
| 62 | 61 | regs->status32 &= ~STATUS_Z_MASK; |
|---|
| 63 | 62 | |
|---|
| 64 | | - ret = access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr)); |
|---|
| 63 | + ret = access_ok(uaddr, sizeof(*uaddr)); |
|---|
| 65 | 64 | if (!ret) |
|---|
| 66 | 65 | goto fail; |
|---|
| 67 | 66 | |
|---|
| .. | .. |
|---|
| 91 | 90 | if (unlikely(ret != -EFAULT)) |
|---|
| 92 | 91 | goto fail; |
|---|
| 93 | 92 | |
|---|
| 94 | | - down_read(¤t->mm->mmap_sem); |
|---|
| 95 | | - ret = fixup_user_fault(current, current->mm, (unsigned long) uaddr, |
|---|
| 93 | + mmap_read_lock(current->mm); |
|---|
| 94 | + ret = fixup_user_fault(current->mm, (unsigned long) uaddr, |
|---|
| 96 | 95 | FAULT_FLAG_WRITE, NULL); |
|---|
| 97 | | - up_read(¤t->mm->mmap_sem); |
|---|
| 96 | + mmap_read_unlock(current->mm); |
|---|
| 98 | 97 | |
|---|
| 99 | 98 | if (likely(!ret)) |
|---|
| 100 | 99 | goto again; |
|---|
| 101 | 100 | |
|---|
| 102 | 101 | fail: |
|---|
| 103 | | - force_sig(SIGSEGV, current); |
|---|
| 102 | + force_sig(SIGSEGV); |
|---|
| 104 | 103 | return ret; |
|---|
| 105 | 104 | } |
|---|
| 106 | 105 | |
|---|
| .. | .. |
|---|
| 115 | 114 | "sleep %0 \n" |
|---|
| 116 | 115 | : |
|---|
| 117 | 116 | :"I"(arg)); /* can't be "r" has to be embedded const */ |
|---|
| 118 | | -} |
|---|
| 119 | | - |
|---|
| 120 | | -#elif defined(CONFIG_EZNPS_MTM_EXT) /* ARC700 variant in NPS */ |
|---|
| 121 | | - |
|---|
| 122 | | -void arch_cpu_idle(void) |
|---|
| 123 | | -{ |
|---|
| 124 | | - /* only the calling HW thread needs to sleep */ |
|---|
| 125 | | - __asm__ __volatile__( |
|---|
| 126 | | - ".word %0 \n" |
|---|
| 127 | | - : |
|---|
| 128 | | - :"i"(CTOP_INST_HWSCHD_WFT_IE12)); |
|---|
| 129 | 117 | } |
|---|
| 130 | 118 | |
|---|
| 131 | 119 | #else /* ARC700 */ |
|---|
| .. | .. |
|---|
| 174 | 162 | * | user_r25 | |
|---|
| 175 | 163 | * ------------------ <===== END of PAGE |
|---|
| 176 | 164 | */ |
|---|
| 177 | | -int copy_thread(unsigned long clone_flags, |
|---|
| 178 | | - unsigned long usp, unsigned long kthread_arg, |
|---|
| 179 | | - struct task_struct *p) |
|---|
| 165 | +int copy_thread(unsigned long clone_flags, unsigned long usp, |
|---|
| 166 | + unsigned long kthread_arg, struct task_struct *p, |
|---|
| 167 | + unsigned long tls) |
|---|
| 180 | 168 | { |
|---|
| 181 | 169 | struct pt_regs *c_regs; /* child's pt_regs */ |
|---|
| 182 | 170 | unsigned long *childksp; /* to unwind out of __switch_to() */ |
|---|
| .. | .. |
|---|
| 203 | 191 | childksp[0] = 0; /* fp */ |
|---|
| 204 | 192 | childksp[1] = (unsigned long)ret_from_fork; /* blink */ |
|---|
| 205 | 193 | |
|---|
| 206 | | - if (unlikely(p->flags & PF_KTHREAD)) { |
|---|
| 194 | + if (unlikely(p->flags & (PF_KTHREAD | PF_IO_WORKER))) { |
|---|
| 207 | 195 | memset(c_regs, 0, sizeof(struct pt_regs)); |
|---|
| 208 | 196 | |
|---|
| 209 | 197 | c_callee->r13 = kthread_arg; |
|---|
| .. | .. |
|---|
| 234 | 222 | * set task's userland tls data ptr from 4th arg |
|---|
| 235 | 223 | * clone C-lib call is difft from clone sys-call |
|---|
| 236 | 224 | */ |
|---|
| 237 | | - task_thread_info(p)->thr_ptr = regs->r3; |
|---|
| 225 | + task_thread_info(p)->thr_ptr = tls; |
|---|
| 238 | 226 | } else { |
|---|
| 239 | 227 | /* Normal fork case: set parent's TLS ptr in child */ |
|---|
| 240 | 228 | task_thread_info(p)->thr_ptr = |
|---|
| .. | .. |
|---|
| 267 | 255 | /* |
|---|
| 268 | 256 | * Do necessary setup to start up a new user task |
|---|
| 269 | 257 | */ |
|---|
| 270 | | -void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long usp) |
|---|
| 258 | +void start_thread(struct pt_regs *regs, unsigned long pc, unsigned long usp) |
|---|
| 271 | 259 | { |
|---|
| 272 | 260 | regs->sp = usp; |
|---|
| 273 | 261 | regs->ret = pc; |
|---|
| .. | .. |
|---|
| 279 | 267 | */ |
|---|
| 280 | 268 | regs->status32 = STATUS_U_MASK | STATUS_L_MASK | ISA_INIT_STATUS_BITS; |
|---|
| 281 | 269 | |
|---|
| 282 | | -#ifdef CONFIG_EZNPS_MTM_EXT |
|---|
| 283 | | - regs->eflags = 0; |
|---|
| 284 | | -#endif |
|---|
| 270 | + fpu_init_task(regs); |
|---|
| 285 | 271 | |
|---|
| 286 | 272 | /* bogus seed values for debugging */ |
|---|
| 287 | 273 | regs->lp_start = 0x10; |
|---|
| .. | .. |
|---|
| 293 | 279 | */ |
|---|
| 294 | 280 | void flush_thread(void) |
|---|
| 295 | 281 | { |
|---|
| 296 | | -} |
|---|
| 297 | | - |
|---|
| 298 | | -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) |
|---|
| 299 | | -{ |
|---|
| 300 | | - return 0; |
|---|
| 301 | 282 | } |
|---|
| 302 | 283 | |
|---|
| 303 | 284 | int elf_check_arch(const struct elf32_hdr *x) |
|---|
| .. | .. |
|---|
| 313 | 294 | eflags = x->e_flags; |
|---|
| 314 | 295 | if ((eflags & EF_ARC_OSABI_MSK) != EF_ARC_OSABI_CURRENT) { |
|---|
| 315 | 296 | pr_err("ABI mismatch - you need newer toolchain\n"); |
|---|
| 316 | | - force_sigsegv(SIGSEGV, current); |
|---|
| 297 | + force_sigsegv(SIGSEGV); |
|---|
| 317 | 298 | return 0; |
|---|
| 318 | 299 | } |
|---|
| 319 | 300 | |
|---|