diff options
| -rw-r--r-- | arch/x86/include/asm/trace/exceptions.h | 52 | ||||
| -rw-r--r-- | arch/x86/mm/Makefile | 2 | ||||
| -rw-r--r-- | arch/x86/mm/fault.c | 13 |
3 files changed, 67 insertions, 0 deletions
diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h new file mode 100644 index 000000000000..86540c094ecc --- /dev/null +++ b/arch/x86/include/asm/trace/exceptions.h | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | #undef TRACE_SYSTEM | ||
| 2 | #define TRACE_SYSTEM exceptions | ||
| 3 | |||
| 4 | #if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 5 | #define _TRACE_PAGE_FAULT_H | ||
| 6 | |||
| 7 | #include <linux/tracepoint.h> | ||
| 8 | |||
| 9 | extern void trace_irq_vector_regfunc(void); | ||
| 10 | extern void trace_irq_vector_unregfunc(void); | ||
| 11 | |||
| 12 | DECLARE_EVENT_CLASS(x86_exceptions, | ||
| 13 | |||
| 14 | TP_PROTO(unsigned long address, struct pt_regs *regs, | ||
| 15 | unsigned long error_code), | ||
| 16 | |||
| 17 | TP_ARGS(address, regs, error_code), | ||
| 18 | |||
| 19 | TP_STRUCT__entry( | ||
| 20 | __field( unsigned long, address ) | ||
| 21 | __field( unsigned long, ip ) | ||
| 22 | __field( unsigned long, error_code ) | ||
| 23 | ), | ||
| 24 | |||
| 25 | TP_fast_assign( | ||
| 26 | __entry->address = address; | ||
| 27 | __entry->ip = regs->ip; | ||
| 28 | __entry->error_code = error_code; | ||
| 29 | ), | ||
| 30 | |||
| 31 | TP_printk("address=%pf ip=%pf error_code=0x%lx", | ||
| 32 | (void *)__entry->address, (void *)__entry->ip, | ||
| 33 | __entry->error_code) ); | ||
| 34 | |||
| 35 | #define DEFINE_PAGE_FAULT_EVENT(name) \ | ||
| 36 | DEFINE_EVENT_FN(x86_exceptions, name, \ | ||
| 37 | TP_PROTO(unsigned long address, struct pt_regs *regs, \ | ||
| 38 | unsigned long error_code), \ | ||
| 39 | TP_ARGS(address, regs, error_code), \ | ||
| 40 | trace_irq_vector_regfunc, \ | ||
| 41 | trace_irq_vector_unregfunc); | ||
| 42 | |||
| 43 | DEFINE_PAGE_FAULT_EVENT(user_page_fault); | ||
| 44 | DEFINE_PAGE_FAULT_EVENT(kernel_page_fault); | ||
| 45 | |||
| 46 | #undef TRACE_INCLUDE_PATH | ||
| 47 | #define TRACE_INCLUDE_PATH . | ||
| 48 | #define TRACE_INCLUDE_FILE exceptions | ||
| 49 | #endif /* _TRACE_PAGE_FAULT_H */ | ||
| 50 | |||
| 51 | /* This part must be outside protection */ | ||
| 52 | #include <trace/define_trace.h> | ||
diff --git a/arch/x86/mm/Makefile b/arch/x86/mm/Makefile index 23d8e5fecf76..6a19ad9f370d 100644 --- a/arch/x86/mm/Makefile +++ b/arch/x86/mm/Makefile | |||
| @@ -6,6 +6,8 @@ nostackp := $(call cc-option, -fno-stack-protector) | |||
| 6 | CFLAGS_physaddr.o := $(nostackp) | 6 | CFLAGS_physaddr.o := $(nostackp) |
| 7 | CFLAGS_setup_nx.o := $(nostackp) | 7 | CFLAGS_setup_nx.o := $(nostackp) |
| 8 | 8 | ||
| 9 | CFLAGS_fault.o := -I$(src)/../include/asm/trace | ||
| 10 | |||
| 9 | obj-$(CONFIG_X86_PAT) += pat_rbtree.o | 11 | obj-$(CONFIG_X86_PAT) += pat_rbtree.o |
| 10 | obj-$(CONFIG_SMP) += tlb.o | 12 | obj-$(CONFIG_SMP) += tlb.o |
| 11 | 13 | ||
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index fd3e281fbc70..f2730cbce0b5 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
| @@ -20,6 +20,9 @@ | |||
| 20 | #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ | 20 | #include <asm/kmemcheck.h> /* kmemcheck_*(), ... */ |
| 21 | #include <asm/fixmap.h> /* VSYSCALL_START */ | 21 | #include <asm/fixmap.h> /* VSYSCALL_START */ |
| 22 | 22 | ||
| 23 | #define CREATE_TRACE_POINTS | ||
| 24 | #include <asm/trace/exceptions.h> | ||
| 25 | |||
| 23 | /* | 26 | /* |
| 24 | * Page fault error code bits: | 27 | * Page fault error code bits: |
| 25 | * | 28 | * |
| @@ -1232,12 +1235,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
| 1232 | exception_exit(prev_state); | 1235 | exception_exit(prev_state); |
| 1233 | } | 1236 | } |
| 1234 | 1237 | ||
| 1238 | static void trace_page_fault_entries(struct pt_regs *regs, | ||
| 1239 | unsigned long error_code) | ||
| 1240 | { | ||
| 1241 | if (user_mode(regs)) | ||
| 1242 | trace_user_page_fault(read_cr2(), regs, error_code); | ||
| 1243 | else | ||
| 1244 | trace_kernel_page_fault(read_cr2(), regs, error_code); | ||
| 1245 | } | ||
| 1246 | |||
| 1235 | dotraplinkage void __kprobes | 1247 | dotraplinkage void __kprobes |
| 1236 | trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) | 1248 | trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) |
| 1237 | { | 1249 | { |
| 1238 | enum ctx_state prev_state; | 1250 | enum ctx_state prev_state; |
| 1239 | 1251 | ||
| 1240 | prev_state = exception_enter(); | 1252 | prev_state = exception_enter(); |
| 1253 | trace_page_fault_entries(regs, error_code); | ||
| 1241 | __do_page_fault(regs, error_code); | 1254 | __do_page_fault(regs, error_code); |
| 1242 | exception_exit(prev_state); | 1255 | exception_exit(prev_state); |
| 1243 | } | 1256 | } |
