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

Commit ef4e277b authored by Michal Simek's avatar Michal Simek
Browse files

microblaze: uaccess: Fix put_user for noMMU



Here is small regression on dhrystone tests and I think
that on all benchmarking tests. It is due to better checking
mechanism in put_user macro

Signed-off-by: default avatarMichal Simek <monstr@monstr.eu>
parent 3a6d7724
Loading
Loading
Loading
Loading
+56 −22
Original line number Diff line number Diff line
@@ -213,33 +213,67 @@ extern long __user_bad(void);
		? __get_user((x), (ptr)) : -EFAULT;			\
})

/* Undefined function to trigger linker error */
extern int bad_user_access_length(void);
#define __put_user_asm(insn, __gu_ptr, __gu_val, __gu_err)	\
({								\
	__asm__ __volatile__ (					\
			"1:"	insn	" %1, %2, r0;"		\
			"	addk	%0, r0, r0;"		\
			"2:			"		\
			__FIXUP_SECTION				\
			"3:	brid	2b;"			\
			"	addik	%0, r0, %3;"		\
			".previous;"				\
			__EX_TABLE_SECTION			\
			".word	1b,3b;"				\
			".previous;"				\
		: "=&r"(__gu_err)				\
		: "r"(__gu_val), "r"(__gu_ptr), "i"(-EFAULT)	\
	);							\
})

/* FIXME is not there defined __pu_val */
#define __put_user(var, ptr)					\
#define __put_user_asm_8(__gu_ptr, __gu_val, __gu_err)		\
({								\
	int __pu_err = 0;					\
	switch (sizeof(*(ptr))) {				\
	__asm__ __volatile__ ("	lwi	%0, %1, 0;"		\
			"1:	swi	%0, %2, 0;"		\
			"	lwi	%0, %1, 4;"		\
			"2:	swi	%0, %2, 4;"		\
			"	addk	%0, r0, r0;"		\
			"3:			"		\
			__FIXUP_SECTION				\
			"4:	brid	3b;"			\
			"	addik	%0, r0, %3;"		\
			".previous;"				\
			__EX_TABLE_SECTION			\
			".word	1b,4b,2b,4b;"			\
			".previous;"				\
		: "=&r"(__gu_err)				\
		: "r"(&__gu_val), "r"(__gu_ptr), "i"(-EFAULT)	\
		);						\
})

#define __put_user(x, ptr)						\
({									\
	__typeof__(*(ptr)) volatile __gu_val = (x);			\
	long __gu_err = 0;						\
	switch (sizeof(__gu_val)) {					\
	case 1:								\
		__put_user_asm("sb", (ptr), __gu_val, __gu_err);	\
		break;							\
	case 2:								\
		__put_user_asm("sh", (ptr), __gu_val, __gu_err);	\
		break;							\
	case 4:								\
		*(ptr) = (var);					\
		__put_user_asm("sw", (ptr), __gu_val, __gu_err);	\
		break;							\
	case 8: {						\
		typeof(*(ptr)) __pu_val = (var);		\
		memcpy(ptr, &__pu_val, sizeof(__pu_val));	\
		}						\
	case 8:								\
		__put_user_asm_8((ptr), __gu_val, __gu_err);		\
		break;							\
	default:							\
		__pu_err = __put_user_bad();			\
		break;						\
		/*__gu_err = -EINVAL;*/	__gu_err = __user_bad();	\
	}								\
	__pu_err;						\
	__gu_err;							\
})

#define __put_user_bad()	(bad_user_access_length(), (-EFAULT))

#define put_user(x, ptr)	__put_user((x), (ptr))

#define copy_to_user(to, from, n)	(memcpy((to), (from), (n)), 0)