root/include/linux/context_tracking.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. user_enter
  2. user_exit
  3. user_enter_irqoff
  4. user_exit_irqoff
  5. exception_enter
  6. exception_exit
  7. ct_state
  8. user_enter
  9. user_exit
  10. user_enter_irqoff
  11. user_exit_irqoff
  12. exception_enter
  13. exception_exit
  14. ct_state
  15. context_tracking_init
  16. guest_enter_irqoff
  17. guest_exit_irqoff
  18. guest_enter_irqoff
  19. guest_exit_irqoff
  20. guest_enter
  21. guest_exit

   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 <asm/ptrace.h>
   9 
  10 
  11 #ifdef CONFIG_CONTEXT_TRACKING
  12 extern void context_tracking_cpu_set(int cpu);
  13 
  14 /* Called with interrupts disabled.  */
  15 extern void __context_tracking_enter(enum ctx_state state);
  16 extern void __context_tracking_exit(enum ctx_state state);
  17 
  18 extern void context_tracking_enter(enum ctx_state state);
  19 extern void context_tracking_exit(enum ctx_state state);
  20 extern void context_tracking_user_enter(void);
  21 extern void context_tracking_user_exit(void);
  22 
  23 static inline void user_enter(void)
  24 {
  25         if (context_tracking_is_enabled())
  26                 context_tracking_enter(CONTEXT_USER);
  27 
  28 }
  29 static inline void user_exit(void)
  30 {
  31         if (context_tracking_is_enabled())
  32                 context_tracking_exit(CONTEXT_USER);
  33 }
  34 
  35 /* Called with interrupts disabled.  */
  36 static inline void user_enter_irqoff(void)
  37 {
  38         if (context_tracking_is_enabled())
  39                 __context_tracking_enter(CONTEXT_USER);
  40 
  41 }
  42 static inline void user_exit_irqoff(void)
  43 {
  44         if (context_tracking_is_enabled())
  45                 __context_tracking_exit(CONTEXT_USER);
  46 }
  47 
  48 static inline enum ctx_state exception_enter(void)
  49 {
  50         enum ctx_state prev_ctx;
  51 
  52         if (!context_tracking_is_enabled())
  53                 return 0;
  54 
  55         prev_ctx = this_cpu_read(context_tracking.state);
  56         if (prev_ctx != CONTEXT_KERNEL)
  57                 context_tracking_exit(prev_ctx);
  58 
  59         return prev_ctx;
  60 }
  61 
  62 static inline void exception_exit(enum ctx_state prev_ctx)
  63 {
  64         if (context_tracking_is_enabled()) {
  65                 if (prev_ctx != CONTEXT_KERNEL)
  66                         context_tracking_enter(prev_ctx);
  67         }
  68 }
  69 
  70 
  71 /**
  72  * ct_state() - return the current context tracking state if known
  73  *
  74  * Returns the current cpu's context tracking state if context tracking
  75  * is enabled.  If context tracking is disabled, returns
  76  * CONTEXT_DISABLED.  This should be used primarily for debugging.
  77  */
  78 static inline enum ctx_state ct_state(void)
  79 {
  80         return context_tracking_is_enabled() ?
  81                 this_cpu_read(context_tracking.state) : CONTEXT_DISABLED;
  82 }
  83 #else
  84 static inline void user_enter(void) { }
  85 static inline void user_exit(void) { }
  86 static inline void user_enter_irqoff(void) { }
  87 static inline void user_exit_irqoff(void) { }
  88 static inline enum ctx_state exception_enter(void) { return 0; }
  89 static inline void exception_exit(enum ctx_state prev_ctx) { }
  90 static inline enum ctx_state ct_state(void) { return CONTEXT_DISABLED; }
  91 #endif /* !CONFIG_CONTEXT_TRACKING */
  92 
  93 #define CT_WARN_ON(cond) WARN_ON(context_tracking_is_enabled() && (cond))
  94 
  95 #ifdef CONFIG_CONTEXT_TRACKING_FORCE
  96 extern void context_tracking_init(void);
  97 #else
  98 static inline void context_tracking_init(void) { }
  99 #endif /* CONFIG_CONTEXT_TRACKING_FORCE */
 100 
 101 
 102 #ifdef CONFIG_VIRT_CPU_ACCOUNTING_GEN
 103 /* must be called with irqs disabled */
 104 static inline void guest_enter_irqoff(void)
 105 {
 106         if (vtime_accounting_cpu_enabled())
 107                 vtime_guest_enter(current);
 108         else
 109                 current->flags |= PF_VCPU;
 110 
 111         if (context_tracking_is_enabled())
 112                 __context_tracking_enter(CONTEXT_GUEST);
 113 
 114         /* KVM does not hold any references to rcu protected data when it
 115          * switches CPU into a guest mode. In fact switching to a guest mode
 116          * is very similar to exiting to userspace from rcu point of view. In
 117          * addition CPU may stay in a guest mode for quite a long time (up to
 118          * one time slice). Lets treat guest mode as quiescent state, just like
 119          * we do with user-mode execution.
 120          */
 121         if (!context_tracking_cpu_is_enabled())
 122                 rcu_virt_note_context_switch(smp_processor_id());
 123 }
 124 
 125 static inline void guest_exit_irqoff(void)
 126 {
 127         if (context_tracking_is_enabled())
 128                 __context_tracking_exit(CONTEXT_GUEST);
 129 
 130         if (vtime_accounting_cpu_enabled())
 131                 vtime_guest_exit(current);
 132         else
 133                 current->flags &= ~PF_VCPU;
 134 }
 135 
 136 #else
 137 static inline void guest_enter_irqoff(void)
 138 {
 139         /*
 140          * This is running in ioctl context so its safe
 141          * to assume that it's the stime pending cputime
 142          * to flush.
 143          */
 144         vtime_account_system(current);
 145         current->flags |= PF_VCPU;
 146         rcu_virt_note_context_switch(smp_processor_id());
 147 }
 148 
 149 static inline void guest_exit_irqoff(void)
 150 {
 151         /* Flush the guest cputime we spent on the guest */
 152         vtime_account_system(current);
 153         current->flags &= ~PF_VCPU;
 154 }
 155 #endif /* CONFIG_VIRT_CPU_ACCOUNTING_GEN */
 156 
 157 static inline void guest_enter(void)
 158 {
 159         unsigned long flags;
 160 
 161         local_irq_save(flags);
 162         guest_enter_irqoff();
 163         local_irq_restore(flags);
 164 }
 165 
 166 static inline void guest_exit(void)
 167 {
 168         unsigned long flags;
 169 
 170         local_irq_save(flags);
 171         guest_exit_irqoff();
 172         local_irq_restore(flags);
 173 }
 174 
 175 #endif

/* [<][>][^][v][top][bottom][index][help] */