Commit dbb8864b authored by Heiko Carstens's avatar Heiko Carstens Committed by Vasily Gorbik
Browse files

s390/uaccess: get rid of register asm

parent 5fe29839
Loading
Loading
Loading
Loading
+17 −19
Original line number Diff line number Diff line
@@ -49,52 +49,51 @@ int __get_user_bad(void) __attribute__((noreturn));

#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES

#define __put_get_user_asm(to, from, size, spec)		\
#define __put_get_user_asm(to, from, size, insn)		\
({								\
	register unsigned long __reg0 asm("0") = spec;		\
	int __rc;						\
								\
	asm volatile(						\
		"0:	mvcos	%1,%3,%2\n"			\
		"1:	xr	%0,%0\n"			\
		insn "		0,%[spec]\n"			\
		"0:	mvcos	%[_to],%[_from],%[_size]\n"	\
		"1:	xr	%[rc],%[rc]\n"			\
		"2:\n"						\
		".pushsection .fixup, \"ax\"\n"			\
		"3:	lhi	%0,%5\n"			\
		"3:	lhi	%[rc],%[retval]\n"		\
		"	jg	2b\n"				\
		".popsection\n"					\
		EX_TABLE(0b,3b) EX_TABLE(1b,3b)			\
		: "=d" (__rc), "+Q" (*(to))			\
		: "d" (size), "Q" (*(from)),			\
		  "d" (__reg0), "K" (-EFAULT)			\
		: "cc");					\
		: [rc] "=&d" (__rc), [_to] "+Q" (*(to))		\
		: [_size] "d" (size), [_from] "Q" (*(from)),	\
		  [retval] "K" (-EFAULT), [spec] "K" (0x81UL)	\
		: "cc", "0");					\
	__rc;							\
})

static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
{
	unsigned long spec = 0x810000UL;
	int rc;

	switch (size) {
	case 1:
		rc = __put_get_user_asm((unsigned char __user *)ptr,
					(unsigned char *)x,
					size, spec);
					size, "llilh");
		break;
	case 2:
		rc = __put_get_user_asm((unsigned short __user *)ptr,
					(unsigned short *)x,
					size, spec);
					size, "llilh");
		break;
	case 4:
		rc = __put_get_user_asm((unsigned int __user *)ptr,
					(unsigned int *)x,
					size, spec);
					size, "llilh");
		break;
	case 8:
		rc = __put_get_user_asm((unsigned long __user *)ptr,
					(unsigned long *)x,
					size, spec);
					size, "llilh");
		break;
	default:
		__put_user_bad();
@@ -105,29 +104,28 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon

static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
{
	unsigned long spec = 0x81UL;
	int rc;

	switch (size) {
	case 1:
		rc = __put_get_user_asm((unsigned char *)x,
					(unsigned char __user *)ptr,
					size, spec);
					size, "lghi");
		break;
	case 2:
		rc = __put_get_user_asm((unsigned short *)x,
					(unsigned short __user *)ptr,
					size, spec);
					size, "lghi");
		break;
	case 4:
		rc = __put_get_user_asm((unsigned int *)x,
					(unsigned int __user *)ptr,
					size, spec);
					size, "lghi");
		break;
	case 8:
		rc = __put_get_user_asm((unsigned long *)x,
					(unsigned long __user *)ptr,
					size, spec);
					size, "lghi");
		break;
	default:
		__get_user_bad();