1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2012 ARM Ltd.
4  */
5 
6 #include <linux/linkage.h>
7 
8 #include <asm/asm-uaccess.h>
9 #include <asm/assembler.h>
10 #include <asm/cache.h>
11 
12 /*
13  * Copy to user space from a kernel buffer (alignment handled by the hardware)
14  *
15  * Parameters:
16  *	x0 - to
17  *	x1 - from
18  *	x2 - n
19  * Returns:
20  *	x0 - bytes not copied
21  */
22 	.macro ldrb1 reg, ptr, val
23 	ldrb  \reg, [\ptr], \val
24 	.endm
25 
26 	.macro strb1 reg, ptr, val
27 	uao_user_alternative 9998f, strb, sttrb, \reg, \ptr, \val
28 	.endm
29 
30 	.macro ldrh1 reg, ptr, val
31 	ldrh  \reg, [\ptr], \val
32 	.endm
33 
34 	.macro strh1 reg, ptr, val
35 	uao_user_alternative 9997f, strh, sttrh, \reg, \ptr, \val
36 	.endm
37 
38 	.macro ldr1 reg, ptr, val
39 	ldr \reg, [\ptr], \val
40 	.endm
41 
42 	.macro str1 reg, ptr, val
43 	uao_user_alternative 9997f, str, sttr, \reg, \ptr, \val
44 	.endm
45 
46 	.macro ldp1 reg1, reg2, ptr, val
47 	ldp \reg1, \reg2, [\ptr], \val
48 	.endm
49 
50 	.macro stp1 reg1, reg2, ptr, val
51 	uao_stp 9997f, \reg1, \reg2, \ptr, \val
52 	.endm
53 
54 end	.req	x5
55 srcin	.req	x15
56 SYM_FUNC_START(__arch_copy_to_user)
57 	add	end, x0, x2
58 	mov	srcin, x1
59 #include "copy_template.S"
60 	mov	x0, #0
61 	ret
62 SYM_FUNC_END(__arch_copy_to_user)
63 EXPORT_SYMBOL(__arch_copy_to_user)
64 
65 	.section .fixup,"ax"
66 	.align	2
67 9997:	cmp	dst, dstin
68 	b.ne	9998f
69 	// Before being absolutely sure we couldn't copy anything, try harder
70 	ldrb	tmp1w, [srcin]
71 USER(9998f, sttrb tmp1w, [dst])
72 	add	dst, dst, #1
73 9998:	sub	x0, end, dst			// bytes not copied
74 	ret
75 	.previous
76