linux/arch/x86/lib/putuser.S
<<
>>
Prefs
   1/*
   2 * __put_user functions.
   3 *
   4 * (C) Copyright 2005 Linus Torvalds
   5 * (C) Copyright 2005 Andi Kleen
   6 * (C) Copyright 2008 Glauber Costa
   7 *
   8 * These functions have a non-standard call interface
   9 * to make them more efficient, especially as they
  10 * return an error value in addition to the "real"
  11 * return value.
  12 */
  13#include <linux/linkage.h>
  14#include <asm/dwarf2.h>
  15#include <asm/thread_info.h>
  16#include <asm/errno.h>
  17#include <asm/asm.h>
  18#include <asm/smap.h>
  19
  20
  21/*
  22 * __put_user_X
  23 *
  24 * Inputs:      %eax[:%edx] contains the data
  25 *              %ecx contains the address
  26 *
  27 * Outputs:     %eax is error code (0 or -EFAULT)
  28 *
  29 * These functions should not modify any other registers,
  30 * as they get called from within inline assembly.
  31 */
  32
  33#define ENTER   CFI_STARTPROC ; \
  34                GET_THREAD_INFO(%_ASM_BX)
  35#define EXIT    ASM_CLAC ;      \
  36                ret ;           \
  37                CFI_ENDPROC
  38
  39.text
  40ENTRY(__put_user_1)
  41        ENTER
  42        cmp TI_addr_limit(%_ASM_BX),%_ASM_CX
  43        jae bad_put_user
  44        ASM_STAC
  451:      movb %al,(%_ASM_CX)
  46        xor %eax,%eax
  47        EXIT
  48ENDPROC(__put_user_1)
  49
  50ENTRY(__put_user_2)
  51        ENTER
  52        mov TI_addr_limit(%_ASM_BX),%_ASM_BX
  53        sub $1,%_ASM_BX
  54        cmp %_ASM_BX,%_ASM_CX
  55        jae bad_put_user
  56        ASM_STAC
  572:      movw %ax,(%_ASM_CX)
  58        xor %eax,%eax
  59        EXIT
  60ENDPROC(__put_user_2)
  61
  62ENTRY(__put_user_4)
  63        ENTER
  64        mov TI_addr_limit(%_ASM_BX),%_ASM_BX
  65        sub $3,%_ASM_BX
  66        cmp %_ASM_BX,%_ASM_CX
  67        jae bad_put_user
  68        ASM_STAC
  693:      movl %eax,(%_ASM_CX)
  70        xor %eax,%eax
  71        EXIT
  72ENDPROC(__put_user_4)
  73
  74ENTRY(__put_user_8)
  75        ENTER
  76        mov TI_addr_limit(%_ASM_BX),%_ASM_BX
  77        sub $7,%_ASM_BX
  78        cmp %_ASM_BX,%_ASM_CX
  79        jae bad_put_user
  80        ASM_STAC
  814:      mov %_ASM_AX,(%_ASM_CX)
  82#ifdef CONFIG_X86_32
  835:      movl %edx,4(%_ASM_CX)
  84#endif
  85        xor %eax,%eax
  86        EXIT
  87ENDPROC(__put_user_8)
  88
  89bad_put_user:
  90        CFI_STARTPROC
  91        movl $-EFAULT,%eax
  92        EXIT
  93END(bad_put_user)
  94
  95        _ASM_EXTABLE(1b,bad_put_user)
  96        _ASM_EXTABLE(2b,bad_put_user)
  97        _ASM_EXTABLE(3b,bad_put_user)
  98        _ASM_EXTABLE(4b,bad_put_user)
  99#ifdef CONFIG_X86_32
 100        _ASM_EXTABLE(5b,bad_put_user)
 101#endif
 102