LCOV - code coverage report
Current view: top level - arch/arm/include/asm - uaccess.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 8 8 100.0 %
Date: 2014-02-18 Functions: 0 0 -
Branches: 58 199 29.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  *  arch/arm/include/asm/uaccess.h
       3                 :            :  *
       4                 :            :  * This program is free software; you can redistribute it and/or modify
       5                 :            :  * it under the terms of the GNU General Public License version 2 as
       6                 :            :  * published by the Free Software Foundation.
       7                 :            :  */
       8                 :            : #ifndef _ASMARM_UACCESS_H
       9                 :            : #define _ASMARM_UACCESS_H
      10                 :            : 
      11                 :            : /*
      12                 :            :  * User space memory access functions
      13                 :            :  */
      14                 :            : #include <linux/string.h>
      15                 :            : #include <linux/thread_info.h>
      16                 :            : #include <asm/errno.h>
      17                 :            : #include <asm/memory.h>
      18                 :            : #include <asm/domain.h>
      19                 :            : #include <asm/unified.h>
      20                 :            : #include <asm/compiler.h>
      21                 :            : 
      22                 :            : #if __LINUX_ARM_ARCH__ < 6
      23                 :            : #include <asm-generic/uaccess-unaligned.h>
      24                 :            : #else
      25                 :            : #define __get_user_unaligned __get_user
      26                 :            : #define __put_user_unaligned __put_user
      27                 :            : #endif
      28                 :            : 
      29                 :            : #define VERIFY_READ 0
      30                 :            : #define VERIFY_WRITE 1
      31                 :            : 
      32                 :            : /*
      33                 :            :  * The exception table consists of pairs of addresses: the first is the
      34                 :            :  * address of an instruction that is allowed to fault, and the second is
      35                 :            :  * the address at which the program should continue.  No registers are
      36                 :            :  * modified, so it is entirely up to the continuation code to figure out
      37                 :            :  * what to do.
      38                 :            :  *
      39                 :            :  * All the routines below use bits of fixup code that are out of line
      40                 :            :  * with the main instruction path.  This means when everything is well,
      41                 :            :  * we don't even have to jump over them.  Further, they do not intrude
      42                 :            :  * on our cache or tlb entries.
      43                 :            :  */
      44                 :            : 
      45                 :            : struct exception_table_entry
      46                 :            : {
      47                 :            :         unsigned long insn, fixup;
      48                 :            : };
      49                 :            : 
      50                 :            : extern int fixup_exception(struct pt_regs *regs);
      51                 :            : 
      52                 :            : /*
      53                 :            :  * These two are intentionally not defined anywhere - if the kernel
      54                 :            :  * code generates any references to them, that's a bug.
      55                 :            :  */
      56                 :            : extern int __get_user_bad(void);
      57                 :            : extern int __put_user_bad(void);
      58                 :            : 
      59                 :            : /*
      60                 :            :  * Note that this is actually 0x1,0000,0000
      61                 :            :  */
      62                 :            : #define KERNEL_DS       0x00000000
      63                 :            : #define get_ds()        (KERNEL_DS)
      64                 :            : 
      65                 :            : #ifdef CONFIG_MMU
      66                 :            : 
      67                 :            : #define USER_DS         TASK_SIZE
      68                 :            : #define get_fs()        (current_thread_info()->addr_limit)
      69                 :            : 
      70                 :            : static inline void set_fs(mm_segment_t fs)
      71                 :            : {
      72                 :    1928016 :         current_thread_info()->addr_limit = fs;
      73                 :            :         modify_domain(DOMAIN_KERNEL, fs ? DOMAIN_CLIENT : DOMAIN_MANAGER);
      74                 :            : }
      75                 :            : 
      76                 :            : #define segment_eq(a,b) ((a) == (b))
      77                 :            : 
      78                 :            : #define __addr_ok(addr) ({ \
      79                 :            :         unsigned long flag; \
      80                 :            :         __asm__("cmp %2, %0; movlo %0, #0" \
      81                 :            :                 : "=&r" (flag) \
      82                 :            :                 : "0" (current_thread_info()->addr_limit), "r" (addr) \
      83                 :            :                 : "cc"); \
      84                 :            :         (flag == 0); })
      85                 :            : 
      86                 :            : /* We use 33-bit arithmetic here... */
      87                 :            : #define __range_ok(addr,size) ({ \
      88                 :            :         unsigned long flag, roksum; \
      89                 :            :         __chk_user_ptr(addr);   \
      90                 :            :         __asm__("adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0" \
      91                 :            :                 : "=&r" (flag), "=&r" (roksum) \
      92                 :            :                 : "r" (addr), "Ir" (size), "0" (current_thread_info()->addr_limit) \
      93                 :            :                 : "cc"); \
      94                 :            :         flag; })
      95                 :            : 
      96                 :            : /*
      97                 :            :  * Single-value transfer routines.  They automatically use the right
      98                 :            :  * size if we just have the right pointer type.  Note that the functions
      99                 :            :  * which read from user space (*get_*) need to take care not to leak
     100                 :            :  * kernel data even if the calling code is buggy and fails to check
     101                 :            :  * the return value.  This means zeroing out the destination variable
     102                 :            :  * or buffer on error.  Normally this is done out of line by the
     103                 :            :  * fixup code, but there are a few places where it intrudes on the
     104                 :            :  * main code path.  When we only write to user space, there is no
     105                 :            :  * problem.
     106                 :            :  */
     107                 :            : extern int __get_user_1(void *);
     108                 :            : extern int __get_user_2(void *);
     109                 :            : extern int __get_user_4(void *);
     110                 :            : 
     111                 :            : #define __GUP_CLOBBER_1 "lr", "cc"
     112                 :            : #ifdef CONFIG_CPU_USE_DOMAINS
     113                 :            : #define __GUP_CLOBBER_2 "ip", "lr", "cc"
     114                 :            : #else
     115                 :            : #define __GUP_CLOBBER_2 "lr", "cc"
     116                 :            : #endif
     117                 :            : #define __GUP_CLOBBER_4 "lr", "cc"
     118                 :            : 
     119                 :            : #define __get_user_x(__r2,__p,__e,__l,__s)                              \
     120                 :            :            __asm__ __volatile__ (                                       \
     121                 :            :                 __asmeq("%0", "r0") __asmeq("%1", "r2")                 \
     122                 :            :                 __asmeq("%3", "r1")                                 \
     123                 :            :                 "bl        __get_user_" #__s                          \
     124                 :            :                 : "=&r" (__e), "=r" (__r2)                              \
     125                 :            :                 : "0" (__p), "r" (__l)                                      \
     126                 :            :                 : __GUP_CLOBBER_##__s)
     127                 :            : 
     128                 :            : #define __get_user_check(x,p)                                                   \
     129                 :            :         ({                                                              \
     130                 :            :                 unsigned long __limit = current_thread_info()->addr_limit - 1; \
     131                 :            :                 register const typeof(*(p)) __user *__p asm("r0") = (p);\
     132                 :            :                 register unsigned long __r2 asm("r2");                        \
     133                 :            :                 register unsigned long __l asm("r1") = __limit;               \
     134                 :            :                 register int __e asm("r0");                           \
     135                 :            :                 switch (sizeof(*(__p))) {                               \
     136                 :            :                 case 1:                                                 \
     137                 :            :                         __get_user_x(__r2, __p, __e, __l, 1);           \
     138                 :            :                         break;                                          \
     139                 :            :                 case 2:                                                 \
     140                 :            :                         __get_user_x(__r2, __p, __e, __l, 2);           \
     141                 :            :                         break;                                          \
     142                 :            :                 case 4:                                                 \
     143                 :            :                         __get_user_x(__r2, __p, __e, __l, 4);           \
     144                 :            :                         break;                                          \
     145                 :            :                 default: __e = __get_user_bad(); break;                 \
     146                 :            :                 }                                                       \
     147                 :            :                 x = (typeof(*(p))) __r2;                                \
     148                 :            :                 __e;                                                    \
     149                 :            :         })
     150                 :            : 
     151                 :            : #define get_user(x,p)                                                   \
     152                 :            :         ({                                                              \
     153                 :            :                 might_fault();                                          \
     154                 :            :                 __get_user_check(x,p);                                  \
     155                 :            :          })
     156                 :            : 
     157                 :            : extern int __put_user_1(void *, unsigned int);
     158                 :            : extern int __put_user_2(void *, unsigned int);
     159                 :            : extern int __put_user_4(void *, unsigned int);
     160                 :            : extern int __put_user_8(void *, unsigned long long);
     161                 :            : 
     162                 :            : #define __put_user_x(__r2,__p,__e,__l,__s)                              \
     163                 :            :            __asm__ __volatile__ (                                       \
     164                 :            :                 __asmeq("%0", "r0") __asmeq("%2", "r2")                 \
     165                 :            :                 __asmeq("%3", "r1")                                 \
     166                 :            :                 "bl        __put_user_" #__s                          \
     167                 :            :                 : "=&r" (__e)                                             \
     168                 :            :                 : "0" (__p), "r" (__r2), "r" (__l)                        \
     169                 :            :                 : "ip", "lr", "cc")
     170                 :            : 
     171                 :            : #define __put_user_check(x,p)                                                   \
     172                 :            :         ({                                                              \
     173                 :            :                 unsigned long __limit = current_thread_info()->addr_limit - 1; \
     174                 :            :                 register const typeof(*(p)) __r2 asm("r2") = (x);     \
     175                 :            :                 register const typeof(*(p)) __user *__p asm("r0") = (p);\
     176                 :            :                 register unsigned long __l asm("r1") = __limit;               \
     177                 :            :                 register int __e asm("r0");                           \
     178                 :            :                 switch (sizeof(*(__p))) {                               \
     179                 :            :                 case 1:                                                 \
     180                 :            :                         __put_user_x(__r2, __p, __e, __l, 1);           \
     181                 :            :                         break;                                          \
     182                 :            :                 case 2:                                                 \
     183                 :            :                         __put_user_x(__r2, __p, __e, __l, 2);           \
     184                 :            :                         break;                                          \
     185                 :            :                 case 4:                                                 \
     186                 :            :                         __put_user_x(__r2, __p, __e, __l, 4);           \
     187                 :            :                         break;                                          \
     188                 :            :                 case 8:                                                 \
     189                 :            :                         __put_user_x(__r2, __p, __e, __l, 8);           \
     190                 :            :                         break;                                          \
     191                 :            :                 default: __e = __put_user_bad(); break;                 \
     192                 :            :                 }                                                       \
     193                 :            :                 __e;                                                    \
     194                 :            :         })
     195                 :            : 
     196                 :            : #define put_user(x,p)                                                   \
     197                 :            :         ({                                                              \
     198                 :            :                 might_fault();                                          \
     199                 :            :                 __put_user_check(x,p);                                  \
     200                 :            :          })
     201                 :            : 
     202                 :            : #else /* CONFIG_MMU */
     203                 :            : 
     204                 :            : /*
     205                 :            :  * uClinux has only one addr space, so has simplified address limits.
     206                 :            :  */
     207                 :            : #define USER_DS                 KERNEL_DS
     208                 :            : 
     209                 :            : #define segment_eq(a,b)         (1)
     210                 :            : #define __addr_ok(addr)         ((void)(addr),1)
     211                 :            : #define __range_ok(addr,size)   ((void)(addr),0)
     212                 :            : #define get_fs()                (KERNEL_DS)
     213                 :            : 
     214                 :            : static inline void set_fs(mm_segment_t fs)
     215                 :            : {
     216                 :            : }
     217                 :            : 
     218                 :            : #define get_user(x,p)   __get_user(x,p)
     219                 :            : #define put_user(x,p)   __put_user(x,p)
     220                 :            : 
     221                 :            : #endif /* CONFIG_MMU */
     222                 :            : 
     223                 :            : #define access_ok(type,addr,size)       (__range_ok(addr,size) == 0)
     224                 :            : 
     225                 :            : #define user_addr_max() \
     226                 :            :         (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL)
     227                 :            : 
     228                 :            : /*
     229                 :            :  * The "__xxx" versions of the user access functions do not verify the
     230                 :            :  * address space - it must have been done previously with a separate
     231                 :            :  * "access_ok()" call.
     232                 :            :  *
     233                 :            :  * The "xxx_error" versions set the third argument to EFAULT if an
     234                 :            :  * error occurs, and leave it unchanged on success.  Note that these
     235                 :            :  * versions are void (ie, don't return a value as such).
     236                 :            :  */
     237                 :            : #define __get_user(x,ptr)                                               \
     238                 :            : ({                                                                      \
     239                 :            :         long __gu_err = 0;                                              \
     240                 :            :         __get_user_err((x),(ptr),__gu_err);                             \
     241                 :            :         __gu_err;                                                       \
     242                 :            : })
     243                 :            : 
     244                 :            : #define __get_user_error(x,ptr,err)                                     \
     245                 :            : ({                                                                      \
     246                 :            :         __get_user_err((x),(ptr),err);                                  \
     247                 :            :         (void) 0;                                                       \
     248                 :            : })
     249                 :            : 
     250                 :            : #define __get_user_err(x,ptr,err)                                       \
     251                 :            : do {                                                                    \
     252                 :            :         unsigned long __gu_addr = (unsigned long)(ptr);                 \
     253                 :            :         unsigned long __gu_val;                                         \
     254                 :            :         __chk_user_ptr(ptr);                                            \
     255                 :            :         might_fault();                                                  \
     256                 :            :         switch (sizeof(*(ptr))) {                                       \
     257                 :            :         case 1: __get_user_asm_byte(__gu_val,__gu_addr,err);    break;  \
     258                 :            :         case 2: __get_user_asm_half(__gu_val,__gu_addr,err);    break;  \
     259                 :            :         case 4: __get_user_asm_word(__gu_val,__gu_addr,err);    break;  \
     260                 :            :         default: (__gu_val) = __get_user_bad();                         \
     261                 :            :         }                                                               \
     262                 :            :         (x) = (__typeof__(*(ptr)))__gu_val;                             \
     263                 :            : } while (0)
     264                 :            : 
     265                 :            : #define __get_user_asm_byte(x,addr,err)                         \
     266                 :            :         __asm__ __volatile__(                                   \
     267                 :            :         "1:        " TUSER(ldrb) "       %1,[%2],#0\n"                      \
     268                 :            :         "2:\n"                                                        \
     269                 :            :         "  .pushsection .fixup,\"ax\"\n"                    \
     270                 :            :         "  .align  2\n"                                       \
     271                 :            :         "3:        mov     %0, %3\n"                          \
     272                 :            :         "  mov     %1, #0\n"                          \
     273                 :            :         "  b       2b\n"                                      \
     274                 :            :         "  .popsection\n"                                     \
     275                 :            :         "  .pushsection __ex_table,\"a\"\n"         \
     276                 :            :         "  .align  3\n"                                       \
     277                 :            :         "  .long   1b, 3b\n"                          \
     278                 :            :         "  .popsection"                                       \
     279                 :            :         : "+r" (err), "=&r" (x)                                 \
     280                 :            :         : "r" (addr), "i" (-EFAULT)                         \
     281                 :            :         : "cc")
     282                 :            : 
     283                 :            : #ifndef __ARMEB__
     284                 :            : #define __get_user_asm_half(x,__gu_addr,err)                    \
     285                 :            : ({                                                              \
     286                 :            :         unsigned long __b1, __b2;                               \
     287                 :            :         __get_user_asm_byte(__b1, __gu_addr, err);              \
     288                 :            :         __get_user_asm_byte(__b2, __gu_addr + 1, err);          \
     289                 :            :         (x) = __b1 | (__b2 << 8);                         \
     290                 :            : })
     291                 :            : #else
     292                 :            : #define __get_user_asm_half(x,__gu_addr,err)                    \
     293                 :            : ({                                                              \
     294                 :            :         unsigned long __b1, __b2;                               \
     295                 :            :         __get_user_asm_byte(__b1, __gu_addr, err);              \
     296                 :            :         __get_user_asm_byte(__b2, __gu_addr + 1, err);          \
     297                 :            :         (x) = (__b1 << 8) | __b2;                         \
     298                 :            : })
     299                 :            : #endif
     300                 :            : 
     301                 :            : #define __get_user_asm_word(x,addr,err)                         \
     302                 :            :         __asm__ __volatile__(                                   \
     303                 :            :         "1:        " TUSER(ldr) "        %1,[%2],#0\n"                      \
     304                 :            :         "2:\n"                                                        \
     305                 :            :         "  .pushsection .fixup,\"ax\"\n"                    \
     306                 :            :         "  .align  2\n"                                       \
     307                 :            :         "3:        mov     %0, %3\n"                          \
     308                 :            :         "  mov     %1, #0\n"                          \
     309                 :            :         "  b       2b\n"                                      \
     310                 :            :         "  .popsection\n"                                     \
     311                 :            :         "  .pushsection __ex_table,\"a\"\n"         \
     312                 :            :         "  .align  3\n"                                       \
     313                 :            :         "  .long   1b, 3b\n"                          \
     314                 :            :         "  .popsection"                                       \
     315                 :            :         : "+r" (err), "=&r" (x)                                 \
     316                 :            :         : "r" (addr), "i" (-EFAULT)                         \
     317                 :            :         : "cc")
     318                 :            : 
     319                 :            : #define __put_user(x,ptr)                                               \
     320                 :            : ({                                                                      \
     321                 :            :         long __pu_err = 0;                                              \
     322                 :            :         __put_user_err((x),(ptr),__pu_err);                             \
     323                 :            :         __pu_err;                                                       \
     324                 :            : })
     325                 :            : 
     326                 :            : #define __put_user_error(x,ptr,err)                                     \
     327                 :            : ({                                                                      \
     328                 :            :         __put_user_err((x),(ptr),err);                                  \
     329                 :            :         (void) 0;                                                       \
     330                 :            : })
     331                 :            : 
     332                 :            : #define __put_user_err(x,ptr,err)                                       \
     333                 :            : do {                                                                    \
     334                 :            :         unsigned long __pu_addr = (unsigned long)(ptr);                 \
     335                 :            :         __typeof__(*(ptr)) __pu_val = (x);                              \
     336                 :            :         __chk_user_ptr(ptr);                                            \
     337                 :            :         might_fault();                                                  \
     338                 :            :         switch (sizeof(*(ptr))) {                                       \
     339                 :            :         case 1: __put_user_asm_byte(__pu_val,__pu_addr,err);    break;  \
     340                 :            :         case 2: __put_user_asm_half(__pu_val,__pu_addr,err);    break;  \
     341                 :            :         case 4: __put_user_asm_word(__pu_val,__pu_addr,err);    break;  \
     342                 :            :         case 8: __put_user_asm_dword(__pu_val,__pu_addr,err);   break;  \
     343                 :            :         default: __put_user_bad();                                      \
     344                 :            :         }                                                               \
     345                 :            : } while (0)
     346                 :            : 
     347                 :            : #define __put_user_asm_byte(x,__pu_addr,err)                    \
     348                 :            :         __asm__ __volatile__(                                   \
     349                 :            :         "1:        " TUSER(strb) "       %1,[%2],#0\n"                      \
     350                 :            :         "2:\n"                                                        \
     351                 :            :         "  .pushsection .fixup,\"ax\"\n"                    \
     352                 :            :         "  .align  2\n"                                       \
     353                 :            :         "3:        mov     %0, %3\n"                          \
     354                 :            :         "  b       2b\n"                                      \
     355                 :            :         "  .popsection\n"                                     \
     356                 :            :         "  .pushsection __ex_table,\"a\"\n"         \
     357                 :            :         "  .align  3\n"                                       \
     358                 :            :         "  .long   1b, 3b\n"                          \
     359                 :            :         "  .popsection"                                       \
     360                 :            :         : "+r" (err)                                          \
     361                 :            :         : "r" (x), "r" (__pu_addr), "i" (-EFAULT)         \
     362                 :            :         : "cc")
     363                 :            : 
     364                 :            : #ifndef __ARMEB__
     365                 :            : #define __put_user_asm_half(x,__pu_addr,err)                    \
     366                 :            : ({                                                              \
     367                 :            :         unsigned long __temp = (unsigned long)(x);              \
     368                 :            :         __put_user_asm_byte(__temp, __pu_addr, err);            \
     369                 :            :         __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err);     \
     370                 :            : })
     371                 :            : #else
     372                 :            : #define __put_user_asm_half(x,__pu_addr,err)                    \
     373                 :            : ({                                                              \
     374                 :            :         unsigned long __temp = (unsigned long)(x);              \
     375                 :            :         __put_user_asm_byte(__temp >> 8, __pu_addr, err); \
     376                 :            :         __put_user_asm_byte(__temp, __pu_addr + 1, err);        \
     377                 :            : })
     378                 :            : #endif
     379                 :            : 
     380                 :            : #define __put_user_asm_word(x,__pu_addr,err)                    \
     381                 :            :         __asm__ __volatile__(                                   \
     382                 :            :         "1:        " TUSER(str) "        %1,[%2],#0\n"                      \
     383                 :            :         "2:\n"                                                        \
     384                 :            :         "  .pushsection .fixup,\"ax\"\n"                    \
     385                 :            :         "  .align  2\n"                                       \
     386                 :            :         "3:        mov     %0, %3\n"                          \
     387                 :            :         "  b       2b\n"                                      \
     388                 :            :         "  .popsection\n"                                     \
     389                 :            :         "  .pushsection __ex_table,\"a\"\n"         \
     390                 :            :         "  .align  3\n"                                       \
     391                 :            :         "  .long   1b, 3b\n"                          \
     392                 :            :         "  .popsection"                                       \
     393                 :            :         : "+r" (err)                                          \
     394                 :            :         : "r" (x), "r" (__pu_addr), "i" (-EFAULT)         \
     395                 :            :         : "cc")
     396                 :            : 
     397                 :            : #ifndef __ARMEB__
     398                 :            : #define __reg_oper0     "%R2"
     399                 :            : #define __reg_oper1     "%Q2"
     400                 :            : #else
     401                 :            : #define __reg_oper0     "%Q2"
     402                 :            : #define __reg_oper1     "%R2"
     403                 :            : #endif
     404                 :            : 
     405                 :            : #define __put_user_asm_dword(x,__pu_addr,err)                   \
     406                 :            :         __asm__ __volatile__(                                   \
     407                 :            :  ARM(   "1:        " TUSER(str) "        " __reg_oper1 ", [%1], #4\n"     ) \
     408                 :            :  ARM(   "2:        " TUSER(str) "        " __reg_oper0 ", [%1]\n" ) \
     409                 :            :  THUMB( "1:        " TUSER(str) "        " __reg_oper1 ", [%1]\n" ) \
     410                 :            :  THUMB( "2:        " TUSER(str) "        " __reg_oper0 ", [%1, #4]\n"     ) \
     411                 :            :         "3:\n"                                                        \
     412                 :            :         "  .pushsection .fixup,\"ax\"\n"                    \
     413                 :            :         "  .align  2\n"                                       \
     414                 :            :         "4:        mov     %0, %3\n"                          \
     415                 :            :         "  b       3b\n"                                      \
     416                 :            :         "  .popsection\n"                                     \
     417                 :            :         "  .pushsection __ex_table,\"a\"\n"         \
     418                 :            :         "  .align  3\n"                                       \
     419                 :            :         "  .long   1b, 4b\n"                          \
     420                 :            :         "  .long   2b, 4b\n"                          \
     421                 :            :         "  .popsection"                                       \
     422                 :            :         : "+r" (err), "+r" (__pu_addr)                              \
     423                 :            :         : "r" (x), "i" (-EFAULT)                            \
     424                 :            :         : "cc")
     425                 :            : 
     426                 :            : 
     427                 :            : #ifdef CONFIG_MMU
     428                 :            : extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
     429                 :            : extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
     430                 :            : extern unsigned long __must_check __copy_to_user_std(void __user *to, const void *from, unsigned long n);
     431                 :            : extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
     432                 :            : extern unsigned long __must_check __clear_user_std(void __user *addr, unsigned long n);
     433                 :            : #else
     434                 :            : #define __copy_from_user(to,from,n)     (memcpy(to, (void __force *)from, n), 0)
     435                 :            : #define __copy_to_user(to,from,n)       (memcpy((void __force *)to, from, n), 0)
     436                 :            : #define __clear_user(addr,n)            (memset((void __force *)addr, 0, n), 0)
     437                 :            : #endif
     438                 :            : 
     439                 :            : static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
     440                 :            : {
     441 [ +  + ][ +  + ]:   33990341 :         if (access_ok(VERIFY_READ, from, n))
         [ +  + ][ +  + ]
         [ +  + ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ #  # ]
         [ +  - ][ #  # ]
         [ +  + ][ +  - ]
                 [ #  # ]
           [ +  -  +  + ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
           [ #  #  #  # ]
     442                 :   33990158 :                 n = __copy_from_user(to, from, n);
     443                 :            :         else /* security hole - plug it */
     444 [ +  - ][ +  - ]:        183 :                 memset(to, 0, n);
         [ #  # ][ #  # ]
            [ #  # ][ # ]
         [ #  # ][ -  # ]
         [ #  # ][ #  # ]
         [ #  # ][ +  - ]
         [ #  # ][ #  # ]
            [ #  # ][ # ]
         [ + ][ #  #  # ]
         [ #  # ][ #  # ]
            [ # ][ #  # ]
         [ #  # ][ #  # ]
     445                 :            :         return n;
     446                 :            : }
     447                 :            : 
     448                 :            : static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
     449                 :            : {
     450 [ +  + ][ +  + ]:   85777974 :         if (access_ok(VERIFY_WRITE, to, n))
         [ +  + ][ +  + ]
                 [ +  + ]
           [ +  +  +  + ]
         [ +  - ][ +  + ]
           [ #  #  #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  #  
          #  #  #  #  #  
              # ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  # ]
                 [ #  # ]
           [ #  #  #  # ]
         [ +  + ][ +  - ]
         [ +  - ][ #  # ]
         [ #  # ][ #  # ]
           [ #  #  #  #  
             +  +  #  # ]
         [ #  # ][ #  # ]
         [ +  - ][ +  + ]
         [ +  - ][ +  + ]
         [ #  # ][ #  # ]
                 [ #  # ]
     451                 :   85720300 :                 n = __copy_to_user(to, from, n);
     452                 :            :         return n;
     453                 :            : }
     454                 :            : 
     455                 :            : #define __copy_to_user_inatomic __copy_to_user
     456                 :            : #define __copy_from_user_inatomic __copy_from_user
     457                 :            : 
     458                 :            : static inline unsigned long __must_check clear_user(void __user *to, unsigned long n)
     459                 :            : {
     460 [ +  - ][ +  # ]:     178042 :         if (access_ok(VERIFY_WRITE, to, n))
     461                 :     178045 :                 n = __clear_user(to, n);
     462                 :            :         return n;
     463                 :            : }
     464                 :            : 
     465                 :            : extern long strncpy_from_user(char *dest, const char __user *src, long count);
     466                 :            : 
     467                 :            : extern __must_check long strlen_user(const char __user *str);
     468                 :            : extern __must_check long strnlen_user(const char __user *str, long n);
     469                 :            : 
     470                 :            : #endif /* _ASMARM_UACCESS_H */

Generated by: LCOV version 1.9