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 reg1 reg2 95 mov r3, #0 96 stmdb sp!, {r0, r2, r3, \reg1, \reg2} 97 .endm 98 99 .macro usave reg1 reg2 100 UNWIND( .save {r0, r2, r3, \reg1, \reg2} ) 101 .endm 102 103 .macro exit reg1 reg2 104 add sp, sp, #8 105 ldmfd sp!, {r0, \reg1, \reg2} 106 .endm 107 108 .text 109 110ENTRY(arm_copy_from_user) 111#ifdef CONFIG_CPU_SPECTRE 112 get_thread_info r3 113 ldr r3, [r3, #TI_ADDR_LIMIT] 114 uaccess_mask_range_ptr r1, r2, r3, ip 115#endif 116 117#include "copy_template.S" 118 119ENDPROC(arm_copy_from_user) 120 121 .pushsection .text.fixup,"ax" 122 .align 0 123 copy_abort_preamble 124 ldmfd sp!, {r1, r2, r3} 125 sub r0, r0, r1 126 rsb r0, r0, r2 127 copy_abort_end 128 .popsection 129 130