Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/parisc/lib/lusercopy.S
10817 views
1
/*
2
* User Space Access Routines
3
*
4
* Copyright (C) 2000-2002 Hewlett-Packard (John Marvin)
5
* Copyright (C) 2000 Richard Hirst <rhirst with parisc-linux.org>
6
* Copyright (C) 2001 Matthieu Delahaye <delahaym at esiee.fr>
7
* Copyright (C) 2003 Randolph Chung <tausq with parisc-linux.org>
8
*
9
*
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2, or (at your option)
13
* any later version.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
19
*
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
*/
24
25
/*
26
* These routines still have plenty of room for optimization
27
* (word & doubleword load/store, dual issue, store hints, etc.).
28
*/
29
30
/*
31
* The following routines assume that space register 3 (sr3) contains
32
* the space id associated with the current users address space.
33
*/
34
35
36
.text
37
38
#include <asm/assembly.h>
39
#include <asm/errno.h>
40
#include <linux/linkage.h>
41
42
/*
43
* get_sr gets the appropriate space value into
44
* sr1 for kernel/user space access, depending
45
* on the flag stored in the task structure.
46
*/
47
48
.macro get_sr
49
mfctl %cr30,%r1
50
ldw TI_SEGMENT(%r1),%r22
51
mfsp %sr3,%r1
52
or,<> %r22,%r0,%r0
53
copy %r0,%r1
54
mtsp %r1,%sr1
55
.endm
56
57
.macro fixup_branch lbl
58
ldil L%\lbl, %r1
59
ldo R%\lbl(%r1), %r1
60
bv %r0(%r1)
61
.endm
62
63
/*
64
* long lstrncpy_from_user(char *dst, const char *src, long n)
65
*
66
* Returns -EFAULT if exception before terminator,
67
* N if the entire buffer filled,
68
* otherwise strlen (i.e. excludes zero byte)
69
*/
70
71
ENTRY(lstrncpy_from_user)
72
.proc
73
.callinfo NO_CALLS
74
.entry
75
comib,= 0,%r24,$lsfu_done
76
copy %r24,%r23
77
get_sr
78
1: ldbs,ma 1(%sr1,%r25),%r1
79
$lsfu_loop:
80
stbs,ma %r1,1(%r26)
81
comib,=,n 0,%r1,$lsfu_done
82
addib,<>,n -1,%r24,$lsfu_loop
83
2: ldbs,ma 1(%sr1,%r25),%r1
84
$lsfu_done:
85
sub %r23,%r24,%r28
86
$lsfu_exit:
87
bv %r0(%r2)
88
nop
89
.exit
90
ENDPROC(lstrncpy_from_user)
91
92
.section .fixup,"ax"
93
3: fixup_branch $lsfu_exit
94
ldi -EFAULT,%r28
95
.previous
96
97
.section __ex_table,"aw"
98
ASM_ULONG_INSN 1b,3b
99
ASM_ULONG_INSN 2b,3b
100
.previous
101
102
.procend
103
104
/*
105
* unsigned long lclear_user(void *to, unsigned long n)
106
*
107
* Returns 0 for success.
108
* otherwise, returns number of bytes not transferred.
109
*/
110
111
ENTRY(lclear_user)
112
.proc
113
.callinfo NO_CALLS
114
.entry
115
comib,=,n 0,%r25,$lclu_done
116
get_sr
117
$lclu_loop:
118
addib,<> -1,%r25,$lclu_loop
119
1: stbs,ma %r0,1(%sr1,%r26)
120
121
$lclu_done:
122
bv %r0(%r2)
123
copy %r25,%r28
124
.exit
125
ENDPROC(lclear_user)
126
127
.section .fixup,"ax"
128
2: fixup_branch $lclu_done
129
ldo 1(%r25),%r25
130
.previous
131
132
.section __ex_table,"aw"
133
ASM_ULONG_INSN 1b,2b
134
.previous
135
136
.procend
137
138
/*
139
* long lstrnlen_user(char *s, long n)
140
*
141
* Returns 0 if exception before zero byte or reaching N,
142
* N+1 if N would be exceeded,
143
* else strlen + 1 (i.e. includes zero byte).
144
*/
145
146
ENTRY(lstrnlen_user)
147
.proc
148
.callinfo NO_CALLS
149
.entry
150
comib,= 0,%r25,$lslen_nzero
151
copy %r26,%r24
152
get_sr
153
1: ldbs,ma 1(%sr1,%r26),%r1
154
$lslen_loop:
155
comib,=,n 0,%r1,$lslen_done
156
addib,<> -1,%r25,$lslen_loop
157
2: ldbs,ma 1(%sr1,%r26),%r1
158
$lslen_done:
159
bv %r0(%r2)
160
sub %r26,%r24,%r28
161
.exit
162
163
$lslen_nzero:
164
b $lslen_done
165
ldo 1(%r26),%r26 /* special case for N == 0 */
166
ENDPROC(lstrnlen_user)
167
168
.section .fixup,"ax"
169
3: fixup_branch $lslen_done
170
copy %r24,%r26 /* reset r26 so 0 is returned on fault */
171
.previous
172
173
.section __ex_table,"aw"
174
ASM_ULONG_INSN 1b,3b
175
ASM_ULONG_INSN 2b,3b
176
.previous
177
178
.procend
179
180
.end
181
182