xref: /openbmc/linux/arch/arm64/lib/copy_to_user.S (revision 139f9ab7)
1caab277bSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
20aea86a2SCatalin Marinas/*
30aea86a2SCatalin Marinas * Copyright (C) 2012 ARM Ltd.
40aea86a2SCatalin Marinas */
50aea86a2SCatalin Marinas
60aea86a2SCatalin Marinas#include <linux/linkage.h>
7338d4f49SJames Morse
8b4b8664dSAl Viro#include <asm/asm-uaccess.h>
956c08ec5SMark Rutland#include <asm/assembler.h>
1056c08ec5SMark Rutland#include <asm/cache.h>
110aea86a2SCatalin Marinas
120aea86a2SCatalin Marinas/*
130aea86a2SCatalin Marinas * Copy to user space from a kernel buffer (alignment handled by the hardware)
140aea86a2SCatalin Marinas *
150aea86a2SCatalin Marinas * Parameters:
160aea86a2SCatalin Marinas *	x0 - to
170aea86a2SCatalin Marinas *	x1 - from
180aea86a2SCatalin Marinas *	x2 - n
190aea86a2SCatalin Marinas * Returns:
200aea86a2SCatalin Marinas *	x0 - bytes not copied
210aea86a2SCatalin Marinas */
22ada66f18SCatalin Marinas	.macro ldrb1 reg, ptr, val
23ada66f18SCatalin Marinas	ldrb  \reg, [\ptr], \val
2440426882SFeng Kan	.endm
2540426882SFeng Kan
26ada66f18SCatalin Marinas	.macro strb1 reg, ptr, val
277b90dc40SMark Rutland	user_ldst 9998f, sttrb, \reg, \ptr, \val
2840426882SFeng Kan	.endm
2940426882SFeng Kan
30ada66f18SCatalin Marinas	.macro ldrh1 reg, ptr, val
31ada66f18SCatalin Marinas	ldrh  \reg, [\ptr], \val
3240426882SFeng Kan	.endm
3340426882SFeng Kan
34ada66f18SCatalin Marinas	.macro strh1 reg, ptr, val
35295cf156SRobin Murphy	user_ldst 9997f, sttrh, \reg, \ptr, \val
3640426882SFeng Kan	.endm
3740426882SFeng Kan
38ada66f18SCatalin Marinas	.macro ldr1 reg, ptr, val
39ada66f18SCatalin Marinas	ldr \reg, [\ptr], \val
4040426882SFeng Kan	.endm
4140426882SFeng Kan
42ada66f18SCatalin Marinas	.macro str1 reg, ptr, val
43295cf156SRobin Murphy	user_ldst 9997f, sttr, \reg, \ptr, \val
4440426882SFeng Kan	.endm
4540426882SFeng Kan
46ada66f18SCatalin Marinas	.macro ldp1 reg1, reg2, ptr, val
47ada66f18SCatalin Marinas	ldp \reg1, \reg2, [\ptr], \val
4840426882SFeng Kan	.endm
4940426882SFeng Kan
50ada66f18SCatalin Marinas	.macro stp1 reg1, reg2, ptr, val
51295cf156SRobin Murphy	user_stp 9997f, \reg1, \reg2, \ptr, \val
5240426882SFeng Kan	.endm
5340426882SFeng Kan
5440426882SFeng Kanend	.req	x5
55295cf156SRobin Murphysrcin	.req	x15
563ac0f452SMark BrownSYM_FUNC_START(__arch_copy_to_user)
5740426882SFeng Kan	add	end, x0, x2
58295cf156SRobin Murphy	mov	srcin, x1
5940426882SFeng Kan#include "copy_template.S"
6040426882SFeng Kan	mov	x0, #0
610aea86a2SCatalin Marinas	ret
620aea86a2SCatalin Marinas
63*139f9ab7SMark Rutland	// Exception fixups
64295cf156SRobin Murphy9997:	cmp	dst, dstin
65295cf156SRobin Murphy	b.ne	9998f
66295cf156SRobin Murphy	// Before being absolutely sure we couldn't copy anything, try harder
67295cf156SRobin Murphy	ldrb	tmp1w, [srcin]
68295cf156SRobin MurphyUSER(9998f, sttrb tmp1w, [dst])
69295cf156SRobin Murphy	add	dst, dst, #1
7040426882SFeng Kan9998:	sub	x0, end, dst			// bytes not copied
710aea86a2SCatalin Marinas	ret
72*139f9ab7SMark RutlandSYM_FUNC_END(__arch_copy_to_user)
73*139f9ab7SMark RutlandEXPORT_SYMBOL(__arch_copy_to_user)
74