Back to home page

OSCL-LXR

 
 

    


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