2009-10-19 11:58:44 +02:00
# ifndef _ASM_MICROBLAZE_FUTEX_H
# define _ASM_MICROBLAZE_FUTEX_H
# ifdef __KERNEL__
# include <linux/futex.h>
# include <linux/uaccess.h>
# include <asm/errno.h>
# define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
( { \
__asm__ __volatile__ ( \
" 1: lwx %0, %2, r0; " \
insn \
" 2: swx %1, %2, r0; \
addic % 1 , r0 , 0 ; \
bnei % 1 , 1 b ; \
3 : \
. section . fixup , \ " ax \" ; \
4 : brid 3 b ; \
addik % 1 , r0 , % 3 ; \
. previous ; \
. section __ex_table , \ " a \" ; \
. word 1 b , 4 b , 2 b , 4 b ; \
. previous ; " \
: " =&r " ( oldval ) , " =&r " ( ret ) \
2012-03-27 10:10:15 +02:00
: " r " ( uaddr ) , " i " ( - EFAULT ) , " r " ( oparg ) \
2009-10-19 11:58:44 +02:00
) ; \
} )
static inline int
2017-08-24 09:31:05 +02:00
arch_futex_atomic_op_inuser ( int op , int oparg , int * oval , u32 __user * uaddr )
2009-10-19 11:58:44 +02:00
{
int oldval = 0 , ret ;
pagefault_disable ( ) ;
switch ( op ) {
case FUTEX_OP_SET :
__futex_atomic_op ( " or %1,%4,%4; " , ret , oldval , uaddr , oparg ) ;
break ;
case FUTEX_OP_ADD :
__futex_atomic_op ( " add %1,%0,%4; " , ret , oldval , uaddr , oparg ) ;
break ;
case FUTEX_OP_OR :
__futex_atomic_op ( " or %1,%0,%4; " , ret , oldval , uaddr , oparg ) ;
break ;
case FUTEX_OP_ANDN :
2010-04-06 18:51:37 +02:00
__futex_atomic_op ( " andn %1,%0,%4; " , ret , oldval , uaddr , oparg ) ;
2009-10-19 11:58:44 +02:00
break ;
case FUTEX_OP_XOR :
__futex_atomic_op ( " xor %1,%0,%4; " , ret , oldval , uaddr , oparg ) ;
break ;
default :
ret = - ENOSYS ;
}
pagefault_enable ( ) ;
2017-08-24 09:31:05 +02:00
if ( ! ret )
* oval = oldval ;
2009-10-19 11:58:44 +02:00
return ret ;
}
static inline int
2011-03-10 18:50:58 -08:00
futex_atomic_cmpxchg_inatomic ( u32 * uval , u32 __user * uaddr ,
u32 oldval , u32 newval )
2009-10-19 11:58:44 +02:00
{
2011-03-10 18:50:58 -08:00
int ret = 0 , cmp ;
u32 prev ;
2009-10-19 11:58:44 +02:00
2011-03-10 18:50:58 -08:00
if ( ! access_ok ( VERIFY_WRITE , uaddr , sizeof ( u32 ) ) )
2009-10-19 11:58:44 +02:00
return - EFAULT ;
2011-03-10 18:48:51 -08:00
__asm__ __volatile__ ( " 1: lwx %1, %3, r0; \
cmp % 2 , % 1 , % 4 ; \
2013-05-23 17:06:57 +00:00
bnei % 2 , 3f ; \
2011-03-10 18:48:51 -08:00
2 : swx % 5 , % 3 , r0 ; \
addic % 2 , r0 , 0 ; \
bnei % 2 , 1 b ; \
2009-10-19 11:58:44 +02:00
3 : \
. section . fixup , \ " ax \" ; \
4 : brid 3 b ; \
2011-03-10 18:48:51 -08:00
addik % 0 , r0 , % 6 ; \
2009-10-19 11:58:44 +02:00
. previous ; \
. section __ex_table , \ " a \" ; \
. word 1 b , 4 b , 2 b , 4 b ; \
. previous ; " \
2011-03-10 18:48:51 -08:00
: " +r " ( ret ) , " =&r " ( prev ) , " =&r " ( cmp ) \
2009-10-19 11:58:44 +02:00
: " r " ( uaddr ) , " r " ( oldval ) , " r " ( newval ) , " i " ( - EFAULT ) ) ;
2011-03-10 18:48:51 -08:00
* uval = prev ;
return ret ;
2009-10-19 11:58:44 +02:00
}
# endif /* __KERNEL__ */
# endif