Merge tag 'for-linus-20130509' of git://git.infradead.org/~dwmw2/random-2.6
[platform/adaptation/renesas_rcar/renesas_kernel.git] / include / linux / context_tracking.h
index b28d161..365f4a6 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef _LINUX_CONTEXT_TRACKING_H
 #define _LINUX_CONTEXT_TRACKING_H
 
-#ifdef CONFIG_CONTEXT_TRACKING
 #include <linux/sched.h>
 #include <linux/percpu.h>
+#include <asm/ptrace.h>
 
 struct context_tracking {
        /*
@@ -13,12 +13,13 @@ struct context_tracking {
         * may be further optimized using static keys.
         */
        bool active;
-       enum {
+       enum ctx_state {
                IN_KERNEL = 0,
                IN_USER,
        } state;
 };
 
+#ifdef CONFIG_CONTEXT_TRACKING
 DECLARE_PER_CPU(struct context_tracking, context_tracking);
 
 static inline bool context_tracking_in_user(void)
@@ -33,12 +34,31 @@ static inline bool context_tracking_active(void)
 
 extern void user_enter(void);
 extern void user_exit(void);
+
+static inline enum ctx_state exception_enter(void)
+{
+       enum ctx_state prev_ctx;
+
+       prev_ctx = this_cpu_read(context_tracking.state);
+       user_exit();
+
+       return prev_ctx;
+}
+
+static inline void exception_exit(enum ctx_state prev_ctx)
+{
+       if (prev_ctx == IN_USER)
+               user_enter();
+}
+
 extern void context_tracking_task_switch(struct task_struct *prev,
                                         struct task_struct *next);
 #else
 static inline bool context_tracking_in_user(void) { return false; }
 static inline void user_enter(void) { }
 static inline void user_exit(void) { }
+static inline enum ctx_state exception_enter(void) { return 0; }
+static inline void exception_exit(enum ctx_state prev_ctx) { }
 static inline void context_tracking_task_switch(struct task_struct *prev,
                                                struct task_struct *next) { }
 #endif /* !CONFIG_CONTEXT_TRACKING */