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


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _ASM_MICROBLAZE_FUTEX_H
      3#define _ASM_MICROBLAZE_FUTEX_H
      4
      5#ifdef __KERNEL__
      6
      7#include <linux/futex.h>
      8#include <linux/uaccess.h>
      9#include <asm/errno.h>
     10
     11#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
     12({									\
     13	__asm__ __volatile__ (						\
     14			"1:	lwx	%0, %2, r0; "			\
     15				insn					\
     16			"2:	swx	%1, %2, r0;			\
     17				addic	%1, r0, 0;			\
     18				bnei	%1, 1b;				\
     19			3:						\
     20			.section .fixup,\"ax\";				\
     21			4:	brid	3b;				\
     22				addik	%1, r0, %3;			\
     23			.previous;					\
     24			.section __ex_table,\"a\";			\
     25			.word	1b,4b,2b,4b;				\
     26			.previous;"					\
     27	: "=&r" (oldval), "=&r" (ret)					\
     28	: "r" (uaddr), "i" (-EFAULT), "r" (oparg)			\
     29	);								\
     30})
     31
     32static inline int
     33arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr)
     34{
     35	int oldval = 0, ret;
     36
     37	if (!access_ok(uaddr, sizeof(u32)))
     38		return -EFAULT;
     39
     40	switch (op) {
     41	case FUTEX_OP_SET:
     42		__futex_atomic_op("or %1,%4,%4;", ret, oldval, uaddr, oparg);
     43		break;
     44	case FUTEX_OP_ADD:
     45		__futex_atomic_op("add %1,%0,%4;", ret, oldval, uaddr, oparg);
     46		break;
     47	case FUTEX_OP_OR:
     48		__futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
     49		break;
     50	case FUTEX_OP_ANDN:
     51		__futex_atomic_op("andn %1,%0,%4;", ret, oldval, uaddr, oparg);
     52		break;
     53	case FUTEX_OP_XOR:
     54		__futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
     55		break;
     56	default:
     57		ret = -ENOSYS;
     58	}
     59
     60	if (!ret)
     61		*oval = oldval;
     62
     63	return ret;
     64}
     65
     66static inline int
     67futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
     68			      u32 oldval, u32 newval)
     69{
     70	int ret = 0, cmp;
     71	u32 prev;
     72
     73	if (!access_ok(uaddr, sizeof(u32)))
     74		return -EFAULT;
     75
     76	__asm__ __volatile__ ("1:	lwx	%1, %3, r0;		\
     77					cmp	%2, %1, %4;		\
     78					bnei	%2, 3f;			\
     79				2:	swx	%5, %3, r0;		\
     80					addic	%2, r0, 0;		\
     81					bnei	%2, 1b;			\
     82				3:					\
     83				.section .fixup,\"ax\";			\
     84				4:	brid	3b;			\
     85					addik	%0, r0, %6;		\
     86				.previous;				\
     87				.section __ex_table,\"a\";		\
     88				.word	1b,4b,2b,4b;			\
     89				.previous;"				\
     90		: "+r" (ret), "=&r" (prev), "=&r"(cmp)	\
     91		: "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));
     92
     93	*uval = prev;
     94	return ret;
     95}
     96
     97#endif /* __KERNEL__ */
     98
     99#endif