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_key; 27 DECLARE_PER_CPU(struct context_tracking, context_tracking); 28 context_tracking_enabled(void)29static __always_inline bool context_tracking_enabled(void) 30 { 31 return static_branch_unlikely(&context_tracking_key); 32 } 33 context_tracking_enabled_cpu(int cpu)34static __always_inline bool context_tracking_enabled_cpu(int cpu) 35 { 36 return context_tracking_enabled() && per_cpu(context_tracking.active, cpu); 37 } 38 context_tracking_enabled_this_cpu(void)39static inline bool context_tracking_enabled_this_cpu(void) 40 { 41 return context_tracking_enabled() && __this_cpu_read(context_tracking.active); 42 } 43 context_tracking_in_user(void)44static __always_inline bool context_tracking_in_user(void) 45 { 46 return __this_cpu_read(context_tracking.state) == CONTEXT_USER; 47 } 48 #else context_tracking_in_user(void)49static inline bool context_tracking_in_user(void) { return false; } context_tracking_enabled(void)50static inline bool context_tracking_enabled(void) { return false; } context_tracking_enabled_cpu(int cpu)51static inline bool context_tracking_enabled_cpu(int cpu) { return false; } context_tracking_enabled_this_cpu(void)52static inline bool context_tracking_enabled_this_cpu(void) { return false; } 53 #endif /* CONFIG_CONTEXT_TRACKING */ 54 55 #endif 56