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