Merge branch 'address-masking'
[linux-2.6-microblaze.git] / arch / x86 / include / asm / cfi.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_CFI_H
3 #define _ASM_X86_CFI_H
4
5 /*
6  * Clang Control Flow Integrity (CFI) support.
7  *
8  * Copyright (C) 2022 Google LLC
9  */
10 #include <linux/bug.h>
11 #include <asm/ibt.h>
12
13 /*
14  * An overview of the various calling conventions...
15  *
16  * Traditional:
17  *
18  * foo:
19  *   ... code here ...
20  *   ret
21  *
22  * direct caller:
23  *   call foo
24  *
25  * indirect caller:
26  *   lea foo(%rip), %r11
27  *   ...
28  *   call *%r11
29  *
30  *
31  * IBT:
32  *
33  * foo:
34  *   endbr64
35  *   ... code here ...
36  *   ret
37  *
38  * direct caller:
39  *   call foo / call foo+4
40  *
41  * indirect caller:
42  *   lea foo(%rip), %r11
43  *   ...
44  *   call *%r11
45  *
46  *
47  * kCFI:
48  *
49  * __cfi_foo:
50  *   movl $0x12345678, %eax
51  *                              # 11 nops when CONFIG_CALL_PADDING
52  * foo:
53  *   endbr64                    # when IBT
54  *   ... code here ...
55  *   ret
56  *
57  * direct call:
58  *   call foo                   # / call foo+4 when IBT
59  *
60  * indirect call:
61  *   lea foo(%rip), %r11
62  *   ...
63  *   movl $(-0x12345678), %r10d
64  *   addl -4(%r11), %r10d       # -15 when CONFIG_CALL_PADDING
65  *   jz   1f
66  *   ud2
67  * 1:call *%r11
68  *
69  *
70  * FineIBT (builds as kCFI + CALL_PADDING + IBT + RETPOLINE and runtime patches into):
71  *
72  * __cfi_foo:
73  *   endbr64
74  *   subl 0x12345678, %r10d
75  *   jz   foo
76  *   ud2
77  *   nop
78  * foo:
79  *   osp nop3                   # was endbr64
80  *   ... code here ...
81  *   ret
82  *
83  * direct caller:
84  *   call foo / call foo+4
85  *
86  * indirect caller:
87  *   lea foo(%rip), %r11
88  *   ...
89  *   movl $0x12345678, %r10d
90  *   subl $16, %r11
91  *   nop4
92  *   call *%r11
93  *
94  */
95 enum cfi_mode {
96         CFI_DEFAULT,    /* FineIBT if hardware has IBT, otherwise kCFI */
97         CFI_OFF,        /* Taditional / IBT depending on .config */
98         CFI_KCFI,       /* Optionally CALL_PADDING, IBT, RETPOLINE */
99         CFI_FINEIBT,    /* see arch/x86/kernel/alternative.c */
100 };
101
102 extern enum cfi_mode cfi_mode;
103
104 struct pt_regs;
105
106 #ifdef CONFIG_CFI_CLANG
107 enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
108 #define __bpfcall
109 extern u32 cfi_bpf_hash;
110 extern u32 cfi_bpf_subprog_hash;
111
112 static inline int cfi_get_offset(void)
113 {
114         switch (cfi_mode) {
115         case CFI_FINEIBT:
116                 return 16;
117         case CFI_KCFI:
118                 if (IS_ENABLED(CONFIG_CALL_PADDING))
119                         return 16;
120                 return 5;
121         default:
122                 return 0;
123         }
124 }
125 #define cfi_get_offset cfi_get_offset
126
127 extern u32 cfi_get_func_hash(void *func);
128
129 #else
130 static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
131 {
132         return BUG_TRAP_TYPE_NONE;
133 }
134 #define cfi_bpf_hash 0U
135 #define cfi_bpf_subprog_hash 0U
136 static inline u32 cfi_get_func_hash(void *func)
137 {
138         return 0;
139 }
140 #endif /* CONFIG_CFI_CLANG */
141
142 #if HAS_KERNEL_IBT == 1
143 #define CFI_NOSEAL(x)   asm(IBT_NOSEAL(__stringify(x)))
144 #endif
145
146 #endif /* _ASM_X86_CFI_H */