]>
Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
91d1aa43 FW |
2 | #ifndef _LINUX_CONTEXT_TRACKING_H |
3 | #define _LINUX_CONTEXT_TRACKING_H | |
4 | ||
91d1aa43 | 5 | #include <linux/sched.h> |
521921ba | 6 | #include <linux/vtime.h> |
e7358b3b | 7 | #include <linux/context_tracking_state.h> |
d19e789f IM |
8 | #include <linux/instrumentation.h> |
9 | ||
56dd9470 | 10 | #include <asm/ptrace.h> |
95a79fd4 | 11 | |
521921ba | 12 | |
6c1e0256 | 13 | #ifdef CONFIG_CONTEXT_TRACKING |
2e709338 FW |
14 | extern void context_tracking_cpu_set(int cpu); |
15 | ||
d0e536d8 PB |
16 | /* Called with interrupts disabled. */ |
17 | extern void __context_tracking_enter(enum ctx_state state); | |
18 | extern void __context_tracking_exit(enum ctx_state state); | |
19 | ||
3aab4f50 RR |
20 | extern void context_tracking_enter(enum ctx_state state); |
21 | extern void context_tracking_exit(enum ctx_state state); | |
ad65782f FW |
22 | extern void context_tracking_user_enter(void); |
23 | extern void context_tracking_user_exit(void); | |
24 | ||
25 | static inline void user_enter(void) | |
26 | { | |
74c57875 | 27 | if (context_tracking_enabled()) |
f70cd6b0 | 28 | context_tracking_enter(CONTEXT_USER); |
ad65782f FW |
29 | |
30 | } | |
31 | static inline void user_exit(void) | |
32 | { | |
74c57875 | 33 | if (context_tracking_enabled()) |
f70cd6b0 | 34 | context_tracking_exit(CONTEXT_USER); |
ad65782f | 35 | } |
56dd9470 | 36 | |
2e9d1e15 | 37 | /* Called with interrupts disabled. */ |
0372007f | 38 | static __always_inline void user_enter_irqoff(void) |
2e9d1e15 | 39 | { |
74c57875 | 40 | if (context_tracking_enabled()) |
2e9d1e15 PB |
41 | __context_tracking_enter(CONTEXT_USER); |
42 | ||
43 | } | |
0372007f | 44 | static __always_inline void user_exit_irqoff(void) |
2e9d1e15 | 45 | { |
74c57875 | 46 | if (context_tracking_enabled()) |
2e9d1e15 PB |
47 | __context_tracking_exit(CONTEXT_USER); |
48 | } | |
49 | ||
6c1e0256 | 50 | static inline enum ctx_state exception_enter(void) |
56dd9470 | 51 | { |
6c1e0256 FW |
52 | enum ctx_state prev_ctx; |
53 | ||
179a9cf7 FW |
54 | if (IS_ENABLED(CONFIG_HAVE_CONTEXT_TRACKING_OFFSTACK) || |
55 | !context_tracking_enabled()) | |
ad65782f FW |
56 | return 0; |
57 | ||
6c1e0256 | 58 | prev_ctx = this_cpu_read(context_tracking.state); |
3aab4f50 RR |
59 | if (prev_ctx != CONTEXT_KERNEL) |
60 | context_tracking_exit(prev_ctx); | |
6c1e0256 FW |
61 | |
62 | return prev_ctx; | |
56dd9470 FW |
63 | } |
64 | ||
6c1e0256 | 65 | static inline void exception_exit(enum ctx_state prev_ctx) |
56dd9470 | 66 | { |
179a9cf7 FW |
67 | if (!IS_ENABLED(CONFIG_HAVE_CONTEXT_TRACKING_OFFSTACK) && |
68 | context_tracking_enabled()) { | |
3aab4f50 RR |
69 | if (prev_ctx != CONTEXT_KERNEL) |
70 | context_tracking_enter(prev_ctx); | |
ad65782f | 71 | } |
56dd9470 FW |
72 | } |
73 | ||
14296e0c SC |
74 | static __always_inline bool context_tracking_guest_enter(void) |
75 | { | |
76 | if (context_tracking_enabled()) | |
77 | __context_tracking_enter(CONTEXT_GUEST); | |
78 | ||
79 | return context_tracking_enabled_this_cpu(); | |
80 | } | |
81 | ||
82 | static __always_inline void context_tracking_guest_exit(void) | |
83 | { | |
84 | if (context_tracking_enabled()) | |
85 | __context_tracking_exit(CONTEXT_GUEST); | |
86 | } | |
f9281648 AL |
87 | |
88 | /** | |
89 | * ct_state() - return the current context tracking state if known | |
90 | * | |
91 | * Returns the current cpu's context tracking state if context tracking | |
92 | * is enabled. If context tracking is disabled, returns | |
93 | * CONTEXT_DISABLED. This should be used primarily for debugging. | |
94 | */ | |
0372007f | 95 | static __always_inline enum ctx_state ct_state(void) |
f9281648 | 96 | { |
74c57875 | 97 | return context_tracking_enabled() ? |
f9281648 AL |
98 | this_cpu_read(context_tracking.state) : CONTEXT_DISABLED; |
99 | } | |
91d1aa43 FW |
100 | #else |
101 | static inline void user_enter(void) { } | |
102 | static inline void user_exit(void) { } | |
2e9d1e15 PB |
103 | static inline void user_enter_irqoff(void) { } |
104 | static inline void user_exit_irqoff(void) { } | |
2d854e57 FW |
105 | static inline enum ctx_state exception_enter(void) { return 0; } |
106 | static inline void exception_exit(enum ctx_state prev_ctx) { } | |
f9281648 | 107 | static inline enum ctx_state ct_state(void) { return CONTEXT_DISABLED; } |
14296e0c SC |
108 | static inline bool context_tracking_guest_enter(void) { return false; } |
109 | static inline void context_tracking_guest_exit(void) { } | |
110 | ||
2d854e57 | 111 | #endif /* !CONFIG_CONTEXT_TRACKING */ |
521921ba | 112 | |
74c57875 | 113 | #define CT_WARN_ON(cond) WARN_ON(context_tracking_enabled() && (cond)) |
65f382fd FW |
114 | |
115 | #ifdef CONFIG_CONTEXT_TRACKING_FORCE | |
116 | extern void context_tracking_init(void); | |
117 | #else | |
118 | static inline void context_tracking_init(void) { } | |
119 | #endif /* CONFIG_CONTEXT_TRACKING_FORCE */ | |
120 | ||
91d1aa43 | 121 | #endif |