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