Blame view

kernel/linux-rt-4.4.41/arch/arm/lib/getuser.S 3.11 KB
5113f6f70   김현기   kernel add
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
141
142
143
144
145
146
147
148
149
  /*
   *  linux/arch/arm/lib/getuser.S
   *
   *  Copyright (C) 2001 Russell King
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   *
   *  Idea from x86 version, (C) Copyright 1998 Linus Torvalds
   *
   * 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:	r0 contains the address
   *		r1 contains the address limit, which must be preserved
   * Outputs:	r0 is the error code
   *		r2, r3 contains the zero-extended value
   *		lr corrupted
   *
   * No other registers must be altered.  (see <asm/uaccess.h>
   * for specific ASM register usage).
   *
   * Note that ADDR_LIMIT is either 0 or 0xc0000000.
   * Note also that it is intended that __get_user_bad is not global.
   */
  #include <linux/linkage.h>
  #include <asm/assembler.h>
  #include <asm/errno.h>
  #include <asm/domain.h>
  
  ENTRY(__get_user_1)
  	check_uaccess r0, 1, r1, r2, __get_user_bad
  1: TUSER(ldrb)	r2, [r0]
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_1)
  
  ENTRY(__get_user_2)
  	check_uaccess r0, 2, r1, r2, __get_user_bad
  #ifdef CONFIG_CPU_USE_DOMAINS
  rb	.req	ip
  2:	ldrbt	r2, [r0], #1
  3:	ldrbt	rb, [r0], #0
  #else
  rb	.req	r0
  2:	ldrb	r2, [r0]
  3:	ldrb	rb, [r0, #1]
  #endif
  #ifndef __ARMEB__
  	orr	r2, r2, rb, lsl #8
  #else
  	orr	r2, rb, r2, lsl #8
  #endif
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_2)
  
  ENTRY(__get_user_4)
  	check_uaccess r0, 4, r1, r2, __get_user_bad
  4: TUSER(ldr)	r2, [r0]
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_4)
  
  ENTRY(__get_user_8)
  	check_uaccess r0, 8, r1, r2, __get_user_bad
  #ifdef CONFIG_THUMB2_KERNEL
  5: TUSER(ldr)	r2, [r0]
  6: TUSER(ldr)	r3, [r0, #4]
  #else
  5: TUSER(ldr)	r2, [r0], #4
  6: TUSER(ldr)	r3, [r0]
  #endif
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_8)
  
  #ifdef __ARMEB__
  ENTRY(__get_user_32t_8)
  	check_uaccess r0, 8, r1, r2, __get_user_bad
  #ifdef CONFIG_CPU_USE_DOMAINS
  	add	r0, r0, #4
  7:	ldrt	r2, [r0]
  #else
  7:	ldr	r2, [r0, #4]
  #endif
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_32t_8)
  
  ENTRY(__get_user_64t_1)
  	check_uaccess r0, 1, r1, r2, __get_user_bad8
  8: TUSER(ldrb)	r3, [r0]
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_64t_1)
  
  ENTRY(__get_user_64t_2)
  	check_uaccess r0, 2, r1, r2, __get_user_bad8
  #ifdef CONFIG_CPU_USE_DOMAINS
  rb	.req	ip
  9:	ldrbt	r3, [r0], #1
  10:	ldrbt	rb, [r0], #0
  #else
  rb	.req	r0
  9:	ldrb	r3, [r0]
  10:	ldrb	rb, [r0, #1]
  #endif
  	orr	r3, rb, r3, lsl #8
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_64t_2)
  
  ENTRY(__get_user_64t_4)
  	check_uaccess r0, 4, r1, r2, __get_user_bad8
  11: TUSER(ldr)	r3, [r0]
  	mov	r0, #0
  	ret	lr
  ENDPROC(__get_user_64t_4)
  #endif
  
  __get_user_bad8:
  	mov	r3, #0
  __get_user_bad:
  	mov	r2, #0
  	mov	r0, #-EFAULT
  	ret	lr
  ENDPROC(__get_user_bad)
  ENDPROC(__get_user_bad8)
  
  .pushsection __ex_table, "a"
  	.long	1b, __get_user_bad
  	.long	2b, __get_user_bad
  	.long	3b, __get_user_bad
  	.long	4b, __get_user_bad
  	.long	5b, __get_user_bad8
  	.long	6b, __get_user_bad8
  #ifdef __ARMEB__
  	.long   7b, __get_user_bad
  	.long	8b, __get_user_bad8
  	.long	9b, __get_user_bad8
  	.long	10b, __get_user_bad8
  	.long	11b, __get_user_bad8
  #endif
  .popsection