|
| 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) |
0 commit comments