xref: /linux/arch/arm64/lib/copy_from_user.S (revision 404268828c74ba06b1f21584b26edafb381c9d7d)
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
19338d4f49SJames Morse#include <asm/alternative.h>
200aea86a2SCatalin Marinas#include <asm/assembler.h>
21*40426882SFeng Kan#include <asm/cache.h>
22338d4f49SJames Morse#include <asm/cpufeature.h>
23338d4f49SJames Morse#include <asm/sysreg.h>
240aea86a2SCatalin Marinas
250aea86a2SCatalin Marinas/*
260aea86a2SCatalin Marinas * Copy from user space to a kernel buffer (alignment handled by the hardware)
270aea86a2SCatalin Marinas *
280aea86a2SCatalin Marinas * Parameters:
290aea86a2SCatalin Marinas *	x0 - to
300aea86a2SCatalin Marinas *	x1 - from
310aea86a2SCatalin Marinas *	x2 - n
320aea86a2SCatalin Marinas * Returns:
330aea86a2SCatalin Marinas *	x0 - bytes not copied
340aea86a2SCatalin Marinas */
35*40426882SFeng Kan
36*40426882SFeng Kan	.macro ldrb1 ptr, regB, val
37*40426882SFeng Kan	USER(9998f, ldrb  \ptr, [\regB], \val)
38*40426882SFeng Kan	.endm
39*40426882SFeng Kan
40*40426882SFeng Kan	.macro strb1 ptr, regB, val
41*40426882SFeng Kan	strb \ptr, [\regB], \val
42*40426882SFeng Kan	.endm
43*40426882SFeng Kan
44*40426882SFeng Kan	.macro ldrh1 ptr, regB, val
45*40426882SFeng Kan	USER(9998f, ldrh  \ptr, [\regB], \val)
46*40426882SFeng Kan	.endm
47*40426882SFeng Kan
48*40426882SFeng Kan	.macro strh1 ptr, regB, val
49*40426882SFeng Kan	strh \ptr, [\regB], \val
50*40426882SFeng Kan	.endm
51*40426882SFeng Kan
52*40426882SFeng Kan	.macro ldr1 ptr, regB, val
53*40426882SFeng Kan	USER(9998f, ldr \ptr, [\regB], \val)
54*40426882SFeng Kan	.endm
55*40426882SFeng Kan
56*40426882SFeng Kan	.macro str1 ptr, regB, val
57*40426882SFeng Kan	str \ptr, [\regB], \val
58*40426882SFeng Kan	.endm
59*40426882SFeng Kan
60*40426882SFeng Kan	.macro ldp1 ptr, regB, regC, val
61*40426882SFeng Kan	USER(9998f, ldp \ptr, \regB, [\regC], \val)
62*40426882SFeng Kan	.endm
63*40426882SFeng Kan
64*40426882SFeng Kan	.macro stp1 ptr, regB, regC, val
65*40426882SFeng Kan	stp \ptr, \regB, [\regC], \val
66*40426882SFeng Kan	.endm
67*40426882SFeng Kan
68*40426882SFeng Kanend	.req	x5
690aea86a2SCatalin MarinasENTRY(__copy_from_user)
70338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
71338d4f49SJames Morse	    CONFIG_ARM64_PAN)
72*40426882SFeng Kan	add	end, x0, x2
73*40426882SFeng Kan#include "copy_template.S"
74338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
75338d4f49SJames Morse	    CONFIG_ARM64_PAN)
76*40426882SFeng Kan	mov	x0, #0				// Nothing to copy
770aea86a2SCatalin Marinas	ret
780aea86a2SCatalin MarinasENDPROC(__copy_from_user)
790aea86a2SCatalin Marinas
800aea86a2SCatalin Marinas	.section .fixup,"ax"
810aea86a2SCatalin Marinas	.align	2
82*40426882SFeng Kan9998:
83*40426882SFeng Kan	sub	x0, end, dst
84*40426882SFeng Kan9999:
85*40426882SFeng Kan	strb	wzr, [dst], #1			// zero remaining buffer space
86*40426882SFeng Kan	cmp	dst, end
87*40426882SFeng Kan	b.lo	9999b
880aea86a2SCatalin Marinas	ret
890aea86a2SCatalin Marinas	.previous
90