1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_CONTEXT_TRACKING_STATE_H |
3 | #define _LINUX_CONTEXT_TRACKING_STATE_H |
4 | |
5 | #include <linux/percpu.h> |
6 | #include <linux/static_key.h> |
7 | |
8 | struct context_tracking { |
9 | /* |
10 | * When active is false, probes are unset in order |
11 | * to minimize overhead: TIF flags are cleared |
12 | * and calls to user_enter/exit are ignored. This |
13 | * may be further optimized using static keys. |
14 | */ |
15 | bool active; |
16 | int recursion; |
17 | enum ctx_state { |
18 | CONTEXT_DISABLED = -1, /* returned by ct_state() if unknown */ |
19 | CONTEXT_KERNEL = 0, |
20 | CONTEXT_USER, |
21 | CONTEXT_GUEST, |
22 | } state; |
23 | }; |
24 | |
25 | #ifdef CONFIG_CONTEXT_TRACKING |
26 | extern struct static_key_false context_tracking_enabled; |
27 | DECLARE_PER_CPU(struct context_tracking, context_tracking); |
28 | |
29 | static inline bool context_tracking_is_enabled(void) |
30 | { |
31 | return static_branch_unlikely(&context_tracking_enabled); |
32 | } |
33 | |
34 | static inline bool context_tracking_cpu_is_enabled(void) |
35 | { |
36 | return __this_cpu_read(context_tracking.active); |
37 | } |
38 | |
39 | static inline bool context_tracking_in_user(void) |
40 | { |
41 | return __this_cpu_read(context_tracking.state) == CONTEXT_USER; |
42 | } |
43 | #else |
44 | static inline bool context_tracking_in_user(void) { return false; } |
45 | static inline bool context_tracking_active(void) { return false; } |
46 | static inline bool context_tracking_is_enabled(void) { return false; } |
47 | static inline bool context_tracking_cpu_is_enabled(void) { return false; } |
48 | #endif /* CONFIG_CONTEXT_TRACKING */ |
49 | |
50 | #endif |
51 | |