2 * linux/arch/arm/lib/copy_to_user.S
4 * Author: Nicolas Pitre
5 * Created: Sep 29, 2005
6 * Copyright: MontaVista Software, Inc.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
13 #include <linux/linkage.h>
14 #include <asm/assembler.h>
15 #include <asm/unwind.h>
20 * size_t arm_copy_to_user(void *to, const void *from, size_t n)
24 * copy a block to user memory from kernel memory
29 * from = kernel memory
30 * n = number of bytes to copy
34 * Number of bytes NOT copied.
39 .macro ldr1w ptr reg abort
40 W(ldr) \reg, [\ptr], #4
43 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
44 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
47 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
48 ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
51 .macro ldr1b ptr reg cond=al abort
52 ldr\cond\()b \reg, [\ptr], #1
55 #ifdef CONFIG_CPU_USE_DOMAINS
57 #ifndef CONFIG_THUMB2_KERNEL
63 .macro str1w ptr reg abort
64 strusr \reg, \ptr, 4, abort=\abort
67 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
68 str1w \ptr, \reg1, \abort
69 str1w \ptr, \reg2, \abort
70 str1w \ptr, \reg3, \abort
71 str1w \ptr, \reg4, \abort
72 str1w \ptr, \reg5, \abort
73 str1w \ptr, \reg6, \abort
74 str1w \ptr, \reg7, \abort
75 str1w \ptr, \reg8, \abort
82 .macro str1w ptr reg abort
83 USERL(\abort, W(str) \reg, [\ptr], #4)
86 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
87 USERL(\abort, stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
90 #endif /* CONFIG_CPU_USE_DOMAINS */
92 .macro str1b ptr reg cond=al abort
93 strusr \reg, \ptr, 1, \cond, abort=\abort
96 .macro enter reg1 reg2
98 stmdb sp!, {r0, r2, r3, \reg1, \reg2}
101 .macro usave reg1 reg2
102 UNWIND( .save {r0, r2, r3, \reg1, \reg2} )
105 .macro exit reg1 reg2
107 ldmfd sp!, {r0, \reg1, \reg2}
112 ENTRY(__copy_to_user_std)
113 WEAK(arm_copy_to_user)
114 #ifdef CONFIG_CPU_SPECTRE
116 ldr r3, [r3, #TI_ADDR_LIMIT]
117 uaccess_mask_range_ptr r0, r2, r3, ip
120 #include "copy_template.S"
122 ENDPROC(arm_copy_to_user)
123 ENDPROC(__copy_to_user_std)
125 .pushsection .text.fixup,"ax"
128 ldmfd sp!, {r1, r2, r3}