162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __ASM_GENERIC_UACCESS_H
362306a36Sopenharmony_ci#define __ASM_GENERIC_UACCESS_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci * User space memory access functions, these should work
762306a36Sopenharmony_ci * on any machine that has kernel and user data in the same
862306a36Sopenharmony_ci * address space, e.g. all NOMMU machines.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci#include <linux/string.h>
1162306a36Sopenharmony_ci#include <asm-generic/access_ok.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#ifdef CONFIG_UACCESS_MEMCPY
1462306a36Sopenharmony_ci#include <asm/unaligned.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_cistatic __always_inline int
1762306a36Sopenharmony_ci__get_user_fn(size_t size, const void __user *from, void *to)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	BUILD_BUG_ON(!__builtin_constant_p(size));
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci	switch (size) {
2262306a36Sopenharmony_ci	case 1:
2362306a36Sopenharmony_ci		*(u8 *)to = *((u8 __force *)from);
2462306a36Sopenharmony_ci		return 0;
2562306a36Sopenharmony_ci	case 2:
2662306a36Sopenharmony_ci		*(u16 *)to = get_unaligned((u16 __force *)from);
2762306a36Sopenharmony_ci		return 0;
2862306a36Sopenharmony_ci	case 4:
2962306a36Sopenharmony_ci		*(u32 *)to = get_unaligned((u32 __force *)from);
3062306a36Sopenharmony_ci		return 0;
3162306a36Sopenharmony_ci	case 8:
3262306a36Sopenharmony_ci		*(u64 *)to = get_unaligned((u64 __force *)from);
3362306a36Sopenharmony_ci		return 0;
3462306a36Sopenharmony_ci	default:
3562306a36Sopenharmony_ci		BUILD_BUG();
3662306a36Sopenharmony_ci		return 0;
3762306a36Sopenharmony_ci	}
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci#define __get_user_fn(sz, u, k)	__get_user_fn(sz, u, k)
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_cistatic __always_inline int
4362306a36Sopenharmony_ci__put_user_fn(size_t size, void __user *to, void *from)
4462306a36Sopenharmony_ci{
4562306a36Sopenharmony_ci	BUILD_BUG_ON(!__builtin_constant_p(size));
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	switch (size) {
4862306a36Sopenharmony_ci	case 1:
4962306a36Sopenharmony_ci		*(u8 __force *)to = *(u8 *)from;
5062306a36Sopenharmony_ci		return 0;
5162306a36Sopenharmony_ci	case 2:
5262306a36Sopenharmony_ci		put_unaligned(*(u16 *)from, (u16 __force *)to);
5362306a36Sopenharmony_ci		return 0;
5462306a36Sopenharmony_ci	case 4:
5562306a36Sopenharmony_ci		put_unaligned(*(u32 *)from, (u32 __force *)to);
5662306a36Sopenharmony_ci		return 0;
5762306a36Sopenharmony_ci	case 8:
5862306a36Sopenharmony_ci		put_unaligned(*(u64 *)from, (u64 __force *)to);
5962306a36Sopenharmony_ci		return 0;
6062306a36Sopenharmony_ci	default:
6162306a36Sopenharmony_ci		BUILD_BUG();
6262306a36Sopenharmony_ci		return 0;
6362306a36Sopenharmony_ci	}
6462306a36Sopenharmony_ci}
6562306a36Sopenharmony_ci#define __put_user_fn(sz, u, k)	__put_user_fn(sz, u, k)
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci#define __get_kernel_nofault(dst, src, type, err_label)			\
6862306a36Sopenharmony_cido {									\
6962306a36Sopenharmony_ci	*((type *)dst) = get_unaligned((type *)(src));			\
7062306a36Sopenharmony_ci	if (0) /* make sure the label looks used to the compiler */	\
7162306a36Sopenharmony_ci		goto err_label;						\
7262306a36Sopenharmony_ci} while (0)
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#define __put_kernel_nofault(dst, src, type, err_label)			\
7562306a36Sopenharmony_cido {									\
7662306a36Sopenharmony_ci	put_unaligned(*((type *)src), (type *)(dst));			\
7762306a36Sopenharmony_ci	if (0) /* make sure the label looks used to the compiler */	\
7862306a36Sopenharmony_ci		goto err_label;						\
7962306a36Sopenharmony_ci} while (0)
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic inline __must_check unsigned long
8262306a36Sopenharmony_ciraw_copy_from_user(void *to, const void __user * from, unsigned long n)
8362306a36Sopenharmony_ci{
8462306a36Sopenharmony_ci	memcpy(to, (const void __force *)from, n);
8562306a36Sopenharmony_ci	return 0;
8662306a36Sopenharmony_ci}
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic inline __must_check unsigned long
8962306a36Sopenharmony_ciraw_copy_to_user(void __user *to, const void *from, unsigned long n)
9062306a36Sopenharmony_ci{
9162306a36Sopenharmony_ci	memcpy((void __force *)to, from, n);
9262306a36Sopenharmony_ci	return 0;
9362306a36Sopenharmony_ci}
9462306a36Sopenharmony_ci#define INLINE_COPY_FROM_USER
9562306a36Sopenharmony_ci#define INLINE_COPY_TO_USER
9662306a36Sopenharmony_ci#endif /* CONFIG_UACCESS_MEMCPY */
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci/*
9962306a36Sopenharmony_ci * These are the main single-value transfer routines.  They automatically
10062306a36Sopenharmony_ci * use the right size if we just have the right pointer type.
10162306a36Sopenharmony_ci * This version just falls back to copy_{from,to}_user, which should
10262306a36Sopenharmony_ci * provide a fast-path for small values.
10362306a36Sopenharmony_ci */
10462306a36Sopenharmony_ci#define __put_user(x, ptr) \
10562306a36Sopenharmony_ci({								\
10662306a36Sopenharmony_ci	__typeof__(*(ptr)) __x = (x);				\
10762306a36Sopenharmony_ci	int __pu_err = -EFAULT;					\
10862306a36Sopenharmony_ci        __chk_user_ptr(ptr);                                    \
10962306a36Sopenharmony_ci	switch (sizeof (*(ptr))) {				\
11062306a36Sopenharmony_ci	case 1:							\
11162306a36Sopenharmony_ci	case 2:							\
11262306a36Sopenharmony_ci	case 4:							\
11362306a36Sopenharmony_ci	case 8:							\
11462306a36Sopenharmony_ci		__pu_err = __put_user_fn(sizeof (*(ptr)),	\
11562306a36Sopenharmony_ci					 ptr, &__x);		\
11662306a36Sopenharmony_ci		break;						\
11762306a36Sopenharmony_ci	default:						\
11862306a36Sopenharmony_ci		__put_user_bad();				\
11962306a36Sopenharmony_ci		break;						\
12062306a36Sopenharmony_ci	 }							\
12162306a36Sopenharmony_ci	__pu_err;						\
12262306a36Sopenharmony_ci})
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci#define put_user(x, ptr)					\
12562306a36Sopenharmony_ci({								\
12662306a36Sopenharmony_ci	void __user *__p = (ptr);				\
12762306a36Sopenharmony_ci	might_fault();						\
12862306a36Sopenharmony_ci	access_ok(__p, sizeof(*ptr)) ?		\
12962306a36Sopenharmony_ci		__put_user((x), ((__typeof__(*(ptr)) __user *)__p)) :	\
13062306a36Sopenharmony_ci		-EFAULT;					\
13162306a36Sopenharmony_ci})
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci#ifndef __put_user_fn
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic inline int __put_user_fn(size_t size, void __user *ptr, void *x)
13662306a36Sopenharmony_ci{
13762306a36Sopenharmony_ci	return unlikely(raw_copy_to_user(ptr, x, size)) ? -EFAULT : 0;
13862306a36Sopenharmony_ci}
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci#define __put_user_fn(sz, u, k)	__put_user_fn(sz, u, k)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#endif
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ciextern int __put_user_bad(void) __attribute__((noreturn));
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci#define __get_user(x, ptr)					\
14762306a36Sopenharmony_ci({								\
14862306a36Sopenharmony_ci	int __gu_err = -EFAULT;					\
14962306a36Sopenharmony_ci	__chk_user_ptr(ptr);					\
15062306a36Sopenharmony_ci	switch (sizeof(*(ptr))) {				\
15162306a36Sopenharmony_ci	case 1: {						\
15262306a36Sopenharmony_ci		unsigned char __x = 0;				\
15362306a36Sopenharmony_ci		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
15462306a36Sopenharmony_ci					 ptr, &__x);		\
15562306a36Sopenharmony_ci		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
15662306a36Sopenharmony_ci		break;						\
15762306a36Sopenharmony_ci	};							\
15862306a36Sopenharmony_ci	case 2: {						\
15962306a36Sopenharmony_ci		unsigned short __x = 0;				\
16062306a36Sopenharmony_ci		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
16162306a36Sopenharmony_ci					 ptr, &__x);		\
16262306a36Sopenharmony_ci		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
16362306a36Sopenharmony_ci		break;						\
16462306a36Sopenharmony_ci	};							\
16562306a36Sopenharmony_ci	case 4: {						\
16662306a36Sopenharmony_ci		unsigned int __x = 0;				\
16762306a36Sopenharmony_ci		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
16862306a36Sopenharmony_ci					 ptr, &__x);		\
16962306a36Sopenharmony_ci		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
17062306a36Sopenharmony_ci		break;						\
17162306a36Sopenharmony_ci	};							\
17262306a36Sopenharmony_ci	case 8: {						\
17362306a36Sopenharmony_ci		unsigned long long __x = 0;			\
17462306a36Sopenharmony_ci		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
17562306a36Sopenharmony_ci					 ptr, &__x);		\
17662306a36Sopenharmony_ci		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
17762306a36Sopenharmony_ci		break;						\
17862306a36Sopenharmony_ci	};							\
17962306a36Sopenharmony_ci	default:						\
18062306a36Sopenharmony_ci		__get_user_bad();				\
18162306a36Sopenharmony_ci		break;						\
18262306a36Sopenharmony_ci	}							\
18362306a36Sopenharmony_ci	__gu_err;						\
18462306a36Sopenharmony_ci})
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci#define get_user(x, ptr)					\
18762306a36Sopenharmony_ci({								\
18862306a36Sopenharmony_ci	const void __user *__p = (ptr);				\
18962306a36Sopenharmony_ci	might_fault();						\
19062306a36Sopenharmony_ci	access_ok(__p, sizeof(*ptr)) ?		\
19162306a36Sopenharmony_ci		__get_user((x), (__typeof__(*(ptr)) __user *)__p) :\
19262306a36Sopenharmony_ci		((x) = (__typeof__(*(ptr)))0,-EFAULT);		\
19362306a36Sopenharmony_ci})
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#ifndef __get_user_fn
19662306a36Sopenharmony_cistatic inline int __get_user_fn(size_t size, const void __user *ptr, void *x)
19762306a36Sopenharmony_ci{
19862306a36Sopenharmony_ci	return unlikely(raw_copy_from_user(x, ptr, size)) ? -EFAULT : 0;
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci#define __get_user_fn(sz, u, k)	__get_user_fn(sz, u, k)
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci#endif
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ciextern int __get_user_bad(void) __attribute__((noreturn));
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci/*
20862306a36Sopenharmony_ci * Zero Userspace
20962306a36Sopenharmony_ci */
21062306a36Sopenharmony_ci#ifndef __clear_user
21162306a36Sopenharmony_cistatic inline __must_check unsigned long
21262306a36Sopenharmony_ci__clear_user(void __user *to, unsigned long n)
21362306a36Sopenharmony_ci{
21462306a36Sopenharmony_ci	memset((void __force *)to, 0, n);
21562306a36Sopenharmony_ci	return 0;
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci#endif
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_cistatic inline __must_check unsigned long
22062306a36Sopenharmony_ciclear_user(void __user *to, unsigned long n)
22162306a36Sopenharmony_ci{
22262306a36Sopenharmony_ci	might_fault();
22362306a36Sopenharmony_ci	if (!access_ok(to, n))
22462306a36Sopenharmony_ci		return n;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	return __clear_user(to, n);
22762306a36Sopenharmony_ci}
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci#include <asm/extable.h>
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci__must_check long strncpy_from_user(char *dst, const char __user *src,
23262306a36Sopenharmony_ci				    long count);
23362306a36Sopenharmony_ci__must_check long strnlen_user(const char __user *src, long n);
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci#endif /* __ASM_GENERIC_UACCESS_H */
236