File: ibt.h

package info (click to toggle)
lttng-modules 2.14.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,808 kB
  • sloc: ansic: 74,851; sh: 548; makefile: 62
file content (59 lines) | stat: -rw-r--r-- 1,458 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/* SPDX-License-Identifier: (GPL-2.0-only)
 *
 * wrapper/ibt.h
 *
 * Copyright (C) 2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
 */

#ifndef _LTTNG_WRAPPER_IBT_H
#define _LTTNG_WRAPPER_IBT_H

struct irq_ibt_state {
	u64 msr;
	unsigned long flags;
};

/*
 * Save (disable) and restore interrupts around MSR bit change and indirect
 * function call to make sure this thread is not migrated to another CPU which
 * would not have the MSR bit cleared.
 */

#ifdef CONFIG_X86_KERNEL_IBT
# include <asm/cpufeature.h>
# include <asm/msr.h>
static inline __attribute__((always_inline))
struct irq_ibt_state wrapper_irq_ibt_save(void)
{
	struct irq_ibt_state state = { 0, 0 };
	u64 msr;

	if (!cpu_feature_enabled(X86_FEATURE_IBT))
		goto end;
	local_irq_save(state.flags);
	rdmsrl(MSR_IA32_S_CET, msr);
	wrmsrl(MSR_IA32_S_CET, msr & ~CET_ENDBR_EN);
	state.msr = msr;
end:
	return state;
}

static inline __attribute__((always_inline))
void wrapper_irq_ibt_restore(struct irq_ibt_state state)
{
	u64 msr;

	if (!cpu_feature_enabled(X86_FEATURE_IBT))
		return;
	rdmsrl(MSR_IA32_S_CET, msr);
	msr &= ~CET_ENDBR_EN;
	msr |= (state.msr & CET_ENDBR_EN);
	wrmsrl(MSR_IA32_S_CET, msr);
	local_irq_restore(state.flags);
}
#else
static inline struct irq_ibt_state wrapper_irq_ibt_save(void) { struct irq_ibt_state state = { 0, 0 }; return state; }
static inline void wrapper_irq_ibt_restore(struct irq_ibt_state state) { }
#endif

#endif /* _LTTNG_WRAPPER_IBT_H */