aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/process.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/kernel/process.c')
-rw-r--r--arch/arc/kernel/process.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/arch/arc/kernel/process.c b/arch/arc/kernel/process.c
index be1972bd2729..59aa43cb146e 100644
--- a/arch/arc/kernel/process.c
+++ b/arch/arc/kernel/process.c
@@ -41,6 +41,39 @@ SYSCALL_DEFINE0(arc_gettls)
41 return task_thread_info(current)->thr_ptr; 41 return task_thread_info(current)->thr_ptr;
42} 42}
43 43
44SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
45{
46 int uval;
47 int ret;
48
49 /*
50 * This is only for old cores lacking LLOCK/SCOND, which by defintion
51 * can't possibly be SMP. Thus doesn't need to be SMP safe.
52 * And this also helps reduce the overhead for serializing in
53 * the UP case
54 */
55 WARN_ON_ONCE(IS_ENABLED(CONFIG_SMP));
56
57 if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
58 return -EFAULT;
59
60 preempt_disable();
61
62 ret = __get_user(uval, uaddr);
63 if (ret)
64 goto done;
65
66 if (uval != expected)
67 ret = -EAGAIN;
68 else
69 ret = __put_user(new, uaddr);
70
71done:
72 preempt_enable();
73
74 return ret;
75}
76
44void arch_cpu_idle(void) 77void arch_cpu_idle(void)
45{ 78{
46 /* sleep, but enable all interrupts before committing */ 79 /* sleep, but enable all interrupts before committing */