Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

context_tracking: Move exception handling to generic code

Exceptions handling on context tracking should share common
treatment: on entry we exit user mode if the exception triggered
in that context. Then on exception exit we return to that previous
context.

Generalize this to avoid duplication across archs.

Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Li Zhong <zhong@linux.vnet.ibm.com>
Cc: Kevin Hilman <khilman@linaro.org>
Cc: Mats Liljegren <mats.liljegren@enea.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Namhyung Kim <namhyung.kim@lge.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

+19 -26
-21
arch/x86/include/asm/context_tracking.h
··· 1 1 #ifndef _ASM_X86_CONTEXT_TRACKING_H 2 2 #define _ASM_X86_CONTEXT_TRACKING_H 3 3 4 - #ifndef __ASSEMBLY__ 5 - #include <linux/context_tracking.h> 6 - #include <asm/ptrace.h> 7 - 8 - static inline void exception_enter(struct pt_regs *regs) 9 - { 10 - user_exit(); 11 - } 12 - 13 - static inline void exception_exit(struct pt_regs *regs) 14 - { 15 - #ifdef CONFIG_CONTEXT_TRACKING 16 - if (user_mode(regs)) 17 - user_enter(); 18 - #endif 19 - } 20 - 21 - #else /* __ASSEMBLY__ */ 22 - 23 4 #ifdef CONFIG_CONTEXT_TRACKING 24 5 # define SCHEDULE_USER call schedule_user 25 6 #else 26 7 # define SCHEDULE_USER call schedule 27 8 #endif 28 - 29 - #endif /* !__ASSEMBLY__ */ 30 9 31 10 #endif
+1 -1
arch/x86/kernel/kvm.c
··· 20 20 * Authors: Anthony Liguori <aliguori@us.ibm.com> 21 21 */ 22 22 23 + #include <linux/context_tracking.h> 23 24 #include <linux/module.h> 24 25 #include <linux/kernel.h> 25 26 #include <linux/kvm_para.h> ··· 44 43 #include <asm/apicdef.h> 45 44 #include <asm/hypervisor.h> 46 45 #include <asm/kvm_guest.h> 47 - #include <asm/context_tracking.h> 48 46 49 47 static int kvmapf = 1; 50 48
+1 -2
arch/x86/kernel/traps.c
··· 12 12 13 13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 14 14 15 + #include <linux/context_tracking.h> 15 16 #include <linux/interrupt.h> 16 17 #include <linux/kallsyms.h> 17 18 #include <linux/spinlock.h> ··· 56 55 #include <asm/i387.h> 57 56 #include <asm/fpu-internal.h> 58 57 #include <asm/mce.h> 59 - #include <asm/context_tracking.h> 60 - 61 58 #include <asm/mach_traps.h> 62 59 63 60 #ifdef CONFIG_X86_64
+1 -1
arch/x86/mm/fault.c
··· 13 13 #include <linux/perf_event.h> /* perf_sw_event */ 14 14 #include <linux/hugetlb.h> /* hstate_index_to_shift */ 15 15 #include <linux/prefetch.h> /* prefetchw */ 16 + #include <linux/context_tracking.h> /* exception_enter(), ... */ 16 17 17 18 #include <asm/traps.h> /* dotraplinkage, ... */ 18 19 #include <asm/pgalloc.h> /* pgd_*(), ... */ 19 20 #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ 20 21 #include <asm/fixmap.h> /* VSYSCALL_START */ 21 - #include <asm/context_tracking.h> /* exception_enter(), ... */ 22 22 23 23 /* 24 24 * Page fault error code bits:
+16 -1
include/linux/context_tracking.h
··· 1 1 #ifndef _LINUX_CONTEXT_TRACKING_H 2 2 #define _LINUX_CONTEXT_TRACKING_H 3 3 4 - #ifdef CONFIG_CONTEXT_TRACKING 5 4 #include <linux/sched.h> 6 5 #include <linux/percpu.h> 6 + #include <asm/ptrace.h> 7 7 8 + #ifdef CONFIG_CONTEXT_TRACKING 8 9 struct context_tracking { 9 10 /* 10 11 * When active is false, probes are unset in order ··· 34 33 35 34 extern void user_enter(void); 36 35 extern void user_exit(void); 36 + 37 + static inline void exception_enter(struct pt_regs *regs) 38 + { 39 + user_exit(); 40 + } 41 + 42 + static inline void exception_exit(struct pt_regs *regs) 43 + { 44 + if (user_mode(regs)) 45 + user_enter(); 46 + } 47 + 37 48 extern void context_tracking_task_switch(struct task_struct *prev, 38 49 struct task_struct *next); 39 50 #else 40 51 static inline bool context_tracking_in_user(void) { return false; } 41 52 static inline void user_enter(void) { } 42 53 static inline void user_exit(void) { } 54 + static inline void exception_enter(struct pt_regs *regs) { } 55 + static inline void exception_exit(struct pt_regs *regs) { } 43 56 static inline void context_tracking_task_switch(struct task_struct *prev, 44 57 struct task_struct *next) { } 45 58 #endif /* !CONFIG_CONTEXT_TRACKING */