OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [arch/] [x86/] [lib/] [usercopy_64.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
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
#include <linux/module.h>
9
#include <asm/uaccess.h>
10
 
11
/*
12
 * Copy a null terminated string from userspace.
13
 */
14
 
15
#define __do_strncpy_from_user(dst,src,count,res)                          \
16
do {                                                                       \
17
        long __d0, __d1, __d2;                                             \
18
        might_sleep();                                                     \
19
        __asm__ __volatile__(                                              \
20
                "       testq %1,%1\n"                                     \
21
                "       jz 2f\n"                                           \
22
                "0:     lodsb\n"                                           \
23
                "       stosb\n"                                           \
24
                "       testb %%al,%%al\n"                                 \
25
                "       jz 1f\n"                                           \
26
                "       decq %1\n"                                         \
27
                "       jnz 0b\n"                                          \
28
                "1:     subq %1,%0\n"                                      \
29
                "2:\n"                                                     \
30
                ".section .fixup,\"ax\"\n"                                 \
31
                "3:     movq %5,%0\n"                                      \
32
                "       jmp 2b\n"                                          \
33
                ".previous\n"                                              \
34
                ".section __ex_table,\"a\"\n"                              \
35
                "       .align 8\n"                                        \
36
                "       .quad 0b,3b\n"                                     \
37
                ".previous"                                                \
38
                : "=r"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1),      \
39
                  "=&D" (__d2)                                             \
40
                : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \
41
                : "memory");                                               \
42
} while (0)
43
 
44
long
45
__strncpy_from_user(char *dst, const char __user *src, long count)
46
{
47
        long res;
48
        __do_strncpy_from_user(dst, src, count, res);
49
        return res;
50
}
51
EXPORT_SYMBOL(__strncpy_from_user);
52
 
53
long
54
strncpy_from_user(char *dst, const char __user *src, long count)
55
{
56
        long res = -EFAULT;
57
        if (access_ok(VERIFY_READ, src, 1))
58
                return __strncpy_from_user(dst, src, count);
59
        return res;
60
}
61
EXPORT_SYMBOL(strncpy_from_user);
62
 
63
/*
64
 * Zero Userspace
65
 */
66
 
67
unsigned long __clear_user(void __user *addr, unsigned long size)
68
{
69
        long __d0;
70
        might_sleep();
71
        /* no memory constraint because it doesn't change any memory gcc knows
72
           about */
73
        asm volatile(
74
                "       testq  %[size8],%[size8]\n"
75
                "       jz     4f\n"
76
                "0:     movq %[zero],(%[dst])\n"
77
                "       addq   %[eight],%[dst]\n"
78
                "       decl %%ecx ; jnz   0b\n"
79
                "4:     movq  %[size1],%%rcx\n"
80
                "       testl %%ecx,%%ecx\n"
81
                "       jz     2f\n"
82
                "1:     movb   %b[zero],(%[dst])\n"
83
                "       incq   %[dst]\n"
84
                "       decl %%ecx ; jnz  1b\n"
85
                "2:\n"
86
                ".section .fixup,\"ax\"\n"
87
                "3:     lea 0(%[size1],%[size8],8),%[size8]\n"
88
                "       jmp 2b\n"
89
                ".previous\n"
90
                ".section __ex_table,\"a\"\n"
91
                "       .align 8\n"
92
                "       .quad 0b,3b\n"
93
                "       .quad 1b,2b\n"
94
                ".previous"
95
                : [size8] "=c"(size), [dst] "=&D" (__d0)
96
                : [size1] "r"(size & 7), "[size8]" (size / 8), "[dst]"(addr),
97
                  [zero] "r" (0UL), [eight] "r" (8UL));
98
        return size;
99
}
100
EXPORT_SYMBOL(__clear_user);
101
 
102
unsigned long clear_user(void __user *to, unsigned long n)
103
{
104
        if (access_ok(VERIFY_WRITE, to, n))
105
                return __clear_user(to, n);
106
        return n;
107
}
108
EXPORT_SYMBOL(clear_user);
109
 
110
/*
111
 * Return the size of a string (including the ending 0)
112
 *
113
 * Return 0 on exception, a value greater than N if too long
114
 */
115
 
116
long __strnlen_user(const char __user *s, long n)
117
{
118
        long res = 0;
119
        char c;
120
 
121
        while (1) {
122
                if (res>n)
123
                        return n+1;
124
                if (__get_user(c, s))
125
                        return 0;
126
                if (!c)
127
                        return res+1;
128
                res++;
129
                s++;
130
        }
131
}
132
EXPORT_SYMBOL(__strnlen_user);
133
 
134
long strnlen_user(const char __user *s, long n)
135
{
136
        if (!access_ok(VERIFY_READ, s, n))
137
                return 0;
138
        return __strnlen_user(s, n);
139
}
140
EXPORT_SYMBOL(strnlen_user);
141
 
142
long strlen_user(const char __user *s)
143
{
144
        long res = 0;
145
        char c;
146
 
147
        for (;;) {
148
                if (get_user(c, s))
149
                        return 0;
150
                if (!c)
151
                        return res+1;
152
                res++;
153
                s++;
154
        }
155
}
156
EXPORT_SYMBOL(strlen_user);
157
 
158
unsigned long copy_in_user(void __user *to, const void __user *from, unsigned len)
159
{
160
        if (access_ok(VERIFY_WRITE, to, len) && access_ok(VERIFY_READ, from, len)) {
161
                return copy_user_generic((__force void *)to, (__force void *)from, len);
162
        }
163
        return len;
164
}
165
EXPORT_SYMBOL(copy_in_user);
166
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.