| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /* |
| 3 | * Copyright (C) 2012 ARM Ltd. |
| 4 | */ |
| 5 | |
| 6 | #include <linux/linkage.h> |
| 7 | |
| 8 | #include <asm/asm-uaccess.h> |
| 9 | #include <asm/assembler.h> |
| 10 | #include <asm/cache.h> |
| 11 | |
| 12 | /* |
| 13 | * Copy from user space to a kernel buffer (alignment handled by the hardware) |
| 14 | * |
| 15 | * Parameters: |
| 16 | * x0 - to |
| 17 | * x1 - from |
| 18 | * x2 - n |
| 19 | * Returns: |
| 20 | * x0 - bytes not copied |
| 21 | */ |
| 22 | |
| 23 | .macro ldrb1 reg, ptr, val |
| 24 | user_ldst 9998f, ldtrb, \reg, \ptr, \val |
| 25 | .endm |
| 26 | |
| 27 | .macro strb1 reg, ptr, val |
| 28 | strb \reg, [\ptr], \val |
| 29 | .endm |
| 30 | |
| 31 | .macro ldrh1 reg, ptr, val |
| 32 | user_ldst 9997f, ldtrh, \reg, \ptr, \val |
| 33 | .endm |
| 34 | |
| 35 | .macro strh1 reg, ptr, val |
| 36 | strh \reg, [\ptr], \val |
| 37 | .endm |
| 38 | |
| 39 | .macro ldr1 reg, ptr, val |
| 40 | user_ldst 9997f, ldtr, \reg, \ptr, \val |
| 41 | .endm |
| 42 | |
| 43 | .macro str1 reg, ptr, val |
| 44 | str \reg, [\ptr], \val |
| 45 | .endm |
| 46 | |
| 47 | .macro ldp1 reg1, reg2, ptr, val |
| 48 | user_ldp 9997f, \reg1, \reg2, \ptr, \val |
| 49 | .endm |
| 50 | |
| 51 | .macro stp1 reg1, reg2, ptr, val |
| 52 | stp \reg1, \reg2, [\ptr], \val |
| 53 | .endm |
| 54 | |
| 55 | .macro cpy1 dst, src, count |
| 56 | .arch_extension mops |
| 57 | USER_CPY(9997f, 0, cpyfprt [\dst]!, [\src]!, \count!) |
| 58 | USER_CPY(9996f, 0, cpyfmrt [\dst]!, [\src]!, \count!) |
| 59 | USER_CPY(9996f, 0, cpyfert [\dst]!, [\src]!, \count!) |
| 60 | .endm |
| 61 | |
| 62 | end .req x5 |
| 63 | srcin .req x15 |
| 64 | SYM_FUNC_START(__arch_copy_from_user) |
| 65 | add end, x0, x2 |
| 66 | mov srcin, x1 |
| 67 | #include "copy_template.S" |
| 68 | mov x0, #0 // Nothing to copy |
| 69 | ret |
| 70 | |
| 71 | // Exception fixups |
| 72 | 9996: b.cs 9997f |
| 73 | // Registers are in Option A format |
| 74 | add dst, dst, count |
| 75 | 9997: cmp dst, dstin |
| 76 | b.ne 9998f |
| 77 | // Before being absolutely sure we couldn't copy anything, try harder |
| 78 | USER(9998f, ldtrb tmp1w, [srcin]) |
| 79 | strb tmp1w, [dst], #1 |
| 80 | 9998: sub x0, end, dst // bytes not copied |
| 81 | ret |
| 82 | SYM_FUNC_END(__arch_copy_from_user) |
| 83 | EXPORT_SYMBOL(__arch_copy_from_user) |
| 84 | |