Fix: Disable IBT around indirect function calls
[lttng-modules.git] / include / wrapper / ibt.h
1 /* SPDX-License-Identifier: (GPL-2.0-only)
2 *
3 * wrapper/ibt.h
4 *
5 * Copyright (C) 2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 */
7
8 #ifndef _LTTNG_WRAPPER_IBT_H
9 #define _LTTNG_WRAPPER_IBT_H
10
11 struct irq_ibt_state {
12 u64 msr;
13 unsigned long flags;
14 };
15
16 /*
17 * Save (disable) and restore interrupts around MSR bit change and indirect
18 * function call to make sure this thread is not migrated to another CPU which
19 * would not have the MSR bit cleared.
20 */
21
22 #ifdef CONFIG_X86_KERNEL_IBT
23 # include <asm/cpufeature.h>
24 # include <asm/msr.h>
25 static inline __attribute__((always_inline))
26 struct irq_ibt_state wrapper_irq_ibt_save(void)
27 {
28 struct irq_ibt_state state = { 0, 0 };
29 u64 msr;
30
31 if (!cpu_feature_enabled(X86_FEATURE_IBT))
32 goto end;
33 local_irq_save(state.flags);
34 rdmsrl(MSR_IA32_S_CET, msr);
35 wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN);
36 state.msr = msr;
37 end:
38 return state;
39 }
40
41 static inline __attribute__((always_inline))
42 void wrapper_irq_ibt_restore(struct irq_ibt_state state)
43 {
44 u64 msr;
45
46 if (!cpu_feature_enabled(X86_FEATURE_IBT))
47 return;
48 rdmsrl(MSR_IA32_S_CET, msr);
49 msr &= ~CET_ENDBR_EN;
50 msr |= (state.msr & CET_ENDBR_EN);
51 wrmsrl(MSR_IA32_S_CET, msr);
52 local_irq_restore(state.flags);
53 }
54 #else
55 static inline struct irq_ibt_state wrapper_irq_ibt_save(void) { struct irq_ibt_state state = { 0, 0 }; return state; }
56 static inline void wrapper_irq_ibt_restore(struct irq_ibt_state state) { }
57 #endif
58
59 #endif /* _LTTNG_WRAPPER_IBT_H */
This page took 0.030098 seconds and 4 git commands to generate.