1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (C) 2021 Arm Ltd.
4 */
5
6#include <linux/linkage.h>
7#include <asm/asm-uaccess.h>
8
9	.text
10
11/* Prototype: int __arch_clear_user(void *addr, size_t sz)
12 * Purpose  : clear some user memory
13 * Params   : addr - user memory address to clear
14 *          : sz   - number of bytes to clear
15 * Returns  : number of bytes NOT cleared
16 *
17 * Alignment fixed up by hardware.
18 */
19
20SYM_FUNC_START(__arch_clear_user)
21	add	x2, x0, x1
22
23#ifdef CONFIG_AS_HAS_MOPS
24	.arch_extension mops
25alternative_if_not ARM64_HAS_MOPS
26	b	.Lno_mops
27alternative_else_nop_endif
28
29USER(9f, setpt	[x0]!, x1!, xzr)
30USER(6f, setmt	[x0]!, x1!, xzr)
31USER(6f, setet	[x0]!, x1!, xzr)
32	mov	x0, #0
33	ret
34.Lno_mops:
35#endif
36
37	subs	x1, x1, #8
38	b.mi	2f
39
401:	.p2align 4
41USER(9f, sttr	xzr, [x0])
42	add	x0, x0, #8
43	subs	x1, x1, #8
44	b.hi	1b
45USER(9f, sttr	xzr, [x2, #-8])
46	mov	x0, #0
47	ret
48
492:	tbz	x1, #2, 3f
50USER(9f, sttr	wzr, [x0])
51USER(8f, sttr	wzr, [x2, #-4])
52	mov	x0, #0
53	ret
54
553:	tbz	x1, #1, 4f
56USER(9f, sttrh	wzr, [x0])
574:	tbz	x1, #0, 5f
58USER(7f, sttrb	wzr, [x2, #-1])
595:	mov	x0, #0
60	ret
61
62	// Exception fixups
636:	b.cs	9f
64	// Registers are in Option A format
65	add	x0, x0, x1
66	b	9f
677:	sub	x0, x2, #5	// Adjust for faulting on the final byte...
688:	add	x0, x0, #4	// ...or the second word of the 4-7 byte case
699:	sub	x0, x2, x0
70	ret
71SYM_FUNC_END(__arch_clear_user)
72EXPORT_SYMBOL(__arch_clear_user)
73