Linux-2.6.12-rc2
[linux-2.6.git] / arch / s390 / lib / uaccess64.S
1 /*
2  *  arch/s390x/lib/uaccess.S
3  *    __copy_{from|to}_user functions.
4  *
5  *  s390
6  *    Copyright (C) 2000,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  *    Authors(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
8  *
9  *  These functions have standard call interface
10  */
11
12 #include <linux/errno.h>
13 #include <asm/lowcore.h>
14 #include <asm/offsets.h>
15
16         .text
17         .align 4
18         .globl __copy_from_user_asm
19         # %r2 = to, %r3 = n, %r4 = from
20 __copy_from_user_asm:
21         slgr    %r0,%r0
22 0:      mvcp    0(%r3,%r2),0(%r4),%r0
23         jnz     1f
24         slgr    %r2,%r2
25         br      %r14
26 1:      la      %r2,256(%r2)
27         la      %r4,256(%r4)
28         aghi    %r3,-256
29 2:      mvcp    0(%r3,%r2),0(%r4),%r0
30         jnz     1b
31 3:      slgr    %r2,%r2
32         br      %r14
33 4:      lghi    %r0,-4096
34         lgr     %r5,%r4
35         slgr    %r5,%r0
36         ngr     %r5,%r0         # %r5 = (%r4 + 4096) & -4096
37         slgr    %r5,%r4         # %r5 = #bytes to next user page boundary
38         clgr    %r3,%r5         # copy crosses next page boundary ?
39         jnh     6f              # no, the current page faulted
40         # move with the reduced length which is < 256
41 5:      mvcp    0(%r5,%r2),0(%r4),%r0
42         slgr    %r3,%r5
43 6:      lgr     %r2,%r3
44         br      %r14
45         .section __ex_table,"a"
46         .quad   0b,4b
47         .quad   2b,4b
48         .quad   5b,6b
49         .previous
50
51         .align 4
52         .text
53         .globl __copy_to_user_asm
54         # %r2 = from, %r3 = n, %r4 = to
55 __copy_to_user_asm:
56         slgr    %r0,%r0
57 0:      mvcs    0(%r3,%r4),0(%r2),%r0
58         jnz     1f
59         slgr    %r2,%r2
60         br      %r14
61 1:      la      %r2,256(%r2)
62         la      %r4,256(%r4)
63         aghi    %r3,-256
64 2:      mvcs    0(%r3,%r4),0(%r2),%r0
65         jnz     1b
66 3:      slgr    %r2,%r2
67         br      %r14
68 4:      lghi    %r0,-4096
69         lgr     %r5,%r4
70         slgr    %r5,%r0
71         ngr     %r5,%r0         # %r5 = (%r4 + 4096) & -4096
72         slgr    %r5,%r4         # %r5 = #bytes to next user page boundary
73         clgr    %r3,%r5         # copy crosses next page boundary ?
74         jnh     6f              # no, the current page faulted
75         # move with the reduced length which is < 256
76 5:      mvcs    0(%r5,%r4),0(%r2),%r0
77         slgr    %r3,%r5
78 6:      lgr     %r2,%r3
79         br      %r14
80         .section __ex_table,"a"
81         .quad   0b,4b
82         .quad   2b,4b
83         .quad   5b,6b
84         .previous
85
86         .align 4
87         .text
88         .globl __copy_in_user_asm
89         # %r2 = from, %r3 = n, %r4 = to
90 __copy_in_user_asm:
91         sacf    256
92         bras    1,1f
93         mvc     0(1,%r4),0(%r2)
94 0:      mvc     0(256,%r4),0(%r2)
95         la      %r2,256(%r2)
96         la      %r4,256(%r4)
97 1:      aghi    %r3,-256
98         jnm     0b
99 2:      ex      %r3,0(%r1)
100         sacf    0
101         slgr    %r2,%r2
102         br      14
103 3:      mvc     0(1,%r4),0(%r2)
104         la      %r2,1(%r2)
105         la      %r4,1(%r4)
106         aghi    %r3,-1
107         jnm     3b
108 4:      lgr     %r2,%r3
109         sacf    0
110         br      %r14
111         .section __ex_table,"a"
112         .quad   0b,3b
113         .quad   2b,3b
114         .quad   3b,4b
115         .previous
116
117         .align 4
118         .text
119         .globl __clear_user_asm
120         # %r2 = to, %r3 = n
121 __clear_user_asm:
122         slgr    %r0,%r0
123         larl    %r5,empty_zero_page
124 1:      mvcs    0(%r3,%r2),0(%r5),%r0
125         jnz     2f
126         slgr    %r2,%r2
127         br      %r14
128 2:      la      %r2,256(%r2)
129         aghi    %r3,-256
130 3:      mvcs    0(%r3,%r2),0(%r5),%r0
131         jnz     2b
132 4:      slgr    %r2,%r2
133         br      %r14
134 5:      lghi    %r0,-4096
135         lgr     %r4,%r2
136         slgr    %r4,%r0
137         ngr     %r4,%r0         # %r4 = (%r2 + 4096) & -4096
138         slgr    %r4,%r2         # %r4 = #bytes to next user page boundary
139         clgr    %r3,%r4         # clear crosses next page boundary ?
140         jnh     7f              # no, the current page faulted
141         # clear with the reduced length which is < 256
142 6:      mvcs    0(%r4,%r2),0(%r5),%r0
143         slgr    %r3,%r4
144 7:      lgr     %r2,%r3
145         br      %r14
146         .section __ex_table,"a"
147         .quad   1b,5b
148         .quad   3b,5b
149         .quad   6b,7b
150         .previous
151
152         .align 4
153         .text
154         .globl __strncpy_from_user_asm
155         # %r2 = count, %r3 = dst, %r4 = src
156 __strncpy_from_user_asm:
157         lghi    %r0,0
158         lgr     %r1,%r4
159         la      %r2,0(%r2,%r4)  # %r2 points to first byte after string
160         sacf    256
161 0:      srst    %r2,%r1
162         jo      0b
163         sacf    0
164         lgr     %r1,%r2
165         jh      1f              # \0 found in string ?
166         aghi    %r1,1           # include \0 in copy
167 1:      slgr    %r1,%r4         # %r1 = copy length (without \0)
168         slgr    %r2,%r4         # %r2 = return length (including \0)
169 2:      mvcp    0(%r1,%r3),0(%r4),%r0
170         jnz     3f
171         br      %r14
172 3:      la      %r3,256(%r3)
173         la      %r4,256(%r4)
174         aghi    %r1,-256
175         mvcp    0(%r1,%r3),0(%r4),%r0
176         jnz     3b
177         br      %r14
178 4:      sacf    0
179         lghi    %r2,-EFAULT
180         br      %r14
181         .section __ex_table,"a"
182         .quad   0b,4b
183         .previous
184
185         .align 4
186         .text
187         .globl __strnlen_user_asm
188         # %r2 = count, %r3 = src
189 __strnlen_user_asm:
190         lghi    %r0,0
191         lgr     %r1,%r3
192         la      %r2,0(%r2,%r3)  # %r2 points to first byte after string
193         sacf    256
194 0:      srst    %r2,%r1
195         jo      0b
196         sacf    0
197         jh      1f              # \0 found in string ?
198         aghi    %r2,1           # strnlen_user result includes the \0
199 1:      slgr    %r2,%r3
200         br      %r14
201 2:      sacf    0
202         lghi    %r2,-EFAULT
203         br      %r14
204         .section __ex_table,"a"
205         .quad   0b,2b
206         .previous