root/arch/arm/lib/copy_to_user.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  *  linux/arch/arm/lib/copy_to_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_to_user(void *to, const void *from, size_t n)
  18  *
  19  * Purpose:
  20  *
  21  *      copy a block to user memory from kernel memory
  22  *
  23  * Params:
  24  *
  25  *      to = user memory
  26  *      from = kernel memory
  27  *      n = number of bytes to copy
  28  *
  29  * Return value:
  30  *
  31  *      Number of bytes NOT copied.
  32  */
  33 
  34 #define LDR1W_SHIFT     0
  35 
  36         .macro ldr1w ptr reg abort
  37         W(ldr) \reg, [\ptr], #4
  38         .endm
  39 
  40         .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
  41         ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
  42         .endm
  43 
  44         .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
  45         ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
  46         .endm
  47 
  48         .macro ldr1b ptr reg cond=al abort
  49         ldrb\cond \reg, [\ptr], #1
  50         .endm
  51 
  52 #ifdef CONFIG_CPU_USE_DOMAINS
  53 
  54 #ifndef CONFIG_THUMB2_KERNEL
  55 #define STR1W_SHIFT     0
  56 #else
  57 #define STR1W_SHIFT     1
  58 #endif
  59 
  60         .macro str1w ptr reg abort
  61         strusr  \reg, \ptr, 4, abort=\abort
  62         .endm
  63 
  64         .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
  65         str1w \ptr, \reg1, \abort
  66         str1w \ptr, \reg2, \abort
  67         str1w \ptr, \reg3, \abort
  68         str1w \ptr, \reg4, \abort
  69         str1w \ptr, \reg5, \abort
  70         str1w \ptr, \reg6, \abort
  71         str1w \ptr, \reg7, \abort
  72         str1w \ptr, \reg8, \abort
  73         .endm
  74 
  75 #else
  76 
  77 #define STR1W_SHIFT     0
  78 
  79         .macro str1w ptr reg abort
  80         USERL(\abort, W(str) \reg, [\ptr], #4)
  81         .endm
  82 
  83         .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
  84         USERL(\abort, stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8})
  85         .endm
  86 
  87 #endif /* CONFIG_CPU_USE_DOMAINS */
  88 
  89         .macro str1b ptr reg cond=al abort
  90         strusr  \reg, \ptr, 1, \cond, abort=\abort
  91         .endm
  92 
  93         .macro enter reg1 reg2
  94         mov     r3, #0
  95         stmdb   sp!, {r0, r2, r3, \reg1, \reg2}
  96         .endm
  97 
  98         .macro usave reg1 reg2
  99         UNWIND( .save {r0, r2, r3, \reg1, \reg2}        )
 100         .endm
 101 
 102         .macro exit reg1 reg2
 103         add     sp, sp, #8
 104         ldmfd   sp!, {r0, \reg1, \reg2}
 105         .endm
 106 
 107         .text
 108 
 109 ENTRY(__copy_to_user_std)
 110 WEAK(arm_copy_to_user)
 111 #ifdef CONFIG_CPU_SPECTRE
 112         get_thread_info r3
 113         ldr     r3, [r3, #TI_ADDR_LIMIT]
 114         uaccess_mask_range_ptr r0, r2, r3, ip
 115 #endif
 116 
 117 #include "copy_template.S"
 118 
 119 ENDPROC(arm_copy_to_user)
 120 ENDPROC(__copy_to_user_std)
 121 
 122         .pushsection .text.fixup,"ax"
 123         .align 0
 124         copy_abort_preamble
 125         ldmfd   sp!, {r1, r2, r3}
 126         sub     r0, r0, r1
 127         rsb     r0, r0, r2
 128         copy_abort_end
 129         .popsection

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