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#ifndef CONFIG_THUMB2_KERNEL 38#define LDR1W_SHIFT 0 39#else 40#define LDR1W_SHIFT 1 41#endif 42#define STR1W_SHIFT 0 43 44 .macro ldr1w ptr reg abort 45 ldrusr \reg, \ptr, 4, abort=\abort 46 .endm 47 48 .macro ldr4w ptr reg1 reg2 reg3 reg4 abort 49 ldr1w \ptr, \reg1, \abort 50 ldr1w \ptr, \reg2, \abort 51 ldr1w \ptr, \reg3, \abort 52 ldr1w \ptr, \reg4, \abort 53 .endm 54 55 .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 56 ldr4w \ptr, \reg1, \reg2, \reg3, \reg4, \abort 57 ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort 58 .endm 59 60 .macro ldr1b ptr reg cond=al abort 61 ldrusr \reg, \ptr, 1, \cond, abort=\abort 62 .endm 63 64 .macro str1w ptr reg abort 65 W(str) \reg, [\ptr], #4 66 .endm 67 68 .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort 69 stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8} 70 .endm 71 72 .macro str1b ptr reg cond=al abort 73 str\cond\()b \reg, [\ptr], #1 74 .endm 75 76 .macro enter reg1 reg2 77 mov r3, #0 78 stmdb sp!, {r0, r2, r3, \reg1, \reg2} 79 .endm 80 81 .macro usave reg1 reg2 82 UNWIND( .save {r0, r2, r3, \reg1, \reg2} ) 83 .endm 84 85 .macro exit reg1 reg2 86 add sp, sp, #8 87 ldmfd sp!, {r0, \reg1, \reg2} 88 .endm 89 90 .text 91 92ENTRY(arm_copy_from_user) 93#ifdef CONFIG_CPU_SPECTRE 94 get_thread_info r3 95 ldr r3, [r3, #TI_ADDR_LIMIT] 96 adds ip, r1, r2 @ ip=addr+size 97 sub r3, r3, #1 @ addr_limit - 1 98 cmpcc ip, r3 @ if (addr+size > addr_limit - 1) 99 movcs r1, #0 @ addr = NULL 100 csdb 101#endif 102 103#include "copy_template.S" 104 105ENDPROC(arm_copy_from_user) 106 107 .pushsection .fixup,"ax" 108 .align 0 109 copy_abort_preamble 110 ldmfd sp!, {r1, r2, r3} 111 sub r0, r0, r1 112 rsb r0, r0, r2 113 copy_abort_end 114 .popsection 115 116