Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
uaccess.c
Go to the documentation of this file.
1 /*
2  * This file is subject to the terms and conditions of the GNU General Public
3  * License. See the file COPYING in the main directory of this archive
4  * for more details.
5  */
6 
7 #include <linux/module.h>
8 #include <asm/uaccess.h>
9 
10 unsigned long __generic_copy_from_user(void *to, const void __user *from,
11  unsigned long n)
12 {
13  unsigned long tmp, res;
14 
15  asm volatile ("\n"
16  " tst.l %0\n"
17  " jeq 2f\n"
18  "1: "MOVES".l (%1)+,%3\n"
19  " move.l %3,(%2)+\n"
20  " subq.l #1,%0\n"
21  " jne 1b\n"
22  "2: btst #1,%5\n"
23  " jeq 4f\n"
24  "3: "MOVES".w (%1)+,%3\n"
25  " move.w %3,(%2)+\n"
26  "4: btst #0,%5\n"
27  " jeq 6f\n"
28  "5: "MOVES".b (%1)+,%3\n"
29  " move.b %3,(%2)+\n"
30  "6:\n"
31  " .section .fixup,\"ax\"\n"
32  " .even\n"
33  "10: move.l %0,%3\n"
34  "7: clr.l (%2)+\n"
35  " subq.l #1,%3\n"
36  " jne 7b\n"
37  " lsl.l #2,%0\n"
38  " btst #1,%5\n"
39  " jeq 8f\n"
40  "30: clr.w (%2)+\n"
41  " addq.l #2,%0\n"
42  "8: btst #0,%5\n"
43  " jeq 6b\n"
44  "50: clr.b (%2)+\n"
45  " addq.l #1,%0\n"
46  " jra 6b\n"
47  " .previous\n"
48  "\n"
49  " .section __ex_table,\"a\"\n"
50  " .align 4\n"
51  " .long 1b,10b\n"
52  " .long 3b,30b\n"
53  " .long 5b,50b\n"
54  " .previous"
55  : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
56  : "0" (n / 4), "d" (n & 3));
57 
58  return res;
59 }
60 EXPORT_SYMBOL(__generic_copy_from_user);
61 
62 unsigned long __generic_copy_to_user(void __user *to, const void *from,
63  unsigned long n)
64 {
65  unsigned long tmp, res;
66 
67  asm volatile ("\n"
68  " tst.l %0\n"
69  " jeq 4f\n"
70  "1: move.l (%1)+,%3\n"
71  "2: "MOVES".l %3,(%2)+\n"
72  "3: subq.l #1,%0\n"
73  " jne 1b\n"
74  "4: btst #1,%5\n"
75  " jeq 6f\n"
76  " move.w (%1)+,%3\n"
77  "5: "MOVES".w %3,(%2)+\n"
78  "6: btst #0,%5\n"
79  " jeq 8f\n"
80  " move.b (%1)+,%3\n"
81  "7: "MOVES".b %3,(%2)+\n"
82  "8:\n"
83  " .section .fixup,\"ax\"\n"
84  " .even\n"
85  "20: lsl.l #2,%0\n"
86  "50: add.l %5,%0\n"
87  " jra 8b\n"
88  " .previous\n"
89  "\n"
90  " .section __ex_table,\"a\"\n"
91  " .align 4\n"
92  " .long 2b,20b\n"
93  " .long 3b,20b\n"
94  " .long 5b,50b\n"
95  " .long 6b,50b\n"
96  " .long 7b,50b\n"
97  " .long 8b,50b\n"
98  " .previous"
99  : "=d" (res), "+a" (from), "+a" (to), "=&r" (tmp)
100  : "0" (n / 4), "d" (n & 3));
101 
102  return res;
103 }
104 EXPORT_SYMBOL(__generic_copy_to_user);
105 
106 /*
107  * Zero Userspace
108  */
109 
110 unsigned long __clear_user(void __user *to, unsigned long n)
111 {
112  unsigned long res;
113 
114  asm volatile ("\n"
115  " tst.l %0\n"
116  " jeq 3f\n"
117  "1: "MOVES".l %2,(%1)+\n"
118  "2: subq.l #1,%0\n"
119  " jne 1b\n"
120  "3: btst #1,%4\n"
121  " jeq 5f\n"
122  "4: "MOVES".w %2,(%1)+\n"
123  "5: btst #0,%4\n"
124  " jeq 7f\n"
125  "6: "MOVES".b %2,(%1)\n"
126  "7:\n"
127  " .section .fixup,\"ax\"\n"
128  " .even\n"
129  "10: lsl.l #2,%0\n"
130  "40: add.l %4,%0\n"
131  " jra 7b\n"
132  " .previous\n"
133  "\n"
134  " .section __ex_table,\"a\"\n"
135  " .align 4\n"
136  " .long 1b,10b\n"
137  " .long 2b,10b\n"
138  " .long 4b,40b\n"
139  " .long 5b,40b\n"
140  " .long 6b,40b\n"
141  " .long 7b,40b\n"
142  " .previous"
143  : "=d" (res), "+a" (to)
144  : "r" (0), "0" (n / 4), "d" (n & 3));
145 
146  return res;
147 }