/root/src/xen/xen/arch/x86/usercopy.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * User address space access functions. |
3 | | * |
4 | | * Copyright 1997 Andi Kleen <ak@muc.de> |
5 | | * Copyright 1997 Linus Torvalds |
6 | | * Copyright 2002 Andi Kleen <ak@suse.de> |
7 | | */ |
8 | | |
9 | | #include <xen/lib.h> |
10 | | #include <xen/sched.h> |
11 | | #include <asm/uaccess.h> |
12 | | |
13 | | unsigned __copy_to_user_ll(void __user *to, const void *from, unsigned n) |
14 | 0 | { |
15 | 0 | unsigned dummy; |
16 | 0 |
|
17 | 0 | stac(); |
18 | 0 | asm volatile ( |
19 | 0 | " cmp $"STR(2*BYTES_PER_LONG-1)", %[cnt]\n" |
20 | 0 | " jbe 1f\n" |
21 | 0 | " mov %k[to], %[cnt]\n" |
22 | 0 | " neg %[cnt]\n" |
23 | 0 | " and $"STR(BYTES_PER_LONG-1)", %[cnt]\n" |
24 | 0 | " sub %[cnt], %[aux]\n" |
25 | 0 | "4: rep movsb\n" /* make 'to' address aligned */ |
26 | 0 | " mov %[aux], %[cnt]\n" |
27 | 0 | " shr $"STR(LONG_BYTEORDER)", %[cnt]\n" |
28 | 0 | " and $"STR(BYTES_PER_LONG-1)", %[aux]\n" |
29 | 0 | " .align 2,0x90\n" |
30 | 0 | "0: rep movs"__OS"\n" /* as many words as possible... */ |
31 | 0 | " mov %[aux],%[cnt]\n" |
32 | 0 | "1: rep movsb\n" /* ...remainder copied as bytes */ |
33 | 0 | "2:\n" |
34 | 0 | ".section .fixup,\"ax\"\n" |
35 | 0 | "5: add %[aux], %[cnt]\n" |
36 | 0 | " jmp 2b\n" |
37 | 0 | "3: lea (%q[aux], %q[cnt], "STR(BYTES_PER_LONG)"), %[cnt]\n" |
38 | 0 | " jmp 2b\n" |
39 | 0 | ".previous\n" |
40 | 0 | _ASM_EXTABLE(4b, 5b) |
41 | 0 | _ASM_EXTABLE(0b, 3b) |
42 | 0 | _ASM_EXTABLE(1b, 2b) |
43 | 0 | : [cnt] "+c" (n), [to] "+D" (to), [from] "+S" (from), |
44 | 0 | [aux] "=&r" (dummy) |
45 | 0 | : "[aux]" (n) |
46 | 0 | : "memory" ); |
47 | 0 | clac(); |
48 | 0 |
|
49 | 0 | return n; |
50 | 0 | } |
51 | | |
52 | | unsigned __copy_from_user_ll(void *to, const void __user *from, unsigned n) |
53 | 1 | { |
54 | 1 | unsigned dummy; |
55 | 1 | |
56 | 1 | stac(); |
57 | 1 | asm volatile ( |
58 | 1 | " cmp $"STR(2*BYTES_PER_LONG-1)", %[cnt]\n" |
59 | 1 | " jbe 1f\n" |
60 | 1 | " mov %k[to], %[cnt]\n" |
61 | 1 | " neg %[cnt]\n" |
62 | 1 | " and $"STR(BYTES_PER_LONG-1)", %[cnt]\n" |
63 | 1 | " sub %[cnt], %[aux]\n" |
64 | 1 | "4: rep movsb\n" /* make 'to' address aligned */ |
65 | 1 | " mov %[aux],%[cnt]\n" |
66 | 1 | " shr $"STR(LONG_BYTEORDER)", %[cnt]\n" |
67 | 1 | " and $"STR(BYTES_PER_LONG-1)", %[aux]\n" |
68 | 1 | " .align 2,0x90\n" |
69 | 1 | "0: rep movs"__OS"\n" /* as many words as possible... */ |
70 | 1 | " mov %[aux], %[cnt]\n" |
71 | 1 | "1: rep movsb\n" /* ...remainder copied as bytes */ |
72 | 1 | "2:\n" |
73 | 1 | ".section .fixup,\"ax\"\n" |
74 | 1 | "5: add %[aux], %[cnt]\n" |
75 | 1 | " jmp 6f\n" |
76 | 1 | "3: lea (%q[aux], %q[cnt], "STR(BYTES_PER_LONG)"), %[cnt]\n" |
77 | 1 | "6: mov %[cnt], %k[from]\n" |
78 | 1 | " xchg %%eax, %[aux]\n" |
79 | 1 | " xor %%eax, %%eax\n" |
80 | 1 | " rep stosb\n" |
81 | 1 | " xchg %[aux], %%eax\n" |
82 | 1 | " mov %k[from], %[cnt]\n" |
83 | 1 | " jmp 2b\n" |
84 | 1 | ".previous\n" |
85 | 1 | _ASM_EXTABLE(4b, 5b) |
86 | 1 | _ASM_EXTABLE(0b, 3b) |
87 | 1 | _ASM_EXTABLE(1b, 6b) |
88 | 1 | : [cnt] "+c" (n), [to] "+D" (to), [from] "+S" (from), |
89 | 1 | [aux] "=&r" (dummy) |
90 | 1 | : "[aux]" (n) |
91 | 1 | : "memory" ); |
92 | 1 | clac(); |
93 | 1 | |
94 | 1 | return n; |
95 | 1 | } |
96 | | |
97 | | /** |
98 | | * copy_to_user: - Copy a block of data into user space. |
99 | | * @to: Destination address, in user space. |
100 | | * @from: Source address, in kernel space. |
101 | | * @n: Number of bytes to copy. |
102 | | * |
103 | | * Context: User context only. This function may sleep. |
104 | | * |
105 | | * Copy data from kernel space to user space. |
106 | | * |
107 | | * Returns number of bytes that could not be copied. |
108 | | * On success, this will be zero. |
109 | | */ |
110 | | unsigned copy_to_user(void __user *to, const void *from, unsigned n) |
111 | 0 | { |
112 | 0 | if ( access_ok(to, n) ) |
113 | 0 | n = __copy_to_user(to, from, n); |
114 | 0 | return n; |
115 | 0 | } |
116 | | |
117 | | /** |
118 | | * clear_user: - Zero a block of memory in user space. |
119 | | * @to: Destination address, in user space. |
120 | | * @n: Number of bytes to zero. |
121 | | * |
122 | | * Zero a block of memory in user space. |
123 | | * |
124 | | * Returns number of bytes that could not be cleared. |
125 | | * On success, this will be zero. |
126 | | */ |
127 | | unsigned clear_user(void __user *to, unsigned n) |
128 | 0 | { |
129 | 0 | if ( access_ok(to, n) ) |
130 | 0 | { |
131 | 0 | stac(); |
132 | 0 | asm volatile ( |
133 | 0 | "0: rep stos"__OS"\n" |
134 | 0 | " mov %[bytes], %[cnt]\n" |
135 | 0 | "1: rep stosb\n" |
136 | 0 | "2:\n" |
137 | 0 | ".section .fixup,\"ax\"\n" |
138 | 0 | "3: lea (%q[bytes], %q[longs], "STR(BYTES_PER_LONG)"), %[cnt]\n" |
139 | 0 | " jmp 2b\n" |
140 | 0 | ".previous\n" |
141 | 0 | _ASM_EXTABLE(0b,3b) |
142 | 0 | _ASM_EXTABLE(1b,2b) |
143 | 0 | : [cnt] "=&c" (n), [to] "+D" (to) |
144 | 0 | : [bytes] "r" (n & (BYTES_PER_LONG - 1)), |
145 | 0 | [longs] "0" (n / BYTES_PER_LONG), "a" (0) ); |
146 | 0 | clac(); |
147 | 0 | } |
148 | 0 |
|
149 | 0 | return n; |
150 | 0 | } |
151 | | |
152 | | /** |
153 | | * copy_from_user: - Copy a block of data from user space. |
154 | | * @to: Destination address, in kernel space. |
155 | | * @from: Source address, in user space. |
156 | | * @n: Number of bytes to copy. |
157 | | * |
158 | | * Context: User context only. This function may sleep. |
159 | | * |
160 | | * Copy data from user space to kernel space. |
161 | | * |
162 | | * Returns number of bytes that could not be copied. |
163 | | * On success, this will be zero. |
164 | | * |
165 | | * If some data could not be copied, this function will pad the copied |
166 | | * data to the requested size using zero bytes. |
167 | | */ |
168 | | unsigned copy_from_user(void *to, const void __user *from, unsigned n) |
169 | 0 | { |
170 | 0 | if ( access_ok(from, n) ) |
171 | 0 | n = __copy_from_user(to, from, n); |
172 | 0 | else |
173 | 0 | memset(to, 0, n); |
174 | 0 | return n; |
175 | 0 | } |
176 | | |
177 | | /* |
178 | | * Local variables: |
179 | | * mode: C |
180 | | * c-file-style: "BSD" |
181 | | * c-basic-offset: 4 |
182 | | * tab-width: 4 |
183 | | * indent-tabs-mode: nil |
184 | | * End: |
185 | | */ |