~ubuntu-branches/ubuntu/utopic/xen/utopic

« back to all changes in this revision

Viewing changes to xen/arch/i386/usercopy.c

  • Committer: Bazaar Package Importer
  • Author(s): Bastian Blank
  • Date: 2010-05-06 15:47:38 UTC
  • mto: (1.3.1) (15.1.1 sid) (4.1.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20100506154738-agoz0rlafrh1fnq7
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
 * User address space access functions.
3
 
 * The non inlined parts of asm-i386/uaccess.h are here.
4
 
 *
5
 
 * Copyright 1997 Andi Kleen <ak@muc.de>
6
 
 * Copyright 1997 Linus Torvalds
7
 
 */
8
 
#include <linux/config.h>
9
 
#include <asm/uaccess.h>
10
 
//#include <asm/mmx.h>
11
 
 
12
 
#ifdef CONFIG_X86_USE_3DNOW_AND_WORKS
13
 
 
14
 
unsigned long
15
 
__generic_copy_to_user(void *to, const void *from, unsigned long n)
16
 
{
17
 
        if (access_ok(VERIFY_WRITE, to, n))
18
 
        {
19
 
                if(n<512)
20
 
                        __copy_user(to,from,n);
21
 
                else
22
 
                        mmx_copy_user(to,from,n);
23
 
        }
24
 
        return n;
25
 
}
26
 
 
27
 
unsigned long
28
 
__generic_copy_from_user(void *to, const void *from, unsigned long n)
29
 
{
30
 
        if (access_ok(VERIFY_READ, from, n))
31
 
        {
32
 
                if(n<512)
33
 
                        __copy_user_zeroing(to,from,n);
34
 
                else
35
 
                        mmx_copy_user_zeroing(to, from, n);
36
 
        }
37
 
        else
38
 
                memset(to, 0, n);
39
 
        return n;
40
 
}
41
 
 
42
 
#else
43
 
 
44
 
unsigned long
45
 
__generic_copy_to_user(void *to, const void *from, unsigned long n)
46
 
{
47
 
        prefetch(from);
48
 
        if (access_ok(VERIFY_WRITE, to, n))
49
 
                __copy_user(to,from,n);
50
 
        return n;
51
 
}
52
 
 
53
 
unsigned long
54
 
__generic_copy_from_user(void *to, const void *from, unsigned long n)
55
 
{
56
 
        prefetchw(to);
57
 
        if (access_ok(VERIFY_READ, from, n))
58
 
                __copy_user_zeroing(to,from,n);
59
 
        else
60
 
                memset(to, 0, n);
61
 
        return n;
62
 
}
63
 
 
64
 
#endif
65
 
 
66
 
/*
67
 
 * Copy a null terminated string from userspace.
68
 
 */
69
 
 
70
 
#define __do_strncpy_from_user(dst,src,count,res)                          \
71
 
do {                                                                       \
72
 
        int __d0, __d1, __d2;                                              \
73
 
        __asm__ __volatile__(                                              \
74
 
                "       testl %1,%1\n"                                     \
75
 
                "       jz 2f\n"                                           \
76
 
                "0:     lodsb\n"                                           \
77
 
                "       stosb\n"                                           \
78
 
                "       testb %%al,%%al\n"                                 \
79
 
                "       jz 1f\n"                                           \
80
 
                "       decl %1\n"                                         \
81
 
                "       jnz 0b\n"                                          \
82
 
                "1:     subl %1,%0\n"                                      \
83
 
                "2:\n"                                                     \
84
 
                ".section .fixup,\"ax\"\n"                                 \
85
 
                "3:     movl %5,%0\n"                                      \
86
 
                "       jmp 2b\n"                                          \
87
 
                ".previous\n"                                              \
88
 
                ".section __ex_table,\"a\"\n"                              \
89
 
                "       .align 4\n"                                        \
90
 
                "       .long 0b,3b\n"                                     \
91
 
                ".previous"                                                \
92
 
                : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
93
 
                  "=&D" (__d2)                                             \
94
 
                : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
95
 
                : "memory");                                               \
96
 
} while (0)
97
 
 
98
 
long
99
 
__strncpy_from_user(char *dst, const char *src, long count)
100
 
{
101
 
        long res;
102
 
        __do_strncpy_from_user(dst, src, count, res);
103
 
        return res;
104
 
}
105
 
 
106
 
long
107
 
strncpy_from_user(char *dst, const char *src, long count)
108
 
{
109
 
        long res = -EFAULT;
110
 
        if (access_ok(VERIFY_READ, src, 1))
111
 
                __do_strncpy_from_user(dst, src, count, res);
112
 
        return res;
113
 
}
114
 
 
115
 
 
116
 
/*
117
 
 * Zero Userspace
118
 
 */
119
 
 
120
 
#define __do_clear_user(addr,size)                                      \
121
 
do {                                                                    \
122
 
        int __d0;                                                       \
123
 
        __asm__ __volatile__(                                           \
124
 
                "0:     rep; stosl\n"                                   \
125
 
                "       movl %2,%0\n"                                   \
126
 
                "1:     rep; stosb\n"                                   \
127
 
                "2:\n"                                                  \
128
 
                ".section .fixup,\"ax\"\n"                              \
129
 
                "3:     lea 0(%2,%0,4),%0\n"                            \
130
 
                "       jmp 2b\n"                                       \
131
 
                ".previous\n"                                           \
132
 
                ".section __ex_table,\"a\"\n"                           \
133
 
                "       .align 4\n"                                     \
134
 
                "       .long 0b,3b\n"                                  \
135
 
                "       .long 1b,2b\n"                                  \
136
 
                ".previous"                                             \
137
 
                : "=&c"(size), "=&D" (__d0)                             \
138
 
                : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0));     \
139
 
} while (0)
140
 
 
141
 
unsigned long
142
 
clear_user(void *to, unsigned long n)
143
 
{
144
 
        if (access_ok(VERIFY_WRITE, to, n))
145
 
                __do_clear_user(to, n);
146
 
        return n;
147
 
}
148
 
 
149
 
unsigned long
150
 
__clear_user(void *to, unsigned long n)
151
 
{
152
 
        __do_clear_user(to, n);
153
 
        return n;
154
 
}
155
 
 
156
 
/*
157
 
 * Return the size of a string (including the ending 0)
158
 
 *
159
 
 * Return 0 on exception, a value greater than N if too long
160
 
 */
161
 
 
162
 
long strnlen_user(const char *s, long n)
163
 
{
164
 
        unsigned long mask = -__addr_ok(s);
165
 
        unsigned long res, tmp;
166
 
 
167
 
        __asm__ __volatile__(
168
 
                "       testl %0, %0\n"
169
 
                "       jz 3f\n"
170
 
                "       andl %0,%%ecx\n"
171
 
                "0:     repne; scasb\n"
172
 
                "       setne %%al\n"
173
 
                "       subl %%ecx,%0\n"
174
 
                "       addl %0,%%eax\n"
175
 
                "1:\n"
176
 
                ".section .fixup,\"ax\"\n"
177
 
                "2:     xorl %%eax,%%eax\n"
178
 
                "       jmp 1b\n"
179
 
                "3:     movb $1,%%al\n"
180
 
                "       jmp 1b\n"
181
 
                ".previous\n"
182
 
                ".section __ex_table,\"a\"\n"
183
 
                "       .align 4\n"
184
 
                "       .long 0b,2b\n"
185
 
                ".previous"
186
 
                :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp)
187
 
                :"0" (n), "1" (s), "2" (0), "3" (mask)
188
 
                :"cc");
189
 
        return res & mask;
190
 
}