root/arch/arm/lib/copy_from_user.S

/* [<][>][^][v][top][bottom][index][help] */
   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 
 110 ENTRY(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 
 119 ENDPROC(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 

/* [<][>][^][v][top][bottom][index][help] */