context_tracking.h (3371B)
1/* SPDX-License-Identifier: GPL-2.0 */ 2#ifndef _LINUX_CONTEXT_TRACKING_H 3#define _LINUX_CONTEXT_TRACKING_H 4 5#include <linux/sched.h> 6#include <linux/vtime.h> 7#include <linux/context_tracking_state.h> 8#include <linux/instrumentation.h> 9 10#include <asm/ptrace.h> 11 12 13#ifdef CONFIG_CONTEXT_TRACKING 14extern void context_tracking_cpu_set(int cpu); 15 16/* Called with interrupts disabled. */ 17extern void __context_tracking_enter(enum ctx_state state); 18extern void __context_tracking_exit(enum ctx_state state); 19 20extern void context_tracking_enter(enum ctx_state state); 21extern void context_tracking_exit(enum ctx_state state); 22extern void context_tracking_user_enter(void); 23extern void context_tracking_user_exit(void); 24 25static inline void user_enter(void) 26{ 27 if (context_tracking_enabled()) 28 context_tracking_enter(CONTEXT_USER); 29 30} 31static inline void user_exit(void) 32{ 33 if (context_tracking_enabled()) 34 context_tracking_exit(CONTEXT_USER); 35} 36 37/* Called with interrupts disabled. */ 38static __always_inline void user_enter_irqoff(void) 39{ 40 if (context_tracking_enabled()) 41 __context_tracking_enter(CONTEXT_USER); 42 43} 44static __always_inline void user_exit_irqoff(void) 45{ 46 if (context_tracking_enabled()) 47 __context_tracking_exit(CONTEXT_USER); 48} 49 50static inline enum ctx_state exception_enter(void) 51{ 52 enum ctx_state prev_ctx; 53 54 if (IS_ENABLED(CONFIG_HAVE_CONTEXT_TRACKING_OFFSTACK) || 55 !context_tracking_enabled()) 56 return 0; 57 58 prev_ctx = this_cpu_read(context_tracking.state); 59 if (prev_ctx != CONTEXT_KERNEL) 60 context_tracking_exit(prev_ctx); 61 62 return prev_ctx; 63} 64 65static inline void exception_exit(enum ctx_state prev_ctx) 66{ 67 if (!IS_ENABLED(CONFIG_HAVE_CONTEXT_TRACKING_OFFSTACK) && 68 context_tracking_enabled()) { 69 if (prev_ctx != CONTEXT_KERNEL) 70 context_tracking_enter(prev_ctx); 71 } 72} 73 74static __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 82static __always_inline void context_tracking_guest_exit(void) 83{ 84 if (context_tracking_enabled()) 85 __context_tracking_exit(CONTEXT_GUEST); 86} 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 */ 95static __always_inline enum ctx_state ct_state(void) 96{ 97 return context_tracking_enabled() ? 98 this_cpu_read(context_tracking.state) : CONTEXT_DISABLED; 99} 100#else 101static inline void user_enter(void) { } 102static inline void user_exit(void) { } 103static inline void user_enter_irqoff(void) { } 104static inline void user_exit_irqoff(void) { } 105static inline enum ctx_state exception_enter(void) { return 0; } 106static inline void exception_exit(enum ctx_state prev_ctx) { } 107static inline enum ctx_state ct_state(void) { return CONTEXT_DISABLED; } 108static __always_inline bool context_tracking_guest_enter(void) { return false; } 109static inline void context_tracking_guest_exit(void) { } 110 111#endif /* !CONFIG_CONTEXT_TRACKING */ 112 113#define CT_WARN_ON(cond) WARN_ON(context_tracking_enabled() && (cond)) 114 115#ifdef CONFIG_CONTEXT_TRACKING_FORCE 116extern void context_tracking_init(void); 117#else 118static inline void context_tracking_init(void) { } 119#endif /* CONFIG_CONTEXT_TRACKING_FORCE */ 120 121#endif