18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copy from user space to user space
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2012 ARM Ltd.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <linux/linkage.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include <asm/asm-uaccess.h>
118c2ecf20Sopenharmony_ci#include <asm/assembler.h>
128c2ecf20Sopenharmony_ci#include <asm/cache.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci/*
158c2ecf20Sopenharmony_ci * Copy from user space to user space (alignment handled by the hardware)
168c2ecf20Sopenharmony_ci *
178c2ecf20Sopenharmony_ci * Parameters:
188c2ecf20Sopenharmony_ci *	x0 - to
198c2ecf20Sopenharmony_ci *	x1 - from
208c2ecf20Sopenharmony_ci *	x2 - n
218c2ecf20Sopenharmony_ci * Returns:
228c2ecf20Sopenharmony_ci *	x0 - bytes not copied
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci	.macro ldrb1 reg, ptr, val
258c2ecf20Sopenharmony_ci	uao_user_alternative 9998f, ldrb, ldtrb, \reg, \ptr, \val
268c2ecf20Sopenharmony_ci	.endm
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	.macro strb1 reg, ptr, val
298c2ecf20Sopenharmony_ci	uao_user_alternative 9998f, strb, sttrb, \reg, \ptr, \val
308c2ecf20Sopenharmony_ci	.endm
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	.macro ldrh1 reg, ptr, val
338c2ecf20Sopenharmony_ci	uao_user_alternative 9997f, ldrh, ldtrh, \reg, \ptr, \val
348c2ecf20Sopenharmony_ci	.endm
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	.macro strh1 reg, ptr, val
378c2ecf20Sopenharmony_ci	uao_user_alternative 9997f, strh, sttrh, \reg, \ptr, \val
388c2ecf20Sopenharmony_ci	.endm
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	.macro ldr1 reg, ptr, val
418c2ecf20Sopenharmony_ci	uao_user_alternative 9997f, ldr, ldtr, \reg, \ptr, \val
428c2ecf20Sopenharmony_ci	.endm
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	.macro str1 reg, ptr, val
458c2ecf20Sopenharmony_ci	uao_user_alternative 9997f, str, sttr, \reg, \ptr, \val
468c2ecf20Sopenharmony_ci	.endm
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	.macro ldp1 reg1, reg2, ptr, val
498c2ecf20Sopenharmony_ci	uao_ldp 9997f, \reg1, \reg2, \ptr, \val
508c2ecf20Sopenharmony_ci	.endm
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	.macro stp1 reg1, reg2, ptr, val
538c2ecf20Sopenharmony_ci	uao_stp 9997f, \reg1, \reg2, \ptr, \val
548c2ecf20Sopenharmony_ci	.endm
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ciend	.req	x5
578c2ecf20Sopenharmony_cisrcin	.req	x15
588c2ecf20Sopenharmony_ciSYM_FUNC_START(__arch_copy_in_user)
598c2ecf20Sopenharmony_ci	add	end, x0, x2
608c2ecf20Sopenharmony_ci	mov	srcin, x1
618c2ecf20Sopenharmony_ci#include "copy_template.S"
628c2ecf20Sopenharmony_ci	mov	x0, #0
638c2ecf20Sopenharmony_ci	ret
648c2ecf20Sopenharmony_ciSYM_FUNC_END(__arch_copy_in_user)
658c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__arch_copy_in_user)
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	.section .fixup,"ax"
688c2ecf20Sopenharmony_ci	.align	2
698c2ecf20Sopenharmony_ci9997:	cmp	dst, dstin
708c2ecf20Sopenharmony_ci	b.ne	9998f
718c2ecf20Sopenharmony_ci	// Before being absolutely sure we couldn't copy anything, try harder
728c2ecf20Sopenharmony_ciUSER(9998f, ldtrb tmp1w, [srcin])
738c2ecf20Sopenharmony_ciUSER(9998f, sttrb tmp1w, [dst])
748c2ecf20Sopenharmony_ci	add	dst, dst, #1
758c2ecf20Sopenharmony_ci9998:	sub	x0, end, dst			// bytes not copied
768c2ecf20Sopenharmony_ci	ret
778c2ecf20Sopenharmony_ci	.previous
78