Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * __get_user functions. | |
3 | * | |
4 | * (C) Copyright 1998 Linus Torvalds | |
5 | * (C) Copyright 2005 Andi Kleen | |
6 | * | |
7 | * These functions have a non-standard call interface | |
8 | * to make them more efficient, especially as they | |
9 | * return an error value in addition to the "real" | |
10 | * return value. | |
11 | */ | |
12 | ||
13 | /* | |
14 | * __get_user_X | |
15 | * | |
16 | * Inputs: %rcx contains the address. | |
17 | * The register is modified, but all changes are undone | |
18 | * before returning because the C code doesn't know about it. | |
19 | * | |
20 | * Outputs: %rax is error code (0 or -EFAULT) | |
21 | * %rdx contains zero-extended value | |
22 | * | |
23 | * %r8 is destroyed. | |
24 | * | |
25 | * These functions should not modify any other registers, | |
26 | * as they get called from within inline assembly. | |
27 | */ | |
28 | ||
29 | #include <linux/linkage.h> | |
30 | #include <asm/page.h> | |
31 | #include <asm/errno.h> | |
e2d5df93 | 32 | #include <asm/asm-offsets.h> |
1da177e4 LT |
33 | #include <asm/thread_info.h> |
34 | ||
35 | .text | |
36 | .p2align 4 | |
37 | .globl __get_user_1 | |
38 | __get_user_1: | |
39 | GET_THREAD_INFO(%r8) | |
40 | cmpq threadinfo_addr_limit(%r8),%rcx | |
41 | jae bad_get_user | |
42 | 1: movzb (%rcx),%edx | |
43 | xorl %eax,%eax | |
44 | ret | |
45 | ||
46 | .p2align 4 | |
47 | .globl __get_user_2 | |
48 | __get_user_2: | |
49 | GET_THREAD_INFO(%r8) | |
50 | addq $1,%rcx | |
51 | jc 20f | |
52 | cmpq threadinfo_addr_limit(%r8),%rcx | |
53 | jae 20f | |
54 | decq %rcx | |
55 | 2: movzwl (%rcx),%edx | |
56 | xorl %eax,%eax | |
57 | ret | |
58 | 20: decq %rcx | |
59 | jmp bad_get_user | |
60 | ||
61 | .p2align 4 | |
62 | .globl __get_user_4 | |
63 | __get_user_4: | |
64 | GET_THREAD_INFO(%r8) | |
65 | addq $3,%rcx | |
66 | jc 30f | |
67 | cmpq threadinfo_addr_limit(%r8),%rcx | |
68 | jae 30f | |
69 | subq $3,%rcx | |
70 | 3: movl (%rcx),%edx | |
71 | xorl %eax,%eax | |
72 | ret | |
73 | 30: subq $3,%rcx | |
74 | jmp bad_get_user | |
75 | ||
76 | .p2align 4 | |
77 | .globl __get_user_8 | |
78 | __get_user_8: | |
79 | GET_THREAD_INFO(%r8) | |
80 | addq $7,%rcx | |
3a6fd752 | 81 | jc 40f |
1da177e4 | 82 | cmpq threadinfo_addr_limit(%r8),%rcx |
3a6fd752 | 83 | jae 40f |
1da177e4 LT |
84 | subq $7,%rcx |
85 | 4: movq (%rcx),%rdx | |
86 | xorl %eax,%eax | |
87 | ret | |
88 | 40: subq $7,%rcx | |
89 | jmp bad_get_user | |
90 | ||
91 | bad_get_user: | |
92 | xorl %edx,%edx | |
93 | movq $(-EFAULT),%rax | |
94 | ret | |
95 | ||
96 | .section __ex_table,"a" | |
97 | .quad 1b,bad_get_user | |
98 | .quad 2b,bad_get_user | |
99 | .quad 3b,bad_get_user | |
100 | .quad 4b,bad_get_user | |
101 | .previous |