Blame view

kernel/linux-imx6_3.14.28/arch/x86/lib/getuser.S 2.54 KB
6b13f685e   김민수   BSP 최초 추가
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  /*
   * __get_user functions.
   *
   * (C) Copyright 1998 Linus Torvalds
   * (C) Copyright 2005 Andi Kleen
   * (C) Copyright 2008 Glauber Costa
   *
   * These functions have a non-standard call interface
   * to make them more efficient, especially as they
   * return an error value in addition to the "real"
   * return value.
   */
  
  /*
   * __get_user_X
   *
   * Inputs:	%[r|e]ax contains the address.
   *
   * Outputs:	%[r|e]ax is error code (0 or -EFAULT)
   *		%[r|e]dx contains zero-extended value
   *		%ecx contains the high half for 32-bit __get_user_8
   *
   *
   * These functions should not modify any other registers,
   * as they get called from within inline assembly.
   */
  
  #include <linux/linkage.h>
  #include <asm/dwarf2.h>
  #include <asm/page_types.h>
  #include <asm/errno.h>
  #include <asm/asm-offsets.h>
  #include <asm/thread_info.h>
  #include <asm/asm.h>
  #include <asm/smap.h>
  
  	.text
  ENTRY(__get_user_1)
  	CFI_STARTPROC
  	GET_THREAD_INFO(%_ASM_DX)
  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
  	jae bad_get_user
  	ASM_STAC
  1:	movzbl (%_ASM_AX),%edx
  	xor %eax,%eax
  	ASM_CLAC
  	ret
  	CFI_ENDPROC
  ENDPROC(__get_user_1)
  
  ENTRY(__get_user_2)
  	CFI_STARTPROC
  	add $1,%_ASM_AX
  	jc bad_get_user
  	GET_THREAD_INFO(%_ASM_DX)
  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
  	jae bad_get_user
  	ASM_STAC
  2:	movzwl -1(%_ASM_AX),%edx
  	xor %eax,%eax
  	ASM_CLAC
  	ret
  	CFI_ENDPROC
  ENDPROC(__get_user_2)
  
  ENTRY(__get_user_4)
  	CFI_STARTPROC
  	add $3,%_ASM_AX
  	jc bad_get_user
  	GET_THREAD_INFO(%_ASM_DX)
  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
  	jae bad_get_user
  	ASM_STAC
  3:	movl -3(%_ASM_AX),%edx
  	xor %eax,%eax
  	ASM_CLAC
  	ret
  	CFI_ENDPROC
  ENDPROC(__get_user_4)
  
  ENTRY(__get_user_8)
  	CFI_STARTPROC
  #ifdef CONFIG_X86_64
  	add $7,%_ASM_AX
  	jc bad_get_user
  	GET_THREAD_INFO(%_ASM_DX)
  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
  	jae bad_get_user
  	ASM_STAC
  4:	movq -7(%_ASM_AX),%rdx
  	xor %eax,%eax
  	ASM_CLAC
  	ret
  #else
  	add $7,%_ASM_AX
  	jc bad_get_user_8
  	GET_THREAD_INFO(%_ASM_DX)
  	cmp TI_addr_limit(%_ASM_DX),%_ASM_AX
  	jae bad_get_user_8
  	ASM_STAC
  4:	movl -7(%_ASM_AX),%edx
  5:	movl -3(%_ASM_AX),%ecx
  	xor %eax,%eax
  	ASM_CLAC
  	ret
  #endif
  	CFI_ENDPROC
  ENDPROC(__get_user_8)
  
  
  bad_get_user:
  	CFI_STARTPROC
  	xor %edx,%edx
  	mov $(-EFAULT),%_ASM_AX
  	ASM_CLAC
  	ret
  	CFI_ENDPROC
  END(bad_get_user)
  
  #ifdef CONFIG_X86_32
  bad_get_user_8:
  	CFI_STARTPROC
  	xor %edx,%edx
  	xor %ecx,%ecx
  	mov $(-EFAULT),%_ASM_AX
  	ASM_CLAC
  	ret
  	CFI_ENDPROC
  END(bad_get_user_8)
  #endif
  
  	_ASM_EXTABLE(1b,bad_get_user)
  	_ASM_EXTABLE(2b,bad_get_user)
  	_ASM_EXTABLE(3b,bad_get_user)
  #ifdef CONFIG_X86_64
  	_ASM_EXTABLE(4b,bad_get_user)
  #else
  	_ASM_EXTABLE(4b,bad_get_user_8)
  	_ASM_EXTABLE(5b,bad_get_user_8)
  #endif