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 #include <linux/context_tracking_irq.h> 8 9 struct context_tracking { 10 /* 11 * When active is false, probes are unset in order 12 * to minimize overhead: TIF flags are cleared 13 * and calls to user_enter/exit are ignored. This 14 * may be further optimized using static keys. 15 */ 16 bool active; 17 int recursion; 18 enum ctx_state { 19 CONTEXT_DISABLED = -1, /* returned by ct_state() if unknown */ 20 CONTEXT_KERNEL = 0, 21 CONTEXT_USER, 22 CONTEXT_GUEST, 23 } state; 24 }; 25 26 #ifdef CONFIG_CONTEXT_TRACKING_USER 27 extern struct static_key_false context_tracking_key; 28 DECLARE_PER_CPU(struct context_tracking, context_tracking); 29 30 static __always_inline bool context_tracking_enabled(void) 31 { 32 return static_branch_unlikely(&context_tracking_key); 33 } 34 35 static __always_inline bool context_tracking_enabled_cpu(int cpu) 36 { 37 return context_tracking_enabled() && per_cpu(context_tracking.active, cpu); 38 } 39 40 static inline bool context_tracking_enabled_this_cpu(void) 41 { 42 return context_tracking_enabled() && __this_cpu_read(context_tracking.active); 43 } 44 45 #else 46 static __always_inline bool context_tracking_enabled(void) { return false; } 47 static __always_inline bool context_tracking_enabled_cpu(int cpu) { return false; } 48 static __always_inline bool context_tracking_enabled_this_cpu(void) { return false; } 49 #endif /* CONFIG_CONTEXT_TRACKING_USER */ 50 51 #endif 52