xref: /openbmc/linux/arch/arm64/lib/clear_user.S (revision 338d4f49)
10aea86a2SCatalin Marinas/*
20aea86a2SCatalin Marinas * Based on arch/arm/lib/clear_user.S
30aea86a2SCatalin Marinas *
40aea86a2SCatalin Marinas * Copyright (C) 2012 ARM Ltd.
50aea86a2SCatalin Marinas *
60aea86a2SCatalin Marinas * This program is free software; you can redistribute it and/or modify
70aea86a2SCatalin Marinas * it under the terms of the GNU General Public License version 2 as
80aea86a2SCatalin Marinas * published by the Free Software Foundation.
90aea86a2SCatalin Marinas *
100aea86a2SCatalin Marinas * This program is distributed in the hope that it will be useful,
110aea86a2SCatalin Marinas * but WITHOUT ANY WARRANTY; without even the implied warranty of
120aea86a2SCatalin Marinas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
130aea86a2SCatalin Marinas * GNU General Public License for more details.
140aea86a2SCatalin Marinas *
150aea86a2SCatalin Marinas * You should have received a copy of the GNU General Public License
160aea86a2SCatalin Marinas * along with this program.  If not, see <http://www.gnu.org/licenses/>.
170aea86a2SCatalin Marinas */
180aea86a2SCatalin Marinas#include <linux/linkage.h>
19338d4f49SJames Morse
20338d4f49SJames Morse#include <asm/alternative.h>
210aea86a2SCatalin Marinas#include <asm/assembler.h>
22338d4f49SJames Morse#include <asm/cpufeature.h>
23338d4f49SJames Morse#include <asm/sysreg.h>
240aea86a2SCatalin Marinas
250aea86a2SCatalin Marinas	.text
260aea86a2SCatalin Marinas
270aea86a2SCatalin Marinas/* Prototype: int __clear_user(void *addr, size_t sz)
280aea86a2SCatalin Marinas * Purpose  : clear some user memory
290aea86a2SCatalin Marinas * Params   : addr - user memory address to clear
300aea86a2SCatalin Marinas *          : sz   - number of bytes to clear
310aea86a2SCatalin Marinas * Returns  : number of bytes NOT cleared
320aea86a2SCatalin Marinas *
330aea86a2SCatalin Marinas * Alignment fixed up by hardware.
340aea86a2SCatalin Marinas */
350aea86a2SCatalin MarinasENTRY(__clear_user)
36338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_HAS_PAN, \
37338d4f49SJames Morse	    CONFIG_ARM64_PAN)
380aea86a2SCatalin Marinas	mov	x2, x1			// save the size for fixup return
390aea86a2SCatalin Marinas	subs	x1, x1, #8
400aea86a2SCatalin Marinas	b.mi	2f
410aea86a2SCatalin Marinas1:
420aea86a2SCatalin MarinasUSER(9f, str	xzr, [x0], #8	)
430aea86a2SCatalin Marinas	subs	x1, x1, #8
440aea86a2SCatalin Marinas	b.pl	1b
450aea86a2SCatalin Marinas2:	adds	x1, x1, #4
460aea86a2SCatalin Marinas	b.mi	3f
470aea86a2SCatalin MarinasUSER(9f, str	wzr, [x0], #4	)
480aea86a2SCatalin Marinas	sub	x1, x1, #4
490aea86a2SCatalin Marinas3:	adds	x1, x1, #2
500aea86a2SCatalin Marinas	b.mi	4f
510aea86a2SCatalin MarinasUSER(9f, strh	wzr, [x0], #2	)
520aea86a2SCatalin Marinas	sub	x1, x1, #2
530aea86a2SCatalin Marinas4:	adds	x1, x1, #1
540aea86a2SCatalin Marinas	b.mi	5f
5597fc1543SKyle McMartinUSER(9f, strb	wzr, [x0]	)
560aea86a2SCatalin Marinas5:	mov	x0, #0
57338d4f49SJames MorseALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_HAS_PAN, \
58338d4f49SJames Morse	    CONFIG_ARM64_PAN)
590aea86a2SCatalin Marinas	ret
600aea86a2SCatalin MarinasENDPROC(__clear_user)
610aea86a2SCatalin Marinas
620aea86a2SCatalin Marinas	.section .fixup,"ax"
630aea86a2SCatalin Marinas	.align	2
640aea86a2SCatalin Marinas9:	mov	x0, x2			// return the original size
650aea86a2SCatalin Marinas	ret
660aea86a2SCatalin Marinas	.previous
67