LCOV - code coverage report
Current view: top level - lkbce/arch/x86/include/asm - uaccess_64.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 8 10 80.0 %
Date: 2017-01-25 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #ifndef _ASM_X86_UACCESS_64_H
       2             : #define _ASM_X86_UACCESS_64_H
       3             : 
       4             : /*
       5             :  * User space memory access functions
       6             :  */
       7             : #include <linux/compiler.h>
       8             : #include <linux/errno.h>
       9             : #include <linux/prefetch.h>
      10             : #include <linux/lockdep.h>
      11             : #include <asm/page.h>
      12             : 
      13             : /*
      14             :  * Copy To/From Userspace
      15             :  */
      16             : 
      17             : /* Handles exceptions in both to and from, but doesn't do access_ok */
      18             : __must_check unsigned long
      19             : copy_user_generic(void *to, const void *from, unsigned len);
      20             : 
      21             : __must_check unsigned long
      22             : _copy_to_user(void __user *to, const void *from, unsigned len);
      23             : __must_check unsigned long
      24             : _copy_from_user(void *to, const void __user *from, unsigned len);
      25             : __must_check unsigned long
      26             : copy_in_user(void __user *to, const void __user *from, unsigned len);
      27             : 
      28             : static inline unsigned long __must_check copy_from_user(void *to,
      29             :                                           const void __user *from,
      30           2 :                                           unsigned long n)
      31           2 : {
      32           6 :         int sz = __compiletime_object_size(to);
      33           2 : 
      34           4 :         might_fault();
      35          16 :         if (likely(sz == -1 || sz >= n))
      36           4 :                 n = _copy_from_user(to, from, n);
      37             : #ifdef CONFIG_DEBUG_VM
      38             :         else
      39             :                 WARN(1, "Buffer overflow detected!\n");
      40             : #endif
      41           4 :         return n;
      42             : }
      43             : 
      44             : static __always_inline __must_check
      45             : int copy_to_user(void __user *dst, const void *src, unsigned size)
      46             : {
      47           0 :         might_fault();
      48             : 
      49           0 :         return _copy_to_user(dst, src, size);
      50             : }
      51             : 
      52             : static __always_inline __must_check
      53             : int __copy_from_user(void *dst, const void __user *src, unsigned size)
      54             : {
      55             :         int ret = 0;
      56             : 
      57             :         might_fault();
      58             :         if (!__builtin_constant_p(size))
      59             :                 return copy_user_generic(dst, (__force void *)src, size);
      60             :         switch (size) {
      61             :         case 1:__get_user_asm(*(u8 *)dst, (u8 __user *)src,
      62             :                               ret, "b", "b", "=q", 1);
      63             :                 return ret;
      64             :         case 2:__get_user_asm(*(u16 *)dst, (u16 __user *)src,
      65             :                               ret, "w", "w", "=r", 2);
      66             :                 return ret;
      67             :         case 4:__get_user_asm(*(u32 *)dst, (u32 __user *)src,
      68             :                               ret, "l", "k", "=r", 4);
      69             :                 return ret;
      70             :         case 8:__get_user_asm(*(u64 *)dst, (u64 __user *)src,
      71             :                               ret, "q", "", "=r", 8);
      72             :                 return ret;
      73             :         case 10:
      74             :                 __get_user_asm(*(u64 *)dst, (u64 __user *)src,
      75             :                                ret, "q", "", "=r", 10);
      76             :                 if (unlikely(ret))
      77             :                         return ret;
      78             :                 __get_user_asm(*(u16 *)(8 + (char *)dst),
      79             :                                (u16 __user *)(8 + (char __user *)src),
      80             :                                ret, "w", "w", "=r", 2);
      81             :                 return ret;
      82             :         case 16:
      83             :                 __get_user_asm(*(u64 *)dst, (u64 __user *)src,
      84             :                                ret, "q", "", "=r", 16);
      85             :                 if (unlikely(ret))
      86             :                         return ret;
      87             :                 __get_user_asm(*(u64 *)(8 + (char *)dst),
      88             :                                (u64 __user *)(8 + (char __user *)src),
      89             :                                ret, "q", "", "=r", 8);
      90             :                 return ret;
      91             :         default:
      92             :                 return copy_user_generic(dst, (__force void *)src, size);
      93             :         }
      94             : }
      95             : 
      96             : static __always_inline __must_check
      97             : int __copy_to_user(void __user *dst, const void *src, unsigned size)
      98             : {
      99             :         int ret = 0;
     100             : 
     101             :         might_fault();
     102             :         if (!__builtin_constant_p(size))
     103             :                 return copy_user_generic((__force void *)dst, src, size);
     104             :         switch (size) {
     105             :         case 1:__put_user_asm(*(u8 *)src, (u8 __user *)dst,
     106             :                               ret, "b", "b", "iq", 1);
     107             :                 return ret;
     108             :         case 2:__put_user_asm(*(u16 *)src, (u16 __user *)dst,
     109             :                               ret, "w", "w", "ir", 2);
     110             :                 return ret;
     111             :         case 4:__put_user_asm(*(u32 *)src, (u32 __user *)dst,
     112             :                               ret, "l", "k", "ir", 4);
     113             :                 return ret;
     114             :         case 8:__put_user_asm(*(u64 *)src, (u64 __user *)dst,
     115             :                               ret, "q", "", "er", 8);
     116             :                 return ret;
     117             :         case 10:
     118             :                 __put_user_asm(*(u64 *)src, (u64 __user *)dst,
     119             :                                ret, "q", "", "er", 10);
     120             :                 if (unlikely(ret))
     121             :                         return ret;
     122             :                 asm("":::"memory");
     123             :                 __put_user_asm(4[(u16 *)src], 4 + (u16 __user *)dst,
     124             :                                ret, "w", "w", "ir", 2);
     125             :                 return ret;
     126             :         case 16:
     127             :                 __put_user_asm(*(u64 *)src, (u64 __user *)dst,
     128             :                                ret, "q", "", "er", 16);
     129             :                 if (unlikely(ret))
     130             :                         return ret;
     131             :                 asm("":::"memory");
     132             :                 __put_user_asm(1[(u64 *)src], 1 + (u64 __user *)dst,
     133             :                                ret, "q", "", "er", 8);
     134             :                 return ret;
     135             :         default:
     136             :                 return copy_user_generic((__force void *)dst, src, size);
     137             :         }
     138             : }
     139             : 
     140             : static __always_inline __must_check
     141             : int __copy_in_user(void __user *dst, const void __user *src, unsigned size)
     142             : {
     143             :         int ret = 0;
     144             : 
     145             :         might_fault();
     146             :         if (!__builtin_constant_p(size))
     147             :                 return copy_user_generic((__force void *)dst,
     148             :                                          (__force void *)src, size);
     149             :         switch (size) {
     150             :         case 1: {
     151             :                 u8 tmp;
     152             :                 __get_user_asm(tmp, (u8 __user *)src,
     153             :                                ret, "b", "b", "=q", 1);
     154             :                 if (likely(!ret))
     155             :                         __put_user_asm(tmp, (u8 __user *)dst,
     156             :                                        ret, "b", "b", "iq", 1);
     157             :                 return ret;
     158             :         }
     159             :         case 2: {
     160             :                 u16 tmp;
     161             :                 __get_user_asm(tmp, (u16 __user *)src,
     162             :                                ret, "w", "w", "=r", 2);
     163             :                 if (likely(!ret))
     164             :                         __put_user_asm(tmp, (u16 __user *)dst,
     165             :                                        ret, "w", "w", "ir", 2);
     166             :                 return ret;
     167             :         }
     168             : 
     169             :         case 4: {
     170             :                 u32 tmp;
     171             :                 __get_user_asm(tmp, (u32 __user *)src,
     172             :                                ret, "l", "k", "=r", 4);
     173             :                 if (likely(!ret))
     174             :                         __put_user_asm(tmp, (u32 __user *)dst,
     175             :                                        ret, "l", "k", "ir", 4);
     176             :                 return ret;
     177             :         }
     178             :         case 8: {
     179             :                 u64 tmp;
     180             :                 __get_user_asm(tmp, (u64 __user *)src,
     181             :                                ret, "q", "", "=r", 8);
     182             :                 if (likely(!ret))
     183             :                         __put_user_asm(tmp, (u64 __user *)dst,
     184             :                                        ret, "q", "", "er", 8);
     185             :                 return ret;
     186             :         }
     187             :         default:
     188             :                 return copy_user_generic((__force void *)dst,
     189             :                                          (__force void *)src, size);
     190             :         }
     191             : }
     192             : 
     193             : __must_check long
     194             : strncpy_from_user(char *dst, const char __user *src, long count);
     195             : __must_check long
     196             : __strncpy_from_user(char *dst, const char __user *src, long count);
     197             : __must_check long strnlen_user(const char __user *str, long n);
     198             : __must_check long __strnlen_user(const char __user *str, long n);
     199             : __must_check long strlen_user(const char __user *str);
     200             : __must_check unsigned long clear_user(void __user *mem, unsigned long len);
     201             : __must_check unsigned long __clear_user(void __user *mem, unsigned long len);
     202             : 
     203             : static __must_check __always_inline int
     204             : __copy_from_user_inatomic(void *dst, const void __user *src, unsigned size)
     205             : {
     206             :         return copy_user_generic(dst, (__force const void *)src, size);
     207             : }
     208             : 
     209             : static __must_check __always_inline int
     210             : __copy_to_user_inatomic(void __user *dst, const void *src, unsigned size)
     211             : {
     212             :         return copy_user_generic((__force void *)dst, src, size);
     213             : }
     214             : 
     215             : extern long __copy_user_nocache(void *dst, const void __user *src,
     216             :                                 unsigned size, int zerorest);
     217             : 
     218             : static inline int
     219             : __copy_from_user_nocache(void *dst, const void __user *src, unsigned size)
     220             : {
     221             :         might_sleep();
     222             :         return __copy_user_nocache(dst, src, size, 1);
     223             : }
     224             : 
     225             : static inline int
     226             : __copy_from_user_inatomic_nocache(void *dst, const void __user *src,
     227             :                                   unsigned size)
     228             : {
     229             :         return __copy_user_nocache(dst, src, size, 0);
     230             : }
     231             : 
     232             : unsigned long
     233             : copy_user_handle_tail(char *to, char *from, unsigned len, unsigned zerorest);
     234             : 
     235             : #endif /* _ASM_X86_UACCESS_64_H */

Generated by: LCOV version 1.10