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

futex.h (2605B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2
      3#ifndef __ASM_CSKY_FUTEX_H
      4#define __ASM_CSKY_FUTEX_H
      5
      6#ifndef CONFIG_SMP
      7#include <asm-generic/futex.h>
      8#else
      9#include <linux/atomic.h>
     10#include <linux/futex.h>
     11#include <linux/uaccess.h>
     12#include <linux/errno.h>
     13
     14#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg)		\
     15{									\
     16	u32 tmp;							\
     17									\
     18	__atomic_pre_full_fence();					\
     19									\
     20	__asm__ __volatile__ (						\
     21	"1:	ldex.w	%[ov], %[u]			\n"		\
     22	"	"insn"					\n"		\
     23	"2:	stex.w	%[t], %[u]			\n"		\
     24	"	bez	%[t], 1b			\n"		\
     25	"	br	4f				\n"		\
     26	"3:	mov	%[r], %[e]			\n"		\
     27	"4:						\n"		\
     28	"	.section __ex_table,\"a\"		\n"		\
     29	"	.balign 4				\n"		\
     30	"	.long	1b, 3b				\n"		\
     31	"	.long	2b, 3b				\n"		\
     32	"	.previous				\n"		\
     33	: [r] "+r" (ret), [ov] "=&r" (oldval),				\
     34	  [u] "+m" (*uaddr), [t] "=&r" (tmp)				\
     35	: [op] "Jr" (oparg), [e] "jr" (-EFAULT)				\
     36	: "memory");							\
     37									\
     38	__atomic_post_full_fence();					\
     39}
     40
     41static inline int
     42arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
     43{
     44	int oldval = 0, ret = 0;
     45
     46	if (!access_ok(uaddr, sizeof(u32)))
     47		return -EFAULT;
     48
     49	switch (op) {
     50	case FUTEX_OP_SET:
     51		__futex_atomic_op("mov %[t], %[ov]",
     52				  ret, oldval, uaddr, oparg);
     53		break;
     54	case FUTEX_OP_ADD:
     55		__futex_atomic_op("add %[t], %[ov], %[op]",
     56				  ret, oldval, uaddr, oparg);
     57		break;
     58	case FUTEX_OP_OR:
     59		__futex_atomic_op("or %[t], %[ov], %[op]",
     60				  ret, oldval, uaddr, oparg);
     61		break;
     62	case FUTEX_OP_ANDN:
     63		__futex_atomic_op("and %[t], %[ov], %[op]",
     64				  ret, oldval, uaddr, ~oparg);
     65		break;
     66	case FUTEX_OP_XOR:
     67		__futex_atomic_op("xor %[t], %[ov], %[op]",
     68				  ret, oldval, uaddr, oparg);
     69		break;
     70	default:
     71		ret = -ENOSYS;
     72	}
     73
     74	if (!ret)
     75		*oval = oldval;
     76
     77	return ret;
     78}
     79
     80
     81
     82static inline int
     83futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
     84			      u32 oldval, u32 newval)
     85{
     86	int ret = 0;
     87	u32 val, tmp;
     88
     89	if (!access_ok(uaddr, sizeof(u32)))
     90		return -EFAULT;
     91
     92	__atomic_pre_full_fence();
     93
     94	__asm__ __volatile__ (
     95	"1:	ldex.w	%[v], %[u]			\n"
     96	"	cmpne	%[v], %[ov]			\n"
     97	"	bt	4f				\n"
     98	"	mov	%[t], %[nv]			\n"
     99	"2:	stex.w	%[t], %[u]			\n"
    100	"	bez	%[t], 1b			\n"
    101	"	br	4f				\n"
    102	"3:	mov	%[r], %[e]			\n"
    103	"4:						\n"
    104	"	.section __ex_table,\"a\"		\n"
    105	"	.balign 4				\n"
    106	"	.long	1b, 3b				\n"
    107	"	.long	2b, 3b				\n"
    108	"	.previous				\n"
    109	: [r] "+r" (ret), [v] "=&r" (val), [u] "+m" (*uaddr),
    110	  [t] "=&r" (tmp)
    111	: [ov] "Jr" (oldval), [nv] "Jr" (newval), [e] "Jr" (-EFAULT)
    112	: "memory");
    113
    114	__atomic_post_full_fence();
    115
    116	*uval = val;
    117	return ret;
    118}
    119
    120#endif /* CONFIG_SMP */
    121#endif /* __ASM_CSKY_FUTEX_H */