Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6e7bf900 authored by Max Filippov's avatar Max Filippov Committed by Greg Kroah-Hartman
Browse files

xtensa: fix futex_atomic_cmpxchg_inatomic



commit ca47480921587ae30417dd234a9f79af188e3666 upstream.

Return 0 if the operation was successful, not the userspace memory
value. Check that userspace value equals passed oldval, not itself.
Don't update *uval if the value wasn't read from userspace memory.

This fixes process hang due to infinite loop in futex_lock_pi.
It also fixes a bunch of glibc tests nptl/tst-mutexpi*.

Signed-off-by: default avatarMax Filippov <jcmvbkbc@gmail.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e6f03ae6
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -109,7 +109,6 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
			      u32 oldval, u32 newval)
{
	int ret = 0;
	u32 prev;

	if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
		return -EFAULT;
@@ -120,26 +119,24 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,

	__asm__ __volatile__ (
	"	# futex_atomic_cmpxchg_inatomic\n"
	"1:	l32i	%1, %3, 0\n"
	"	mov	%0, %5\n"
	"	wsr	%1, scompare1\n"
	"2:	s32c1i	%0, %3, 0\n"
	"3:\n"
	"	wsr	%5, scompare1\n"
	"1:	s32c1i	%1, %4, 0\n"
	"	s32i	%1, %6, 0\n"
	"2:\n"
	"	.section .fixup,\"ax\"\n"
	"	.align 4\n"
	"4:	.long	3b\n"
	"5:	l32r	%1, 4b\n"
	"	movi	%0, %6\n"
	"3:	.long	2b\n"
	"4:	l32r	%1, 3b\n"
	"	movi	%0, %7\n"
	"	jx	%1\n"
	"	.previous\n"
	"	.section __ex_table,\"a\"\n"
	"	.long 1b,5b,2b,5b\n"
	"	.long 1b,4b\n"
	"	.previous\n"
	: "+r" (ret), "=&r" (prev), "+m" (*uaddr)
	: "r" (uaddr), "r" (oldval), "r" (newval), "I" (-EFAULT)
	: "+r" (ret), "+r" (newval), "+m" (*uaddr), "+m" (*uval)
	: "r" (uaddr), "r" (oldval), "r" (uval), "I" (-EFAULT)
	: "memory");

	*uval = prev;
	return ret;
}