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 */
40SYM_CODE_START(__hwasan_tag_mismatch)
41	bti	c
42	add	x29, sp, #232
43	stp	x2, x3, [sp, #8 * 2]
44	stp	x4, x5, [sp, #8 * 4]
45	stp	x6, x7, [sp, #8 * 6]
46	stp	x8, x9, [sp, #8 * 8]
47	stp	x10, x11, [sp, #8 * 10]
48	stp	x12, x13, [sp, #8 * 12]
49	stp	x14, x15, [sp, #8 * 14]
50#ifndef CONFIG_SHADOW_CALL_STACK
51	str	x18, [sp, #8 * 18]
52#endif
53
54	mov	x2, x30
55	bl	kasan_tag_mismatch
56
57	ldp	x0, x1, [sp]
58	ldp	x2, x3, [sp, #8 * 2]
59	ldp	x4, x5, [sp, #8 * 4]
60	ldp	x6, x7, [sp, #8 * 6]
61	ldp	x8, x9, [sp, #8 * 8]
62	ldp	x10, x11, [sp, #8 * 10]
63	ldp	x12, x13, [sp, #8 * 12]
64	ldp	x14, x15, [sp, #8 * 14]
65#ifndef CONFIG_SHADOW_CALL_STACK
66	ldr	x18, [sp, #8 * 18]
67#endif
68	ldp	x29, x30, [sp, #8 * 29]
69
70	/* remove the structure from the stack */
71	add	sp, sp, #256
72	ret
73SYM_CODE_END(__hwasan_tag_mismatch)
74EXPORT_SYMBOL(__hwasan_tag_mismatch)
75