Merge to Fedora kernel-2.6.18-1.2255_FC5-vs2.0.2.2-rc9 patched with stable patch...
[linux-2.6.git] / arch / s390 / lib / uaccess.S
1 /*
2  *  arch/s390/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/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         slr     %r0,%r0
22 0:      mvcp    0(%r3,%r2),0(%r4),%r0
23         jnz     1f
24         slr     %r2,%r2
25         br      %r14
26 1:      la      %r2,256(%r2)
27         la      %r4,256(%r4)
28         ahi     %r3,-256
29 2:      mvcp    0(%r3,%r2),0(%r4),%r0
30         jnz     1b
31 3:      slr     %r2,%r2
32         br      %r14
33 4:      lhi     %r0,-4096
34         lr      %r5,%r4
35         slr     %r5,%r0
36         nr      %r5,%r0         # %r5 = (%r4 + 4096) & -4096
37         slr     %r5,%r4         # %r5 = #bytes to next user page boundary
38         clr     %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         slr     %r3,%r5
43         alr     %r2,%r5
44 6:      lr      %r5,%r3         # copy remaining size
45         ahi     %r5,-1          # subtract 1 for xc loop
46         bras    %r4,8f
47         xc      0(1,%r2),0(%r2)
48 7:      xc      0(256,%r2),0(%r2)
49         la      %r2,256(%r2)
50 8:      ahi     %r5,-256
51         jnm     7b
52         ex      %r5,0(%r4)
53 9:      lr      %r2,%r3
54         br      %r14
55         .section __ex_table,"a"
56         .long   0b,4b
57         .long   2b,4b
58         .long   5b,6b
59         .previous
60
61         .align 4
62         .text
63         .globl __copy_to_user_asm
64         # %r2 = from, %r3 = n, %r4 = to
65 __copy_to_user_asm:
66         slr     %r0,%r0
67 0:      mvcs    0(%r3,%r4),0(%r2),%r0
68         jnz     1f
69         slr     %r2,%r2
70         br      %r14
71 1:      la      %r2,256(%r2)
72         la      %r4,256(%r4)
73         ahi     %r3,-256
74 2:      mvcs    0(%r3,%r4),0(%r2),%r0
75         jnz     1b
76 3:      slr     %r2,%r2
77         br      %r14
78 4:      lhi     %r0,-4096
79         lr      %r5,%r4
80         slr     %r5,%r0
81         nr      %r5,%r0         # %r5 = (%r4 + 4096) & -4096
82         slr     %r5,%r4         # %r5 = #bytes to next user page boundary
83         clr     %r3,%r5         # copy crosses next page boundary ?
84         jnh     6f              # no, the current page faulted
85         # move with the reduced length which is < 256
86 5:      mvcs    0(%r5,%r4),0(%r2),%r0
87         slr     %r3,%r5
88 6:      lr      %r2,%r3
89         br      %r14
90         .section __ex_table,"a"
91         .long   0b,4b
92         .long   2b,4b
93         .long   5b,6b
94         .previous
95
96         .align 4
97         .text
98         .globl __copy_in_user_asm
99         # %r2 = from, %r3 = n, %r4 = to
100 __copy_in_user_asm:
101         ahi     %r3,-1
102         jo      6f
103         sacf    256
104         bras    %r1,4f
105 0:      ahi     %r3,257
106 1:      mvc     0(1,%r4),0(%r2)
107         la      %r2,1(%r2)
108         la      %r4,1(%r4)
109         ahi     %r3,-1
110         jnz     1b
111 2:      lr      %r2,%r3
112         br      %r14
113 3:      mvc     0(256,%r4),0(%r2)
114         la      %r2,256(%r2)
115         la      %r4,256(%r4)
116 4:      ahi     %r3,-256
117         jnm     3b
118 5:      ex      %r3,4(%r1)
119         sacf    0
120 6:      slr     %r2,%r2
121         br      %r14
122         .section __ex_table,"a"
123         .long   1b,2b
124         .long   3b,0b
125         .long   5b,0b
126         .previous
127
128         .align 4
129         .text
130         .globl __clear_user_asm
131         # %r2 = to, %r3 = n
132 __clear_user_asm:
133         bras    %r5,0f
134         .long   empty_zero_page
135 0:      l       %r5,0(%r5)
136         slr     %r0,%r0
137 1:      mvcs    0(%r3,%r2),0(%r5),%r0
138         jnz     2f
139         slr     %r2,%r2
140         br      %r14
141 2:      la      %r2,256(%r2)
142         ahi     %r3,-256
143 3:      mvcs    0(%r3,%r2),0(%r5),%r0
144         jnz     2b
145 4:      slr     %r2,%r2
146         br      %r14
147 5:      lhi     %r0,-4096
148         lr      %r4,%r2
149         slr     %r4,%r0
150         nr      %r4,%r0         # %r4 = (%r2 + 4096) & -4096
151         slr     %r4,%r2         # %r4 = #bytes to next user page boundary
152         clr     %r3,%r4         # clear crosses next page boundary ?
153         jnh     7f              # no, the current page faulted
154         # clear with the reduced length which is < 256
155 6:      mvcs    0(%r4,%r2),0(%r5),%r0
156         slr     %r3,%r4
157 7:      lr      %r2,%r3
158         br      %r14
159         .section __ex_table,"a"
160         .long   1b,5b
161         .long   3b,5b
162         .long   6b,7b
163         .previous
164
165         .align 4
166         .text
167         .globl __strncpy_from_user_asm
168         # %r2 = count, %r3 = dst, %r4 = src
169 __strncpy_from_user_asm:
170         lhi     %r0,0
171         lr      %r1,%r4
172         la      %r4,0(%r4)      # clear high order bit from %r4
173         la      %r2,0(%r2,%r4)  # %r2 points to first byte after string
174         sacf    256
175 0:      srst    %r2,%r1
176         jo      0b
177         sacf    0
178         lr      %r1,%r2
179         jh      1f              # \0 found in string ?
180         ahi     %r1,1           # include \0 in copy
181 1:      slr     %r1,%r4         # %r1 = copy length (without \0)
182         slr     %r2,%r4         # %r2 = return length (including \0)
183 2:      mvcp    0(%r1,%r3),0(%r4),%r0
184         jnz     3f
185         br      %r14
186 3:      la      %r3,256(%r3)
187         la      %r4,256(%r4)
188         ahi     %r1,-256
189         mvcp    0(%r1,%r3),0(%r4),%r0
190         jnz     3b
191         br      %r14
192 4:      sacf    0
193         lhi     %r2,-EFAULT
194         br      %r14
195         .section __ex_table,"a"
196         .long   0b,4b
197         .previous
198
199         .align 4
200         .text
201         .globl __strnlen_user_asm
202         # %r2 = count, %r3 = src
203 __strnlen_user_asm:
204         lhi     %r0,0
205         lr      %r1,%r3
206         la      %r3,0(%r3)      # clear high order bit from %r4
207         la      %r2,0(%r2,%r3)  # %r2 points to first byte after string
208         sacf    256
209 0:      srst    %r2,%r1
210         jo      0b
211         sacf    0
212         ahi     %r2,1           # strnlen_user result includes the \0
213                                 # or return count+1 if \0 not found
214         slr     %r2,%r3
215         br      %r14
216 2:      sacf    0
217         slr     %r2,%r2         # return 0 on exception
218         br      %r14
219         .section __ex_table,"a"
220         .long   0b,2b
221         .previous