]> git.ipfire.org Git - thirdparty/kernel/stable.git/blob - arch/arm26/lib/getuser.S
Linux-2.6.12-rc2
[thirdparty/kernel/stable.git] / arch / arm26 / lib / getuser.S
1 /*
2 * linux/arch/arm26/lib/getuser.S
3 *
4 * Copyright (C) 2001 Russell King
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * Idea from x86 version, (C) Copyright 1998 Linus Torvalds
11 *
12 * These functions have a non-standard call interface to make them more
13 * efficient, especially as they return an error value in addition to
14 * the "real" return value.
15 *
16 * __get_user_X
17 *
18 * Inputs: r0 contains the address
19 * Outputs: r0 is the error code
20 * r1, r2 contains the zero-extended value
21 * lr corrupted
22 *
23 * No other registers must be altered. (see include/asm-arm/uaccess.h
24 * for specific ASM register usage).
25 *
26 * Note that ADDR_LIMIT is either 0 or 0xc0000000.
27 * Note also that it is intended that __get_user_bad is not global.
28 */
29 #include <asm/asm_offsets.h>
30 #include <asm/thread_info.h>
31 #include <asm/errno.h>
32
33 .global __get_user_1
34 __get_user_1:
35 bic r1, sp, #0x1f00
36 bic r1, r1, #0x00ff
37 str lr, [sp, #-4]!
38 ldr r1, [r1, #TI_ADDR_LIMIT]
39 sub r1, r1, #1
40 cmp r0, r1
41 bge __get_user_bad
42 cmp r0, #0x02000000
43 1: ldrlsbt r1, [r0]
44 ldrgeb r1, [r0]
45 mov r0, #0
46 ldmfd sp!, {pc}^
47
48 .global __get_user_2
49 __get_user_2:
50 bic r2, sp, #0x1f00
51 bic r2, r2, #0x00ff
52 str lr, [sp, #-4]!
53 ldr r2, [r2, #TI_ADDR_LIMIT]
54 sub r2, r2, #2
55 cmp r0, r2
56 bge __get_user_bad
57 cmp r0, #0x02000000
58 2: ldrlsbt r1, [r0], #1
59 3: ldrlsbt r2, [r0]
60 ldrgeb r1, [r0], #1
61 ldrgeb r2, [r0]
62 orr r1, r1, r2, lsl #8
63 mov r0, #0
64 ldmfd sp!, {pc}^
65
66 .global __get_user_4
67 __get_user_4:
68 bic r1, sp, #0x1f00
69 bic r1, r1, #0x00ff
70 str lr, [sp, #-4]!
71 ldr r1, [r1, #TI_ADDR_LIMIT]
72 sub r1, r1, #4
73 cmp r0, r1
74 bge __get_user_bad
75 cmp r0, #0x02000000
76 4: ldrlst r1, [r0]
77 ldrge r1, [r0]
78 mov r0, #0
79 ldmfd sp!, {pc}^
80
81 .global __get_user_8
82 __get_user_8:
83 bic r2, sp, #0x1f00
84 bic r2, r2, #0x00ff
85 str lr, [sp, #-4]!
86 ldr r2, [r2, #TI_ADDR_LIMIT]
87 sub r2, r2, #8
88 cmp r0, r2
89 bge __get_user_bad_8
90 cmp r0, #0x02000000
91 5: ldrlst r1, [r0], #4
92 6: ldrlst r2, [r0]
93 ldrge r1, [r0], #4
94 ldrge r2, [r0]
95 mov r0, #0
96 ldmfd sp!, {pc}^
97
98 __get_user_bad_8:
99 mov r2, #0
100 __get_user_bad:
101 mov r1, #0
102 mov r0, #-EFAULT
103 ldmfd sp!, {pc}^
104
105 .section __ex_table, "a"
106 .long 1b, __get_user_bad
107 .long 2b, __get_user_bad
108 .long 3b, __get_user_bad
109 .long 4b, __get_user_bad
110 .long 5b, __get_user_bad_8
111 .long 6b, __get_user_bad_8
112 .previous