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


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef __ASM_SH_UACCESS_H
      3#define __ASM_SH_UACCESS_H
      4
      5#include <asm/extable.h>
      6#include <asm-generic/access_ok.h>
      7
      8/*
      9 * Uh, these should become the main single-value transfer routines ...
     10 * They automatically use the right size if we just have the right
     11 * pointer type ...
     12 *
     13 * As SuperH uses the same address space for kernel and user data, we
     14 * can just do these as direct assignments.
     15 *
     16 * Careful to not
     17 * (a) re-use the arguments for side effects (sizeof is ok)
     18 * (b) require any knowledge of processes at this stage
     19 */
     20#define put_user(x,ptr)		__put_user_check((x), (ptr), sizeof(*(ptr)))
     21#define get_user(x,ptr)		__get_user_check((x), (ptr), sizeof(*(ptr)))
     22
     23/*
     24 * The "__xxx" versions do not do address space checking, useful when
     25 * doing multiple accesses to the same area (the user has to do the
     26 * checks by hand with "access_ok()")
     27 */
     28#define __put_user(x,ptr)	__put_user_nocheck((x), (ptr), sizeof(*(ptr)))
     29#define __get_user(x,ptr)	__get_user_nocheck((x), (ptr), sizeof(*(ptr)))
     30
     31struct __large_struct { unsigned long buf[100]; };
     32#define __m(x) (*(struct __large_struct __user *)(x))
     33
     34#define __get_user_nocheck(x,ptr,size)				\
     35({								\
     36	long __gu_err;						\
     37	unsigned long __gu_val;					\
     38	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);	\
     39	__chk_user_ptr(ptr);					\
     40	__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
     41	(x) = (__force __typeof__(*(ptr)))__gu_val;		\
     42	__gu_err;						\
     43})
     44
     45#define __get_user_check(x,ptr,size)					\
     46({									\
     47	long __gu_err = -EFAULT;					\
     48	unsigned long __gu_val = 0;					\
     49	const __typeof__(*(ptr)) __user *__gu_addr = (ptr);			\
     50	if (likely(access_ok(__gu_addr, (size))))		\
     51		__get_user_size(__gu_val, __gu_addr, (size), __gu_err);	\
     52	(x) = (__force __typeof__(*(ptr)))__gu_val;			\
     53	__gu_err;							\
     54})
     55
     56#define __put_user_nocheck(x,ptr,size)				\
     57({								\
     58	long __pu_err;						\
     59	__typeof__(*(ptr)) __user *__pu_addr = (ptr);		\
     60	__typeof__(*(ptr)) __pu_val = x;			\
     61	__chk_user_ptr(ptr);					\
     62	__put_user_size(__pu_val, __pu_addr, (size), __pu_err);	\
     63	__pu_err;						\
     64})
     65
     66#define __put_user_check(x,ptr,size)				\
     67({								\
     68	long __pu_err = -EFAULT;				\
     69	__typeof__(*(ptr)) __user *__pu_addr = (ptr);		\
     70	__typeof__(*(ptr)) __pu_val = x;			\
     71	if (likely(access_ok(__pu_addr, size)))	\
     72		__put_user_size(__pu_val, __pu_addr, (size),	\
     73				__pu_err);			\
     74	__pu_err;						\
     75})
     76
     77# include <asm/uaccess_32.h>
     78
     79extern long strncpy_from_user(char *dest, const char __user *src, long count);
     80
     81extern __must_check long strnlen_user(const char __user *str, long n);
     82
     83/* Generic arbitrary sized copy.  */
     84/* Return the number of bytes NOT copied */
     85__kernel_size_t __copy_user(void *to, const void *from, __kernel_size_t n);
     86
     87static __always_inline unsigned long
     88raw_copy_from_user(void *to, const void __user *from, unsigned long n)
     89{
     90	return __copy_user(to, (__force void *)from, n);
     91}
     92
     93static __always_inline unsigned long __must_check
     94raw_copy_to_user(void __user *to, const void *from, unsigned long n)
     95{
     96	return __copy_user((__force void *)to, from, n);
     97}
     98#define INLINE_COPY_FROM_USER
     99#define INLINE_COPY_TO_USER
    100
    101/*
    102 * Clear the area and return remaining number of bytes
    103 * (on failure.  Usually it's 0.)
    104 */
    105__kernel_size_t __clear_user(void __user *addr, __kernel_size_t size);
    106
    107#define clear_user(addr,n)						\
    108({									\
    109	void __user * __cl_addr = (addr);				\
    110	unsigned long __cl_size = (n);					\
    111									\
    112	if (__cl_size && access_ok(__cl_addr, __cl_size))		\
    113		__cl_size = __clear_user(__cl_addr, __cl_size);		\
    114									\
    115	__cl_size;							\
    116})
    117
    118extern void *set_exception_table_vec(unsigned int vec, void *handler);
    119
    120static inline void *set_exception_table_evt(unsigned int evt, void *handler)
    121{
    122	return set_exception_table_vec(evt >> 5, handler);
    123}
    124
    125struct mem_access {
    126	unsigned long (*from)(void *dst, const void __user *src, unsigned long cnt);
    127	unsigned long (*to)(void __user *dst, const void *src, unsigned long cnt);
    128};
    129
    130int handle_unaligned_access(insn_size_t instruction, struct pt_regs *regs,
    131			    struct mem_access *ma, int, unsigned long address);
    132
    133#endif /* __ASM_SH_UACCESS_H */