cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

uaccess.h (8027B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2/*
      3 * Copyright (C) 2020-2022 Loongson Technology Corporation Limited
      4 *
      5 * Derived from MIPS:
      6 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 03, 04 by Ralf Baechle
      7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
      8 * Copyright (C) 2007  Maciej W. Rozycki
      9 * Copyright (C) 2014, Imagination Technologies Ltd.
     10 */
     11#ifndef _ASM_UACCESS_H
     12#define _ASM_UACCESS_H
     13
     14#include <linux/kernel.h>
     15#include <linux/string.h>
     16#include <linux/extable.h>
     17#include <asm/pgtable.h>
     18#include <asm-generic/extable.h>
     19#include <asm-generic/access_ok.h>
     20
     21extern u64 __ua_limit;
     22
     23#define __UA_ADDR	".dword"
     24#define __UA_LA		"la.abs"
     25#define __UA_LIMIT	__ua_limit
     26
     27/*
     28 * get_user: - Get a simple variable from user space.
     29 * @x:	 Variable to store result.
     30 * @ptr: Source address, in user space.
     31 *
     32 * Context: User context only. This function may sleep if pagefaults are
     33 *          enabled.
     34 *
     35 * This macro copies a single simple variable from user space to kernel
     36 * space.  It supports simple types like char and int, but not larger
     37 * data types like structures or arrays.
     38 *
     39 * @ptr must have pointer-to-simple-variable type, and the result of
     40 * dereferencing @ptr must be assignable to @x without a cast.
     41 *
     42 * Returns zero on success, or -EFAULT on error.
     43 * On error, the variable @x is set to zero.
     44 */
     45#define get_user(x, ptr) \
     46({									\
     47	const __typeof__(*(ptr)) __user *__p = (ptr);			\
     48									\
     49	might_fault();							\
     50	access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) :		\
     51				       ((x) = 0, -EFAULT);		\
     52})
     53
     54/*
     55 * put_user: - Write a simple value into user space.
     56 * @x:	 Value to copy to user space.
     57 * @ptr: Destination address, in user space.
     58 *
     59 * Context: User context only. This function may sleep if pagefaults are
     60 *          enabled.
     61 *
     62 * This macro copies a single simple value from kernel space to user
     63 * space.  It supports simple types like char and int, but not larger
     64 * data types like structures or arrays.
     65 *
     66 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
     67 * to the result of dereferencing @ptr.
     68 *
     69 * Returns zero on success, or -EFAULT on error.
     70 */
     71#define put_user(x, ptr) \
     72({									\
     73	__typeof__(*(ptr)) __user *__p = (ptr);				\
     74									\
     75	might_fault();							\
     76	access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT;	\
     77})
     78
     79/*
     80 * __get_user: - Get a simple variable from user space, with less checking.
     81 * @x:	 Variable to store result.
     82 * @ptr: Source address, in user space.
     83 *
     84 * Context: User context only. This function may sleep if pagefaults are
     85 *          enabled.
     86 *
     87 * This macro copies a single simple variable from user space to kernel
     88 * space.  It supports simple types like char and int, but not larger
     89 * data types like structures or arrays.
     90 *
     91 * @ptr must have pointer-to-simple-variable type, and the result of
     92 * dereferencing @ptr must be assignable to @x without a cast.
     93 *
     94 * Caller must check the pointer with access_ok() before calling this
     95 * function.
     96 *
     97 * Returns zero on success, or -EFAULT on error.
     98 * On error, the variable @x is set to zero.
     99 */
    100#define __get_user(x, ptr) \
    101({									\
    102	int __gu_err = 0;						\
    103									\
    104	__chk_user_ptr(ptr);						\
    105	__get_user_common((x), sizeof(*(ptr)), ptr);			\
    106	__gu_err;							\
    107})
    108
    109/*
    110 * __put_user: - Write a simple value into user space, with less checking.
    111 * @x:	 Value to copy to user space.
    112 * @ptr: Destination address, in user space.
    113 *
    114 * Context: User context only. This function may sleep if pagefaults are
    115 *          enabled.
    116 *
    117 * This macro copies a single simple value from kernel space to user
    118 * space.  It supports simple types like char and int, but not larger
    119 * data types like structures or arrays.
    120 *
    121 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
    122 * to the result of dereferencing @ptr.
    123 *
    124 * Caller must check the pointer with access_ok() before calling this
    125 * function.
    126 *
    127 * Returns zero on success, or -EFAULT on error.
    128 */
    129#define __put_user(x, ptr) \
    130({									\
    131	int __pu_err = 0;						\
    132	__typeof__(*(ptr)) __pu_val;					\
    133									\
    134	__pu_val = (x);							\
    135	__chk_user_ptr(ptr);						\
    136	__put_user_common(ptr, sizeof(*(ptr)));				\
    137	__pu_err;							\
    138})
    139
    140struct __large_struct { unsigned long buf[100]; };
    141#define __m(x) (*(struct __large_struct __user *)(x))
    142
    143#define __get_user_common(val, size, ptr)				\
    144do {									\
    145	switch (size) {							\
    146	case 1: __get_data_asm(val, "ld.b", ptr); break;		\
    147	case 2: __get_data_asm(val, "ld.h", ptr); break;		\
    148	case 4: __get_data_asm(val, "ld.w", ptr); break;		\
    149	case 8: __get_data_asm(val, "ld.d", ptr); break;		\
    150	default: BUILD_BUG(); break;					\
    151	}								\
    152} while (0)
    153
    154#define __get_kernel_common(val, size, ptr) __get_user_common(val, size, ptr)
    155
    156#define __get_data_asm(val, insn, ptr)					\
    157{									\
    158	long __gu_tmp;							\
    159									\
    160	__asm__ __volatile__(						\
    161	"1:	" insn "	%1, %2				\n"	\
    162	"2:							\n"	\
    163	"	.section .fixup,\"ax\"				\n"	\
    164	"3:	li.w	%0, %3					\n"	\
    165	"	or	%1, $r0, $r0				\n"	\
    166	"	b	2b					\n"	\
    167	"	.previous					\n"	\
    168	"	.section __ex_table,\"a\"			\n"	\
    169	"	"__UA_ADDR "\t1b, 3b				\n"	\
    170	"	.previous					\n"	\
    171	: "+r" (__gu_err), "=r" (__gu_tmp)				\
    172	: "m" (__m(ptr)), "i" (-EFAULT));				\
    173									\
    174	(val) = (__typeof__(*(ptr))) __gu_tmp;				\
    175}
    176
    177#define __put_user_common(ptr, size)					\
    178do {									\
    179	switch (size) {							\
    180	case 1: __put_data_asm("st.b", ptr); break;			\
    181	case 2: __put_data_asm("st.h", ptr); break;			\
    182	case 4: __put_data_asm("st.w", ptr); break;			\
    183	case 8: __put_data_asm("st.d", ptr); break;			\
    184	default: BUILD_BUG(); break;					\
    185	}								\
    186} while (0)
    187
    188#define __put_kernel_common(ptr, size) __put_user_common(ptr, size)
    189
    190#define __put_data_asm(insn, ptr)					\
    191{									\
    192	__asm__ __volatile__(						\
    193	"1:	" insn "	%z2, %1		# __put_user_asm\n"	\
    194	"2:							\n"	\
    195	"	.section	.fixup,\"ax\"			\n"	\
    196	"3:	li.w	%0, %3					\n"	\
    197	"	b	2b					\n"	\
    198	"	.previous					\n"	\
    199	"	.section	__ex_table,\"a\"		\n"	\
    200	"	" __UA_ADDR "	1b, 3b				\n"	\
    201	"	.previous					\n"	\
    202	: "+r" (__pu_err), "=m" (__m(ptr))				\
    203	: "Jr" (__pu_val), "i" (-EFAULT));				\
    204}
    205
    206#define __get_kernel_nofault(dst, src, type, err_label)			\
    207do {									\
    208	int __gu_err = 0;						\
    209									\
    210	__get_kernel_common(*((type *)(dst)), sizeof(type),		\
    211			    (__force type *)(src));			\
    212	if (unlikely(__gu_err))						\
    213		goto err_label;						\
    214} while (0)
    215
    216#define __put_kernel_nofault(dst, src, type, err_label)			\
    217do {									\
    218	type __pu_val;							\
    219	int __pu_err = 0;						\
    220									\
    221	__pu_val = *(__force type *)(src);				\
    222	__put_kernel_common(((type *)(dst)), sizeof(type));		\
    223	if (unlikely(__pu_err))						\
    224		goto err_label;						\
    225} while (0)
    226
    227extern unsigned long __copy_user(void *to, const void *from, __kernel_size_t n);
    228
    229static inline unsigned long __must_check
    230raw_copy_from_user(void *to, const void __user *from, unsigned long n)
    231{
    232	return __copy_user(to, from, n);
    233}
    234
    235static inline unsigned long __must_check
    236raw_copy_to_user(void __user *to, const void *from, unsigned long n)
    237{
    238	return __copy_user(to, from, n);
    239}
    240
    241#define INLINE_COPY_FROM_USER
    242#define INLINE_COPY_TO_USER
    243
    244/*
    245 * __clear_user: - Zero a block of memory in user space, with less checking.
    246 * @addr: Destination address, in user space.
    247 * @size: Number of bytes to zero.
    248 *
    249 * Zero a block of memory in user space.  Caller must check
    250 * the specified block with access_ok() before calling this function.
    251 *
    252 * Returns number of bytes that could not be cleared.
    253 * On success, this will be zero.
    254 */
    255extern unsigned long __clear_user(void __user *addr, __kernel_size_t size);
    256
    257#define clear_user(addr, n)						\
    258({									\
    259	void __user *__cl_addr = (addr);				\
    260	unsigned long __cl_size = (n);					\
    261	if (__cl_size && access_ok(__cl_addr, __cl_size))		\
    262		__cl_size = __clear_user(__cl_addr, __cl_size);		\
    263	__cl_size;							\
    264})
    265
    266extern long strncpy_from_user(char *to, const char __user *from, long n);
    267extern long strnlen_user(const char __user *str, long n);
    268
    269#endif /* _ASM_UACCESS_H */