1 #ifndef _LINUX_CONTEXT_TRACKING_H 2 #define _LINUX_CONTEXT_TRACKING_H 3 4 #include <linux/sched.h> 5 #include <linux/vtime.h> 6 #include <linux/context_tracking_state.h> 7 #include <asm/ptrace.h> 8 9 10 #ifdef CONFIG_CONTEXT_TRACKING 11 extern void context_tracking_cpu_set(int cpu); 12 13 extern void context_tracking_enter(enum ctx_state state); 14 extern void context_tracking_exit(enum ctx_state state); 15 extern void context_tracking_user_enter(void); 16 extern void context_tracking_user_exit(void); 17 extern void __context_tracking_task_switch(struct task_struct *prev, 18 struct task_struct *next); 19 user_enter(void)20static inline void user_enter(void) 21 { 22 if (context_tracking_is_enabled()) 23 context_tracking_user_enter(); 24 25 } user_exit(void)26static inline void user_exit(void) 27 { 28 if (context_tracking_is_enabled()) 29 context_tracking_user_exit(); 30 } 31 exception_enter(void)32static inline enum ctx_state exception_enter(void) 33 { 34 enum ctx_state prev_ctx; 35 36 if (!context_tracking_is_enabled()) 37 return 0; 38 39 prev_ctx = this_cpu_read(context_tracking.state); 40 if (prev_ctx != CONTEXT_KERNEL) 41 context_tracking_exit(prev_ctx); 42 43 return prev_ctx; 44 } 45 exception_exit(enum ctx_state prev_ctx)46static inline void exception_exit(enum ctx_state prev_ctx) 47 { 48 if (context_tracking_is_enabled()) { 49 if (prev_ctx != CONTEXT_KERNEL) 50 context_tracking_enter(prev_ctx); 51 } 52 } 53 context_tracking_task_switch(struct task_struct * prev,struct task_struct * next)54static inline void context_tracking_task_switch(struct task_struct *prev, 55 struct task_struct *next) 56 { 57 if (context_tracking_is_enabled()) 58 __context_tracking_task_switch(prev, next); 59 } 60 #else user_enter(void)61static inline void user_enter(void) { } user_exit(void)62static inline void user_exit(void) { } exception_enter(void)63static inline enum ctx_state exception_enter(void) { return 0; } exception_exit(enum ctx_state prev_ctx)64static inline void exception_exit(enum ctx_state prev_ctx) { } context_tracking_task_switch(struct task_struct * prev,struct task_struct * next)65static inline void context_tracking_task_switch(struct task_struct *prev, 66 struct task_struct *next) { } 67 #endif /* !CONFIG_CONTEXT_TRACKING */ 68 69 70 #ifdef CONFIG_CONTEXT_TRACKING_FORCE 71 extern void context_tracking_init(void); 72 #else context_tracking_init(void)73static inline void context_tracking_init(void) { } 74 #endif /* CONFIG_CONTEXT_TRACKING_FORCE */ 75 76 77 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN guest_enter(void)78static inline void guest_enter(void) 79 { 80 if (vtime_accounting_enabled()) 81 vtime_guest_enter(current); 82 else 83 current->flags |= PF_VCPU; 84 85 if (context_tracking_is_enabled()) 86 context_tracking_enter(CONTEXT_GUEST); 87 } 88 guest_exit(void)89static inline void guest_exit(void) 90 { 91 if (context_tracking_is_enabled()) 92 context_tracking_exit(CONTEXT_GUEST); 93 94 if (vtime_accounting_enabled()) 95 vtime_guest_exit(current); 96 else 97 current->flags &= ~PF_VCPU; 98 } 99 100 #else guest_enter(void)101static inline void guest_enter(void) 102 { 103 /* 104 * This is running in ioctl context so its safe 105 * to assume that it's the stime pending cputime 106 * to flush. 107 */ 108 vtime_account_system(current); 109 current->flags |= PF_VCPU; 110 } 111 guest_exit(void)112static inline void guest_exit(void) 113 { 114 /* Flush the guest cputime we spent on the guest */ 115 vtime_account_system(current); 116 current->flags &= ~PF_VCPU; 117 } 118 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */ 119 120 #endif 121