Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-only */
0002 /*
0003  *  linux/arch/arm/lib/copy_from_user.S
0004  *
0005  *  Author: Nicolas Pitre
0006  *  Created:    Sep 29, 2005
0007  *  Copyright:  MontaVista Software, Inc.
0008  */
0009 
0010 #include <linux/linkage.h>
0011 #include <asm/assembler.h>
0012 #include <asm/unwind.h>
0013 
0014 /*
0015  * Prototype:
0016  *
0017  *  size_t arm_copy_from_user(void *to, const void *from, size_t n)
0018  *
0019  * Purpose:
0020  *
0021  *  copy a block to kernel memory from user memory
0022  *
0023  * Params:
0024  *
0025  *  to = kernel memory
0026  *  from = user memory
0027  *  n = number of bytes to copy
0028  *
0029  * Return value:
0030  *
0031  *  Number of bytes NOT copied.
0032  */
0033 
0034 #ifdef CONFIG_CPU_USE_DOMAINS
0035 
0036 #ifndef CONFIG_THUMB2_KERNEL
0037 #define LDR1W_SHIFT 0
0038 #else
0039 #define LDR1W_SHIFT 1
0040 #endif
0041 
0042     .macro ldr1w ptr reg abort
0043     ldrusr  \reg, \ptr, 4, abort=\abort
0044     .endm
0045 
0046     .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
0047     ldr1w \ptr, \reg1, \abort
0048     ldr1w \ptr, \reg2, \abort
0049     ldr1w \ptr, \reg3, \abort
0050     ldr1w \ptr, \reg4, \abort
0051     .endm
0052 
0053     .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
0054     ldr4w \ptr, \reg1, \reg2, \reg3, \reg4, \abort
0055     ldr4w \ptr, \reg5, \reg6, \reg7, \reg8, \abort
0056     .endm
0057 
0058 #else
0059 
0060 #define LDR1W_SHIFT 0
0061 
0062     .macro ldr1w ptr reg abort
0063     USERL(\abort, W(ldr) \reg, [\ptr], #4)
0064     .endm
0065 
0066     .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
0067     USERL(\abort, ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4})
0068     .endm
0069 
0070     .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
0071     USERL(\abort, ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
0072     .endm
0073 
0074 #endif /* CONFIG_CPU_USE_DOMAINS */
0075 
0076     .macro ldr1b ptr reg cond=al abort
0077     ldrusr  \reg, \ptr, 1, \cond, abort=\abort
0078     .endm
0079 
0080 #define STR1W_SHIFT 0
0081 
0082     .macro str1w ptr reg abort
0083     W(str) \reg, [\ptr], #4
0084     .endm
0085 
0086     .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
0087     stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
0088     .endm
0089 
0090     .macro str1b ptr reg cond=al abort
0091     strb\cond \reg, [\ptr], #1
0092     .endm
0093 
0094     .macro enter regs:vararg
0095     mov r3, #0
0096 UNWIND( .save   {r0, r2, r3, \regs}     )
0097     stmdb   sp!, {r0, r2, r3, \regs}
0098     .endm
0099 
0100     .macro exit regs:vararg
0101     add sp, sp, #8
0102     ldmfd   sp!, {r0, \regs}
0103     .endm
0104 
0105     .text
0106 
0107 ENTRY(arm_copy_from_user)
0108 #ifdef CONFIG_CPU_SPECTRE
0109     ldr r3, =TASK_SIZE
0110     uaccess_mask_range_ptr r1, r2, r3, ip
0111 #endif
0112 
0113 #include "copy_template.S"
0114 
0115 ENDPROC(arm_copy_from_user)
0116 
0117     .pushsection .text.fixup,"ax"
0118     .align 0
0119     copy_abort_preamble
0120     ldmfd   sp!, {r1, r2, r3}
0121     sub r0, r0, r1
0122     rsb r0, r0, r2
0123     copy_abort_end
0124     .popsection
0125