Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[pandora-kernel.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 6:      lr      %r2,%r3
44         br      %r14
45         .section __ex_table,"a"
46         .long   0b,4b
47         .long   2b,4b
48         .long   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         slr     %r0,%r0
57 0:      mvcs    0(%r3,%r4),0(%r2),%r0
58         jnz     1f
59         slr     %r2,%r2
60         br      %r14
61 1:      la      %r2,256(%r2)
62         la      %r4,256(%r4)
63         ahi     %r3,-256
64 2:      mvcs    0(%r3,%r4),0(%r2),%r0
65         jnz     1b
66 3:      slr     %r2,%r2
67         br      %r14
68 4:      lhi     %r0,-4096
69         lr      %r5,%r4
70         slr     %r5,%r0
71         nr      %r5,%r0         # %r5 = (%r4 + 4096) & -4096
72         slr     %r5,%r4         # %r5 = #bytes to next user page boundary
73         clr     %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         slr     %r3,%r5
78 6:      lr      %r2,%r3
79         br      %r14
80         .section __ex_table,"a"
81         .long   0b,4b
82         .long   2b,4b
83         .long   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         ahi     %r3,-1
92         jo      6f
93         sacf    256
94         bras    %r1,4f
95 0:      ahi     %r3,257
96 1:      mvc     0(1,%r4),0(%r2)
97         la      %r2,1(%r2)
98         la      %r4,1(%r4)
99         ahi     %r3,-1
100         jnz     1b
101 2:      lr      %r2,%r3
102         br      %r14
103 3:      mvc     0(256,%r4),0(%r2)
104         la      %r2,256(%r2)
105         la      %r4,256(%r4)
106 4:      ahi     %r3,-256
107         jnm     3b
108 5:      ex      %r3,4(%r1)
109         sacf    0
110 6:      slr     %r2,%r2
111         br      %r14
112         .section __ex_table,"a"
113         .long   1b,2b
114         .long   3b,0b
115         .long   5b,0b
116         .previous
117
118         .align 4
119         .text
120         .globl __clear_user_asm
121         # %r2 = to, %r3 = n
122 __clear_user_asm:
123         bras    %r5,0f
124         .long   empty_zero_page
125 0:      l       %r5,0(%r5)
126         slr     %r0,%r0
127 1:      mvcs    0(%r3,%r2),0(%r5),%r0
128         jnz     2f
129         slr     %r2,%r2
130         br      %r14
131 2:      la      %r2,256(%r2)
132         ahi     %r3,-256
133 3:      mvcs    0(%r3,%r2),0(%r5),%r0
134         jnz     2b
135 4:      slr     %r2,%r2
136         br      %r14
137 5:      lhi     %r0,-4096
138         lr      %r4,%r2
139         slr     %r4,%r0
140         nr      %r4,%r0         # %r4 = (%r2 + 4096) & -4096
141         slr     %r4,%r2         # %r4 = #bytes to next user page boundary
142         clr     %r3,%r4         # clear crosses next page boundary ?
143         jnh     7f              # no, the current page faulted
144         # clear with the reduced length which is < 256
145 6:      mvcs    0(%r4,%r2),0(%r5),%r0
146         slr     %r3,%r4
147 7:      lr      %r2,%r3
148         br      %r14
149         .section __ex_table,"a"
150         .long   1b,5b
151         .long   3b,5b
152         .long   6b,7b
153         .previous
154
155         .align 4
156         .text
157         .globl __strncpy_from_user_asm
158         # %r2 = count, %r3 = dst, %r4 = src
159 __strncpy_from_user_asm:
160         lhi     %r0,0
161         lr      %r1,%r4
162         la      %r4,0(%r4)      # clear high order bit from %r4
163         la      %r2,0(%r2,%r4)  # %r2 points to first byte after string
164         sacf    256
165 0:      srst    %r2,%r1
166         jo      0b
167         sacf    0
168         lr      %r1,%r2
169         jh      1f              # \0 found in string ?
170         ahi     %r1,1           # include \0 in copy
171 1:      slr     %r1,%r4         # %r1 = copy length (without \0)
172         slr     %r2,%r4         # %r2 = return length (including \0)
173 2:      mvcp    0(%r1,%r3),0(%r4),%r0
174         jnz     3f
175         br      %r14
176 3:      la      %r3,256(%r3)
177         la      %r4,256(%r4)
178         ahi     %r1,-256
179         mvcp    0(%r1,%r3),0(%r4),%r0
180         jnz     3b
181         br      %r14
182 4:      sacf    0
183         lhi     %r2,-EFAULT
184         br      %r14
185         .section __ex_table,"a"
186         .long   0b,4b
187         .previous
188
189         .align 4
190         .text
191         .globl __strnlen_user_asm
192         # %r2 = count, %r3 = src
193 __strnlen_user_asm:
194         lhi     %r0,0
195         lr      %r1,%r3
196         la      %r3,0(%r3)      # clear high order bit from %r4
197         la      %r2,0(%r2,%r3)  # %r2 points to first byte after string
198         sacf    256
199 0:      srst    %r2,%r1
200         jo      0b
201         sacf    0
202         ahi     %r2,1           # strnlen_user result includes the \0
203                                 # or return count+1 if \0 not found
204         slr     %r2,%r3
205         br      %r14
206 2:      sacf    0
207         slr     %r2,%r2         # return 0 on exception
208         br      %r14
209         .section __ex_table,"a"
210         .long   0b,2b
211         .previous