ARC: syscall for userspace cmpxchg assist
Older ARC700 cores (ARC750 specifically) lack instructions to implement atomic r-w-w. This is problematic for userspace libraries such as NPTL which need atomic primitives. So enable them by providing kernel assist. This is costly but really the only sane soluton (othern than tight spinning using the otherwise availiable atomic exchange EX instruciton). Good thing is there are only a few of these cores running Linux out in the wild. This only works on UP systems. Reviewed-by: Colin Ian King <colin.king@canonical.com> Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
This commit is contained in:
@@ -41,6 +41,39 @@ SYSCALL_DEFINE0(arc_gettls)
|
||||
return task_thread_info(current)->thr_ptr;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new)
|
||||
{
|
||||
int uval;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* This is only for old cores lacking LLOCK/SCOND, which by defintion
|
||||
* can't possibly be SMP. Thus doesn't need to be SMP safe.
|
||||
* And this also helps reduce the overhead for serializing in
|
||||
* the UP case
|
||||
*/
|
||||
WARN_ON_ONCE(IS_ENABLED(CONFIG_SMP));
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
|
||||
return -EFAULT;
|
||||
|
||||
preempt_disable();
|
||||
|
||||
ret = __get_user(uval, uaddr);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
if (uval != expected)
|
||||
ret = -EAGAIN;
|
||||
else
|
||||
ret = __put_user(new, uaddr);
|
||||
|
||||
done:
|
||||
preempt_enable();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void arch_cpu_idle(void)
|
||||
{
|
||||
/* sleep, but enable all interrupts before committing */
|
||||
|
||||
Reference in New Issue
Block a user