1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Based on arch/arm/lib/clear_user.S
4  *
5  * Copyright (C) 2012 ARM Ltd.
6  */
7 #include <linux/linkage.h>
8 
9 #include <asm/asm-uaccess.h>
10 #include <asm/assembler.h>
11 
12 	.text
13 
14 /* Prototype: int __arch_clear_user(void *addr, size_t sz)
15  * Purpose  : clear some user memory
16  * Params   : addr - user memory address to clear
17  *          : sz   - number of bytes to clear
18  * Returns  : number of bytes NOT cleared
19  *
20  * Alignment fixed up by hardware.
21  */
22 SYM_FUNC_START(__arch_clear_user)
23 	mov	x2, x1			// save the size for fixup return
24 	subs	x1, x1, #8
25 	b.mi	2f
26 1:
27 uao_user_alternative 9f, str, sttr, xzr, x0, 8
28 	subs	x1, x1, #8
29 	b.pl	1b
30 2:	adds	x1, x1, #4
31 	b.mi	3f
32 uao_user_alternative 9f, str, sttr, wzr, x0, 4
33 	sub	x1, x1, #4
34 3:	adds	x1, x1, #2
35 	b.mi	4f
36 uao_user_alternative 9f, strh, sttrh, wzr, x0, 2
37 	sub	x1, x1, #2
38 4:	adds	x1, x1, #1
39 	b.mi	5f
40 uao_user_alternative 9f, strb, sttrb, wzr, x0, 0
41 5:	mov	x0, #0
42 	ret
43 SYM_FUNC_END(__arch_clear_user)
44 EXPORT_SYMBOL(__arch_clear_user)
45 
46 	.section .fixup,"ax"
47 	.align	2
48 9:	mov	x0, x2			// return the original size
49 	ret
50 	.previous
51