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