xref: /openbmc/linux/arch/arm/lib/copy_to_user.S (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1d2912cb1SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
2fadab094SNicolas Pitre/*
3fadab094SNicolas Pitre *  linux/arch/arm/lib/copy_to_user.S
4fadab094SNicolas Pitre *
5fadab094SNicolas Pitre *  Author:	Nicolas Pitre
6fadab094SNicolas Pitre *  Created:	Sep 29, 2005
7fadab094SNicolas Pitre *  Copyright:	MontaVista Software, Inc.
8fadab094SNicolas Pitre */
9fadab094SNicolas Pitre
10fadab094SNicolas Pitre#include <linux/linkage.h>
11fadab094SNicolas Pitre#include <asm/assembler.h>
12279f487eSLin Yongting#include <asm/unwind.h>
13fadab094SNicolas Pitre
14fadab094SNicolas Pitre/*
15fadab094SNicolas Pitre * Prototype:
16fadab094SNicolas Pitre *
173fba7e23SRussell King *	size_t arm_copy_to_user(void *to, const void *from, size_t n)
18fadab094SNicolas Pitre *
19fadab094SNicolas Pitre * Purpose:
20fadab094SNicolas Pitre *
21fadab094SNicolas Pitre *	copy a block to user memory from kernel memory
22fadab094SNicolas Pitre *
23fadab094SNicolas Pitre * Params:
24fadab094SNicolas Pitre *
25fadab094SNicolas Pitre *	to = user memory
26fadab094SNicolas Pitre *	from = kernel memory
27fadab094SNicolas Pitre *	n = number of bytes to copy
28fadab094SNicolas Pitre *
29fadab094SNicolas Pitre * Return value:
30fadab094SNicolas Pitre *
31fadab094SNicolas Pitre *	Number of bytes NOT copied.
32fadab094SNicolas Pitre */
33fadab094SNicolas Pitre
348b592783SCatalin Marinas#define LDR1W_SHIFT	0
358b592783SCatalin Marinas
36fadab094SNicolas Pitre	.macro ldr1w ptr reg abort
378b592783SCatalin Marinas	W(ldr) \reg, [\ptr], #4
38fadab094SNicolas Pitre	.endm
39fadab094SNicolas Pitre
40fadab094SNicolas Pitre	.macro ldr4w ptr reg1 reg2 reg3 reg4 abort
41fadab094SNicolas Pitre	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
42fadab094SNicolas Pitre	.endm
43fadab094SNicolas Pitre
44fadab094SNicolas Pitre	.macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
45fadab094SNicolas Pitre	ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
46fadab094SNicolas Pitre	.endm
47fadab094SNicolas Pitre
48fadab094SNicolas Pitre	.macro ldr1b ptr reg cond=al abort
49a216376aSStefan Agner	ldrb\cond \reg, [\ptr], #1
50fadab094SNicolas Pitre	.endm
51fadab094SNicolas Pitre
52f441882aSVincent Whitchurch#ifdef CONFIG_CPU_USE_DOMAINS
53f441882aSVincent Whitchurch
54f441882aSVincent Whitchurch#ifndef CONFIG_THUMB2_KERNEL
55f441882aSVincent Whitchurch#define STR1W_SHIFT	0
56f441882aSVincent Whitchurch#else
57f441882aSVincent Whitchurch#define STR1W_SHIFT	1
58f441882aSVincent Whitchurch#endif
59f441882aSVincent Whitchurch
60fadab094SNicolas Pitre	.macro str1w ptr reg abort
618b592783SCatalin Marinas	strusr	\reg, \ptr, 4, abort=\abort
62fadab094SNicolas Pitre	.endm
63fadab094SNicolas Pitre
64fadab094SNicolas Pitre	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
65fadab094SNicolas Pitre	str1w \ptr, \reg1, \abort
66fadab094SNicolas Pitre	str1w \ptr, \reg2, \abort
67fadab094SNicolas Pitre	str1w \ptr, \reg3, \abort
68fadab094SNicolas Pitre	str1w \ptr, \reg4, \abort
69fadab094SNicolas Pitre	str1w \ptr, \reg5, \abort
70fadab094SNicolas Pitre	str1w \ptr, \reg6, \abort
71fadab094SNicolas Pitre	str1w \ptr, \reg7, \abort
72fadab094SNicolas Pitre	str1w \ptr, \reg8, \abort
73fadab094SNicolas Pitre	.endm
74fadab094SNicolas Pitre
75f441882aSVincent Whitchurch#else
76f441882aSVincent Whitchurch
77f441882aSVincent Whitchurch#define STR1W_SHIFT	0
78f441882aSVincent Whitchurch
79f441882aSVincent Whitchurch	.macro str1w ptr reg abort
80f441882aSVincent Whitchurch	USERL(\abort, W(str) \reg, [\ptr], #4)
81f441882aSVincent Whitchurch	.endm
82f441882aSVincent Whitchurch
83f441882aSVincent Whitchurch	.macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
84f441882aSVincent Whitchurch	USERL(\abort, stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
85f441882aSVincent Whitchurch	.endm
86f441882aSVincent Whitchurch
87f441882aSVincent Whitchurch#endif /* CONFIG_CPU_USE_DOMAINS */
88f441882aSVincent Whitchurch
89fadab094SNicolas Pitre	.macro str1b ptr reg cond=al abort
908b592783SCatalin Marinas	strusr	\reg, \ptr, 1, \cond, abort=\abort
91fadab094SNicolas Pitre	.endm
92fadab094SNicolas Pitre
93*ba999a04SArd Biesheuvel	.macro enter regs:vararg
94fadab094SNicolas Pitre	mov	r3, #0
95*ba999a04SArd BiesheuvelUNWIND( .save	{r0, r2, r3, \regs}		)
96*ba999a04SArd Biesheuvel	stmdb	sp!, {r0, r2, r3, \regs}
97fadab094SNicolas Pitre	.endm
98fadab094SNicolas Pitre
99*ba999a04SArd Biesheuvel	.macro exit regs:vararg
100fadab094SNicolas Pitre	add	sp, sp, #8
101*ba999a04SArd Biesheuvel	ldmfd	sp!, {r0, \regs}
102fadab094SNicolas Pitre	.endm
103fadab094SNicolas Pitre
104fadab094SNicolas Pitre	.text
105fadab094SNicolas Pitre
106a1f98849SNicolas PitreENTRY(__copy_to_user_std)
1073fba7e23SRussell KingWEAK(arm_copy_to_user)
108a1d09e07SJulien Thierry#ifdef CONFIG_CPU_SPECTRE
1098ac6f5d7SArnd Bergmann	ldr	r3, =TASK_SIZE
110a1d09e07SJulien Thierry	uaccess_mask_range_ptr r0, r2, r3, ip
111a1d09e07SJulien Thierry#endif
112fadab094SNicolas Pitre
113fadab094SNicolas Pitre#include "copy_template.S"
114fadab094SNicolas Pitre
1153fba7e23SRussell KingENDPROC(arm_copy_to_user)
116e814d826SCatalin MarinasENDPROC(__copy_to_user_std)
11793ed3970SCatalin Marinas
118c4a84ae3SArd Biesheuvel	.pushsection .text.fixup,"ax"
119fadab094SNicolas Pitre	.align 0
120fadab094SNicolas Pitre	copy_abort_preamble
121fadab094SNicolas Pitre	ldmfd	sp!, {r1, r2, r3}
122fadab094SNicolas Pitre	sub	r0, r0, r1
123fadab094SNicolas Pitre	rsb	r0, r0, r2
124fadab094SNicolas Pitre	copy_abort_end
1254260415fSRussell King	.popsection
126