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 (15028B)


      1/*
      2 * This file is subject to the terms and conditions of the GNU General Public
      3 * License.  See the file "COPYING" in the main directory of this archive
      4 * for more details.
      5 *
      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 <asm/asm-eva.h>
     17#include <asm/extable.h>
     18
     19#ifdef CONFIG_32BIT
     20
     21#define __UA_LIMIT 0x80000000UL
     22#define TASK_SIZE_MAX	KSEG0
     23
     24#define __UA_ADDR	".word"
     25#define __UA_LA		"la"
     26#define __UA_ADDU	"addu"
     27#define __UA_t0		"$8"
     28#define __UA_t1		"$9"
     29
     30#endif /* CONFIG_32BIT */
     31
     32#ifdef CONFIG_64BIT
     33
     34extern u64 __ua_limit;
     35
     36#define __UA_LIMIT	__ua_limit
     37#define TASK_SIZE_MAX	XKSSEG
     38
     39#define __UA_ADDR	".dword"
     40#define __UA_LA		"dla"
     41#define __UA_ADDU	"daddu"
     42#define __UA_t0		"$12"
     43#define __UA_t1		"$13"
     44
     45#endif /* CONFIG_64BIT */
     46
     47#include <asm-generic/access_ok.h>
     48
     49/*
     50 * put_user: - Write a simple value into user space.
     51 * @x:	 Value to copy to user space.
     52 * @ptr: Destination address, in user space.
     53 *
     54 * Context: User context only. This function may sleep if pagefaults are
     55 *          enabled.
     56 *
     57 * This macro copies a single simple value from kernel space to user
     58 * space.  It supports simple types like char and int, but not larger
     59 * data types like structures or arrays.
     60 *
     61 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
     62 * to the result of dereferencing @ptr.
     63 *
     64 * Returns zero on success, or -EFAULT on error.
     65 */
     66#define put_user(x, ptr)						\
     67({									\
     68	__typeof__(*(ptr)) __user *__p = (ptr);				\
     69									\
     70	might_fault();							\
     71	access_ok(__p, sizeof(*__p)) ? __put_user((x), __p) : -EFAULT;	\
     72})
     73
     74/*
     75 * get_user: - Get a simple variable from user space.
     76 * @x:	 Variable to store result.
     77 * @ptr: Source address, in user space.
     78 *
     79 * Context: User context only. This function may sleep if pagefaults are
     80 *          enabled.
     81 *
     82 * This macro copies a single simple variable from user space to kernel
     83 * space.  It supports simple types like char and int, but not larger
     84 * data types like structures or arrays.
     85 *
     86 * @ptr must have pointer-to-simple-variable type, and the result of
     87 * dereferencing @ptr must be assignable to @x without a cast.
     88 *
     89 * Returns zero on success, or -EFAULT on error.
     90 * On error, the variable @x is set to zero.
     91 */
     92#define get_user(x, ptr)						\
     93({									\
     94	const __typeof__(*(ptr)) __user *__p = (ptr);			\
     95									\
     96	might_fault();							\
     97	access_ok(__p, sizeof(*__p)) ? __get_user((x), __p) :		\
     98				       ((x) = 0, -EFAULT);		\
     99})
    100
    101/*
    102 * __put_user: - Write a simple value into user space, with less checking.
    103 * @x:	 Value to copy to user space.
    104 * @ptr: Destination address, in user space.
    105 *
    106 * Context: User context only. This function may sleep if pagefaults are
    107 *          enabled.
    108 *
    109 * This macro copies a single simple value from kernel space to user
    110 * space.  It supports simple types like char and int, but not larger
    111 * data types like structures or arrays.
    112 *
    113 * @ptr must have pointer-to-simple-variable type, and @x must be assignable
    114 * to the result of dereferencing @ptr.
    115 *
    116 * Caller must check the pointer with access_ok() before calling this
    117 * function.
    118 *
    119 * Returns zero on success, or -EFAULT on error.
    120 */
    121#define __put_user(x, ptr)						\
    122({									\
    123	__typeof__(*(ptr)) __user *__pu_ptr = (ptr);			\
    124	__typeof__(*(ptr)) __pu_val = (x);				\
    125	int __pu_err = 0;						\
    126									\
    127	__chk_user_ptr(__pu_ptr);					\
    128	switch (sizeof(*__pu_ptr)) {					\
    129	case 1:								\
    130		__put_data_asm(user_sb, __pu_ptr);			\
    131		break;							\
    132	case 2:								\
    133		__put_data_asm(user_sh, __pu_ptr);			\
    134		break;							\
    135	case 4:								\
    136		__put_data_asm(user_sw, __pu_ptr);			\
    137		break;							\
    138	case 8:								\
    139		__PUT_DW(user_sd, __pu_ptr);				\
    140		break;							\
    141	default:							\
    142		BUILD_BUG();						\
    143	}								\
    144									\
    145	__pu_err;							\
    146})
    147
    148/*
    149 * __get_user: - Get a simple variable from user space, with less checking.
    150 * @x:	 Variable to store result.
    151 * @ptr: Source address, in user space.
    152 *
    153 * Context: User context only. This function may sleep if pagefaults are
    154 *          enabled.
    155 *
    156 * This macro copies a single simple variable from user space to kernel
    157 * space.  It supports simple types like char and int, but not larger
    158 * data types like structures or arrays.
    159 *
    160 * @ptr must have pointer-to-simple-variable type, and the result of
    161 * dereferencing @ptr must be assignable to @x without a cast.
    162 *
    163 * Caller must check the pointer with access_ok() before calling this
    164 * function.
    165 *
    166 * Returns zero on success, or -EFAULT on error.
    167 * On error, the variable @x is set to zero.
    168 */
    169#define __get_user(x, ptr)						\
    170({									\
    171	const __typeof__(*(ptr)) __user *__gu_ptr = (ptr);		\
    172	int __gu_err = 0;						\
    173									\
    174	__chk_user_ptr(__gu_ptr);					\
    175	switch (sizeof(*__gu_ptr)) {					\
    176	case 1:								\
    177		__get_data_asm((x), user_lb, __gu_ptr);			\
    178		break;							\
    179	case 2:								\
    180		__get_data_asm((x), user_lh, __gu_ptr);			\
    181		break;							\
    182	case 4:								\
    183		__get_data_asm((x), user_lw, __gu_ptr);			\
    184		break;							\
    185	case 8:								\
    186		__GET_DW((x), user_ld, __gu_ptr);			\
    187		break;							\
    188	default:							\
    189		BUILD_BUG();						\
    190	}								\
    191									\
    192	__gu_err;							\
    193})
    194
    195struct __large_struct { unsigned long buf[100]; };
    196#define __m(x) (*(struct __large_struct __user *)(x))
    197
    198#ifdef CONFIG_32BIT
    199#define __GET_DW(val, insn, ptr) __get_data_asm_ll32(val, insn, ptr)
    200#endif
    201#ifdef CONFIG_64BIT
    202#define __GET_DW(val, insn, ptr) __get_data_asm(val, insn, ptr)
    203#endif
    204
    205#define __get_data_asm(val, insn, addr)					\
    206{									\
    207	long __gu_tmp;							\
    208									\
    209	__asm__ __volatile__(						\
    210	"1:	"insn("%1", "%3")"				\n"	\
    211	"2:							\n"	\
    212	"	.insn						\n"	\
    213	"	.section .fixup,\"ax\"				\n"	\
    214	"3:	li	%0, %4					\n"	\
    215	"	move	%1, $0					\n"	\
    216	"	j	2b					\n"	\
    217	"	.previous					\n"	\
    218	"	.section __ex_table,\"a\"			\n"	\
    219	"	"__UA_ADDR "\t1b, 3b				\n"	\
    220	"	.previous					\n"	\
    221	: "=r" (__gu_err), "=r" (__gu_tmp)				\
    222	: "0" (0), "o" (__m(addr)), "i" (-EFAULT));			\
    223									\
    224	(val) = (__typeof__(*(addr))) __gu_tmp;				\
    225}
    226
    227/*
    228 * Get a long long 64 using 32 bit registers.
    229 */
    230#define __get_data_asm_ll32(val, insn, addr)				\
    231{									\
    232	union {								\
    233		unsigned long long	l;				\
    234		__typeof__(*(addr))	t;				\
    235	} __gu_tmp;							\
    236									\
    237	__asm__ __volatile__(						\
    238	"1:	" insn("%1", "(%3)")"				\n"	\
    239	"2:	" insn("%D1", "4(%3)")"				\n"	\
    240	"3:							\n"	\
    241	"	.insn						\n"	\
    242	"	.section	.fixup,\"ax\"			\n"	\
    243	"4:	li	%0, %4					\n"	\
    244	"	move	%1, $0					\n"	\
    245	"	move	%D1, $0					\n"	\
    246	"	j	3b					\n"	\
    247	"	.previous					\n"	\
    248	"	.section	__ex_table,\"a\"		\n"	\
    249	"	" __UA_ADDR "	1b, 4b				\n"	\
    250	"	" __UA_ADDR "	2b, 4b				\n"	\
    251	"	.previous					\n"	\
    252	: "=r" (__gu_err), "=&r" (__gu_tmp.l)				\
    253	: "0" (0), "r" (addr), "i" (-EFAULT));				\
    254									\
    255	(val) = __gu_tmp.t;						\
    256}
    257
    258#define __get_kernel_nofault(dst, src, type, err_label)			\
    259do {									\
    260	int __gu_err;							\
    261									\
    262	switch (sizeof(type)) {						\
    263	case 1:								\
    264		__get_data_asm(*(type *)(dst), kernel_lb,		\
    265			       (__force type *)(src));			\
    266		break;							\
    267	case 2:								\
    268		__get_data_asm(*(type *)(dst), kernel_lh,		\
    269			       (__force type *)(src));			\
    270		break;							\
    271	case 4:								\
    272		 __get_data_asm(*(type *)(dst), kernel_lw,		\
    273			       (__force type *)(src));			\
    274		break;							\
    275	case 8:								\
    276		__GET_DW(*(type *)(dst), kernel_ld,			\
    277			 (__force type *)(src));			\
    278		break;							\
    279	default:							\
    280		BUILD_BUG();						\
    281		break;							\
    282	}								\
    283	if (unlikely(__gu_err))						\
    284		goto err_label;						\
    285} while (0)
    286
    287/*
    288 * Yuck.  We need two variants, one for 64bit operation and one
    289 * for 32 bit mode and old iron.
    290 */
    291#ifdef CONFIG_32BIT
    292#define __PUT_DW(insn, ptr) __put_data_asm_ll32(insn, ptr)
    293#endif
    294#ifdef CONFIG_64BIT
    295#define __PUT_DW(insn, ptr) __put_data_asm(insn, ptr)
    296#endif
    297
    298#define __put_data_asm(insn, ptr)					\
    299{									\
    300	__asm__ __volatile__(						\
    301	"1:	"insn("%z2", "%3")"	# __put_data_asm	\n"	\
    302	"2:							\n"	\
    303	"	.insn						\n"	\
    304	"	.section	.fixup,\"ax\"			\n"	\
    305	"3:	li	%0, %4					\n"	\
    306	"	j	2b					\n"	\
    307	"	.previous					\n"	\
    308	"	.section	__ex_table,\"a\"		\n"	\
    309	"	" __UA_ADDR "	1b, 3b				\n"	\
    310	"	.previous					\n"	\
    311	: "=r" (__pu_err)						\
    312	: "0" (0), "Jr" (__pu_val), "o" (__m(ptr)),			\
    313	  "i" (-EFAULT));						\
    314}
    315
    316#define __put_data_asm_ll32(insn, ptr)					\
    317{									\
    318	__asm__ __volatile__(						\
    319	"1:	"insn("%2", "(%3)")"	# __put_data_asm_ll32	\n"	\
    320	"2:	"insn("%D2", "4(%3)")"				\n"	\
    321	"3:							\n"	\
    322	"	.insn						\n"	\
    323	"	.section	.fixup,\"ax\"			\n"	\
    324	"4:	li	%0, %4					\n"	\
    325	"	j	3b					\n"	\
    326	"	.previous					\n"	\
    327	"	.section	__ex_table,\"a\"		\n"	\
    328	"	" __UA_ADDR "	1b, 4b				\n"	\
    329	"	" __UA_ADDR "	2b, 4b				\n"	\
    330	"	.previous"						\
    331	: "=r" (__pu_err)						\
    332	: "0" (0), "r" (__pu_val), "r" (ptr),				\
    333	  "i" (-EFAULT));						\
    334}
    335
    336#define __put_kernel_nofault(dst, src, type, err_label)			\
    337do {									\
    338	type __pu_val;					\
    339	int __pu_err = 0;						\
    340									\
    341	__pu_val = *(__force type *)(src);				\
    342	switch (sizeof(type)) {						\
    343	case 1:								\
    344		__put_data_asm(kernel_sb, (type *)(dst));		\
    345		break;							\
    346	case 2:								\
    347		__put_data_asm(kernel_sh, (type *)(dst));		\
    348		break;							\
    349	case 4:								\
    350		__put_data_asm(kernel_sw, (type *)(dst))		\
    351		break;							\
    352	case 8:								\
    353		__PUT_DW(kernel_sd, (type *)(dst));			\
    354		break;							\
    355	default:							\
    356		BUILD_BUG();						\
    357		break;							\
    358	}								\
    359	if (unlikely(__pu_err))						\
    360		goto err_label;						\
    361} while (0)
    362
    363
    364/*
    365 * We're generating jump to subroutines which will be outside the range of
    366 * jump instructions
    367 */
    368#ifdef MODULE
    369#define __MODULE_JAL(destination)					\
    370	".set\tnoat\n\t"						\
    371	__UA_LA "\t$1, " #destination "\n\t"				\
    372	"jalr\t$1\n\t"							\
    373	".set\tat\n\t"
    374#else
    375#define __MODULE_JAL(destination)					\
    376	"jal\t" #destination "\n\t"
    377#endif
    378
    379#if defined(CONFIG_CPU_DADDI_WORKAROUNDS) || (defined(CONFIG_EVA) &&	\
    380					      defined(CONFIG_CPU_HAS_PREFETCH))
    381#define DADDI_SCRATCH "$3"
    382#else
    383#define DADDI_SCRATCH "$0"
    384#endif
    385
    386extern size_t __raw_copy_from_user(void *__to, const void *__from, size_t __n);
    387extern size_t __raw_copy_to_user(void *__to, const void *__from, size_t __n);
    388
    389static inline unsigned long
    390raw_copy_from_user(void *to, const void __user *from, unsigned long n)
    391{
    392	register void *__cu_to_r __asm__("$4");
    393	register const void __user *__cu_from_r __asm__("$5");
    394	register long __cu_len_r __asm__("$6");
    395
    396	__cu_to_r = to;
    397	__cu_from_r = from;
    398	__cu_len_r = n;
    399
    400	__asm__ __volatile__(
    401		".set\tnoreorder\n\t"
    402		__MODULE_JAL(__raw_copy_from_user)
    403		".set\tnoat\n\t"
    404		__UA_ADDU "\t$1, %1, %2\n\t"
    405		".set\tat\n\t"
    406		".set\treorder"
    407		: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
    408		:
    409		: "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
    410		  DADDI_SCRATCH, "memory");
    411
    412	return __cu_len_r;
    413}
    414
    415static inline unsigned long
    416raw_copy_to_user(void __user *to, const void *from, unsigned long n)
    417{
    418	register void __user *__cu_to_r __asm__("$4");
    419	register const void *__cu_from_r __asm__("$5");
    420	register long __cu_len_r __asm__("$6");
    421
    422	__cu_to_r = (to);
    423	__cu_from_r = (from);
    424	__cu_len_r = (n);
    425
    426	__asm__ __volatile__(
    427		__MODULE_JAL(__raw_copy_to_user)
    428		: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r)
    429		:
    430		: "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31",
    431		  DADDI_SCRATCH, "memory");
    432
    433	return __cu_len_r;
    434}
    435
    436#define INLINE_COPY_FROM_USER
    437#define INLINE_COPY_TO_USER
    438
    439extern __kernel_size_t __bzero(void __user *addr, __kernel_size_t size);
    440
    441/*
    442 * __clear_user: - Zero a block of memory in user space, with less checking.
    443 * @to:	  Destination address, in user space.
    444 * @n:	  Number of bytes to zero.
    445 *
    446 * Zero a block of memory in user space.  Caller must check
    447 * the specified block with access_ok() before calling this function.
    448 *
    449 * Returns number of bytes that could not be cleared.
    450 * On success, this will be zero.
    451 */
    452static inline __kernel_size_t
    453__clear_user(void __user *addr, __kernel_size_t size)
    454{
    455	__kernel_size_t res;
    456
    457#ifdef CONFIG_CPU_MICROMIPS
    458/* micromips memset / bzero also clobbers t7 & t8 */
    459#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$15", "$24", "$31"
    460#else
    461#define bzero_clobbers "$4", "$5", "$6", __UA_t0, __UA_t1, "$31"
    462#endif /* CONFIG_CPU_MICROMIPS */
    463
    464	might_fault();
    465	__asm__ __volatile__(
    466		"move\t$4, %1\n\t"
    467		"move\t$5, $0\n\t"
    468		"move\t$6, %2\n\t"
    469		__MODULE_JAL(__bzero)
    470		"move\t%0, $6"
    471		: "=r" (res)
    472		: "r" (addr), "r" (size)
    473		: bzero_clobbers);
    474
    475	return res;
    476}
    477
    478#define clear_user(addr,n)						\
    479({									\
    480	void __user * __cl_addr = (addr);				\
    481	unsigned long __cl_size = (n);					\
    482	if (__cl_size && access_ok(__cl_addr, __cl_size))		\
    483		__cl_size = __clear_user(__cl_addr, __cl_size);		\
    484	__cl_size;							\
    485})
    486
    487extern long __strncpy_from_user_asm(char *__to, const char __user *__from, long __len);
    488
    489/*
    490 * strncpy_from_user: - Copy a NUL terminated string from userspace.
    491 * @dst:   Destination address, in kernel space.  This buffer must be at
    492 *	   least @count bytes long.
    493 * @src:   Source address, in user space.
    494 * @count: Maximum number of bytes to copy, including the trailing NUL.
    495 *
    496 * Copies a NUL-terminated string from userspace to kernel space.
    497 *
    498 * On success, returns the length of the string (not including the trailing
    499 * NUL).
    500 *
    501 * If access to userspace fails, returns -EFAULT (some data may have been
    502 * copied).
    503 *
    504 * If @count is smaller than the length of the string, copies @count bytes
    505 * and returns @count.
    506 */
    507static inline long
    508strncpy_from_user(char *__to, const char __user *__from, long __len)
    509{
    510	long res;
    511
    512	if (!access_ok(__from, __len))
    513		return -EFAULT;
    514
    515	might_fault();
    516	__asm__ __volatile__(
    517		"move\t$4, %1\n\t"
    518		"move\t$5, %2\n\t"
    519		"move\t$6, %3\n\t"
    520		__MODULE_JAL(__strncpy_from_user_asm)
    521		"move\t%0, $2"
    522		: "=r" (res)
    523		: "r" (__to), "r" (__from), "r" (__len)
    524		: "$2", "$3", "$4", "$5", "$6", __UA_t0, "$31", "memory");
    525
    526	return res;
    527}
    528
    529extern long __strnlen_user_asm(const char __user *s, long n);
    530
    531/*
    532 * strnlen_user: - Get the size of a string in user space.
    533 * @str: The string to measure.
    534 *
    535 * Context: User context only. This function may sleep if pagefaults are
    536 *          enabled.
    537 *
    538 * Get the size of a NUL-terminated string in user space.
    539 *
    540 * Returns the size of the string INCLUDING the terminating NUL.
    541 * On exception, returns 0.
    542 * If the string is too long, returns a value greater than @n.
    543 */
    544static inline long strnlen_user(const char __user *s, long n)
    545{
    546	long res;
    547
    548	if (!access_ok(s, 1))
    549		return 0;
    550
    551	might_fault();
    552	__asm__ __volatile__(
    553		"move\t$4, %1\n\t"
    554		"move\t$5, %2\n\t"
    555		__MODULE_JAL(__strnlen_user_asm)
    556		"move\t%0, $2"
    557		: "=r" (res)
    558		: "r" (s), "r" (n)
    559		: "$2", "$4", "$5", __UA_t0, "$31");
    560
    561	return res;
    562}
    563
    564#endif /* _ASM_UACCESS_H */