Merge branch 'md-fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md...
[linux-2.6-microblaze.git] / arch / arm64 / lib / kasan_sw_tags.S
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Copyright (C) 2020 Google LLC
4  */
5
6 #include <linux/linkage.h>
7 #include <asm/assembler.h>
8
9 /*
10  * Report a tag mismatch detected by tag-based KASAN.
11  *
12  * A compiler-generated thunk calls this with a non-AAPCS calling
13  * convention. Upon entry to this function, registers are as follows:
14  *
15  * x0:         fault address (see below for restore)
16  * x1:         fault description (see below for restore)
17  * x2 to x15:  callee-saved
18  * x16 to x17: safe to clobber
19  * x18 to x30: callee-saved
20  * sp:         pre-decremented by 256 bytes (see below for restore)
21  *
22  * The caller has decremented the SP by 256 bytes, and created a
23  * structure on the stack as follows:
24  *
25  * sp + 0..15:    x0 and x1 to be restored
26  * sp + 16..231:  free for use
27  * sp + 232..247: x29 and x30 (same as in GPRs)
28  * sp + 248..255: free for use
29  *
30  * Note that this is not a struct pt_regs.
31  *
32  * To call a regular AAPCS function we must save x2 to x15 (which we can
33  * store in the gaps), and create a frame record (for which we can use
34  * x29 and x30 spilled by the caller as those match the GPRs).
35  *
36  * The caller expects x0 and x1 to be restored from the structure, and
37  * for the structure to be removed from the stack (i.e. the SP must be
38  * incremented by 256 prior to return).
39  */
40 SYM_CODE_START(__hwasan_tag_mismatch)
41 #ifdef BTI_C
42         BTI_C
43 #endif
44         add     x29, sp, #232
45         stp     x2, x3, [sp, #8 * 2]
46         stp     x4, x5, [sp, #8 * 4]
47         stp     x6, x7, [sp, #8 * 6]
48         stp     x8, x9, [sp, #8 * 8]
49         stp     x10, x11, [sp, #8 * 10]
50         stp     x12, x13, [sp, #8 * 12]
51         stp     x14, x15, [sp, #8 * 14]
52 #ifndef CONFIG_SHADOW_CALL_STACK
53         str     x18, [sp, #8 * 18]
54 #endif
55
56         mov     x2, x30
57         bl      kasan_tag_mismatch
58
59         ldp     x0, x1, [sp]
60         ldp     x2, x3, [sp, #8 * 2]
61         ldp     x4, x5, [sp, #8 * 4]
62         ldp     x6, x7, [sp, #8 * 6]
63         ldp     x8, x9, [sp, #8 * 8]
64         ldp     x10, x11, [sp, #8 * 10]
65         ldp     x12, x13, [sp, #8 * 12]
66         ldp     x14, x15, [sp, #8 * 14]
67 #ifndef CONFIG_SHADOW_CALL_STACK
68         ldr     x18, [sp, #8 * 18]
69 #endif
70         ldp     x29, x30, [sp, #8 * 29]
71
72         /* remove the structure from the stack */
73         add     sp, sp, #256
74         ret
75 SYM_CODE_END(__hwasan_tag_mismatch)
76 EXPORT_SYMBOL(__hwasan_tag_mismatch)