xref: /linux/arch/arm64/lib/copy_from_user.S (revision b4b8664d291ac1998e0f0bcdc96b6397f0fe68b3)
10aea86a2SCatalin Marinas/*
20aea86a2SCatalin Marinas * Copyright (C) 2012 ARM Ltd.
30aea86a2SCatalin Marinas *
40aea86a2SCatalin Marinas * This program is free software; you can redistribute it and/or modify
50aea86a2SCatalin Marinas * it under the terms of the GNU General Public License version 2 as
60aea86a2SCatalin Marinas * published by the Free Software Foundation.
70aea86a2SCatalin Marinas *
80aea86a2SCatalin Marinas * This program is distributed in the hope that it will be useful,
90aea86a2SCatalin Marinas * but WITHOUT ANY WARRANTY; without even the implied warranty of
100aea86a2SCatalin Marinas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
110aea86a2SCatalin Marinas * GNU General Public License for more details.
120aea86a2SCatalin Marinas *
130aea86a2SCatalin Marinas * You should have received a copy of the GNU General Public License
140aea86a2SCatalin Marinas * along with this program.  If not, see <http://www.gnu.org/licenses/>.
150aea86a2SCatalin Marinas */
160aea86a2SCatalin Marinas
170aea86a2SCatalin Marinas#include <linux/linkage.h>
18338d4f49SJames Morse
1940426882SFeng Kan#include <asm/cache.h>
20*b4b8664dSAl Viro#include <asm/asm-uaccess.h>
210aea86a2SCatalin Marinas
220aea86a2SCatalin Marinas/*
230aea86a2SCatalin Marinas * Copy from user space to a kernel buffer (alignment handled by the hardware)
240aea86a2SCatalin Marinas *
250aea86a2SCatalin Marinas * Parameters:
260aea86a2SCatalin Marinas *	x0 - to
270aea86a2SCatalin Marinas *	x1 - from
280aea86a2SCatalin Marinas *	x2 - n
290aea86a2SCatalin Marinas * Returns:
300aea86a2SCatalin Marinas *	x0 - bytes not copied
310aea86a2SCatalin Marinas */
3240426882SFeng Kan
3340426882SFeng Kan	.macro ldrb1 ptr, regB, val
3457f4959bSJames Morse	uao_user_alternative 9998f, ldrb, ldtrb, \ptr, \regB, \val
3540426882SFeng Kan	.endm
3640426882SFeng Kan
3740426882SFeng Kan	.macro strb1 ptr, regB, val
3840426882SFeng Kan	strb \ptr, [\regB], \val
3940426882SFeng Kan	.endm
4040426882SFeng Kan
4140426882SFeng Kan	.macro ldrh1 ptr, regB, val
4257f4959bSJames Morse	uao_user_alternative 9998f, ldrh, ldtrh, \ptr, \regB, \val
4340426882SFeng Kan	.endm
4440426882SFeng Kan
4540426882SFeng Kan	.macro strh1 ptr, regB, val
4640426882SFeng Kan	strh \ptr, [\regB], \val
4740426882SFeng Kan	.endm
4840426882SFeng Kan
4940426882SFeng Kan	.macro ldr1 ptr, regB, val
5057f4959bSJames Morse	uao_user_alternative 9998f, ldr, ldtr, \ptr, \regB, \val
5140426882SFeng Kan	.endm
5240426882SFeng Kan
5340426882SFeng Kan	.macro str1 ptr, regB, val
5440426882SFeng Kan	str \ptr, [\regB], \val
5540426882SFeng Kan	.endm
5640426882SFeng Kan
5740426882SFeng Kan	.macro ldp1 ptr, regB, regC, val
5857f4959bSJames Morse	uao_ldp 9998f, \ptr, \regB, \regC, \val
5940426882SFeng Kan	.endm
6040426882SFeng Kan
6140426882SFeng Kan	.macro stp1 ptr, regB, regC, val
6240426882SFeng Kan	stp \ptr, \regB, [\regC], \val
6340426882SFeng Kan	.endm
6440426882SFeng Kan
6540426882SFeng Kanend	.req	x5
66bffe1bafSYang ShiENTRY(__arch_copy_from_user)
67bd38967dSCatalin Marinas	uaccess_enable_not_uao x3, x4
6840426882SFeng Kan	add	end, x0, x2
6940426882SFeng Kan#include "copy_template.S"
70bd38967dSCatalin Marinas	uaccess_disable_not_uao x3
7140426882SFeng Kan	mov	x0, #0				// Nothing to copy
720aea86a2SCatalin Marinas	ret
73bffe1bafSYang ShiENDPROC(__arch_copy_from_user)
740aea86a2SCatalin Marinas
750aea86a2SCatalin Marinas	.section .fixup,"ax"
760aea86a2SCatalin Marinas	.align	2
774855bd25SAl Viro9998:	sub	x0, end, dst			// bytes not copied
780aea86a2SCatalin Marinas	ret
790aea86a2SCatalin Marinas	.previous
80