linux/arch/arm/lib/copy_from_user.S
<<
>>
Prefs
   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