From 25c74b10bacead867478480170083f69cfc0db48 Mon Sep 17 00:00:00 2001 From: Seiji Aguchi Date: Wed, 30 Oct 2013 16:37:00 -0400 Subject: x86, trace: Register exception handler to trace IDT This patch registers exception handlers for tracing to a trace IDT. To implemented it in set_intr_gate(), this patch does followings. - Register the exception handlers to the trace IDT by prepending "trace_" to the handler's names. - Also, newly introduce trace_page_fault() to add tracepoints in a subsequent patch. Signed-off-by: Seiji Aguchi Link: http://lkml.kernel.org/r/52716DEC.5050204@hds.com Signed-off-by: H. Peter Anvin --- arch/x86/mm/fault.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/x86/mm/fault.c') diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 3aaeffcfd67a..fd3e281fbc70 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1231,3 +1231,13 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) __do_page_fault(regs, error_code); exception_exit(prev_state); } + +dotraplinkage void __kprobes +trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) +{ + enum ctx_state prev_state; + + prev_state = exception_enter(); + __do_page_fault(regs, error_code); + exception_exit(prev_state); +} -- cgit v1.2.3 From d34603b07c4255b2b00a546d34f297ccd50ae4c6 Mon Sep 17 00:00:00 2001 From: Seiji Aguchi Date: Wed, 30 Oct 2013 16:39:03 -0400 Subject: x86, trace: Add page fault tracepoints This patch introduces page fault tracepoints to x86 architecture by switching IDT. Two events, for user and kernel spaces, are introduced at the beginning of page fault handler for tracing. - User space event There is a request of page fault event for user space as below. https://lkml.kernel.org/r/1368079520-11015-2-git-send-email-fdeslaur+()+gmail+!+com https://lkml.kernel.org/r/1368079520-11015-1-git-send-email-fdeslaur+()+gmail+!+com - Kernel space event: When we measure an overhead in kernel space for investigating performance issues, we can check if it comes from the page fault events. Signed-off-by: Seiji Aguchi Link: http://lkml.kernel.org/r/52716E67.6090705@hds.com Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/trace/exceptions.h | 52 +++++++++++++++++++++++++++++++++ arch/x86/mm/Makefile | 2 ++ arch/x86/mm/fault.c | 13 +++++++++ 3 files changed, 67 insertions(+) create mode 100644 arch/x86/include/asm/trace/exceptions.h (limited to 'arch/x86/mm/fault.c') 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 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM exceptions + +#if !defined(_TRACE_PAGE_FAULT_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_PAGE_FAULT_H + +#include + +extern void trace_irq_vector_regfunc(void); +extern void trace_irq_vector_unregfunc(void); + +DECLARE_EVENT_CLASS(x86_exceptions, + + TP_PROTO(unsigned long address, struct pt_regs *regs, + unsigned long error_code), + + TP_ARGS(address, regs, error_code), + + TP_STRUCT__entry( + __field( unsigned long, address ) + __field( unsigned long, ip ) + __field( unsigned long, error_code ) + ), + + TP_fast_assign( + __entry->address = address; + __entry->ip = regs->ip; + __entry->error_code = error_code; + ), + + TP_printk("address=%pf ip=%pf error_code=0x%lx", + (void *)__entry->address, (void *)__entry->ip, + __entry->error_code) ); + +#define DEFINE_PAGE_FAULT_EVENT(name) \ +DEFINE_EVENT_FN(x86_exceptions, name, \ + TP_PROTO(unsigned long address, struct pt_regs *regs, \ + unsigned long error_code), \ + TP_ARGS(address, regs, error_code), \ + trace_irq_vector_regfunc, \ + trace_irq_vector_unregfunc); + +DEFINE_PAGE_FAULT_EVENT(user_page_fault); +DEFINE_PAGE_FAULT_EVENT(kernel_page_fault); + +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE exceptions +#endif /* _TRACE_PAGE_FAULT_H */ + +/* This part must be outside protection */ +#include 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) CFLAGS_physaddr.o := $(nostackp) CFLAGS_setup_nx.o := $(nostackp) +CFLAGS_fault.o := -I$(src)/../include/asm/trace + obj-$(CONFIG_X86_PAT) += pat_rbtree.o obj-$(CONFIG_SMP) += tlb.o 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 @@ #include /* kmemcheck_*(), ... */ #include /* VSYSCALL_START */ +#define CREATE_TRACE_POINTS +#include + /* * Page fault error code bits: * @@ -1232,12 +1235,22 @@ do_page_fault(struct pt_regs *regs, unsigned long error_code) exception_exit(prev_state); } +static void trace_page_fault_entries(struct pt_regs *regs, + unsigned long error_code) +{ + if (user_mode(regs)) + trace_user_page_fault(read_cr2(), regs, error_code); + else + trace_kernel_page_fault(read_cr2(), regs, error_code); +} + dotraplinkage void __kprobes trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) { enum ctx_state prev_state; prev_state = exception_enter(); + trace_page_fault_entries(regs, error_code); __do_page_fault(regs, error_code); exception_exit(prev_state); } -- cgit v1.2.3 From a4f61dec55c1bdebb84ba77212ebf98f7247736c Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 11 Nov 2013 08:15:40 -0800 Subject: x86, trace: Change user|kernel_page_fault to page_fault_user|kernel Tracepoints are named hierachially, and it makes more sense to keep a general flow of information level from general to specific from left to right, i.e. x86_exceptions.page_fault_user|kernel rather than x86_exceptions.user|kernel_page_fault Suggested-by: Ingo Molnar Acked-by: Seiji Aguchi Signed-off-by: H. Peter Anvin Link: http://lkml.kernel.org/r/20131111082955.GB12405@gmail.com --- arch/x86/include/asm/trace/exceptions.h | 4 ++-- arch/x86/mm/fault.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/x86/mm/fault.c') diff --git a/arch/x86/include/asm/trace/exceptions.h b/arch/x86/include/asm/trace/exceptions.h index 86540c094ecc..2fbc66c7885b 100644 --- a/arch/x86/include/asm/trace/exceptions.h +++ b/arch/x86/include/asm/trace/exceptions.h @@ -40,8 +40,8 @@ DEFINE_EVENT_FN(x86_exceptions, name, \ trace_irq_vector_regfunc, \ trace_irq_vector_unregfunc); -DEFINE_PAGE_FAULT_EVENT(user_page_fault); -DEFINE_PAGE_FAULT_EVENT(kernel_page_fault); +DEFINE_PAGE_FAULT_EVENT(page_fault_user); +DEFINE_PAGE_FAULT_EVENT(page_fault_kernel); #undef TRACE_INCLUDE_PATH #define TRACE_INCLUDE_PATH . diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index f2730cbce0b5..e532230685d7 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1239,9 +1239,9 @@ static void trace_page_fault_entries(struct pt_regs *regs, unsigned long error_code) { if (user_mode(regs)) - trace_user_page_fault(read_cr2(), regs, error_code); + trace_page_fault_user(read_cr2(), regs, error_code); else - trace_kernel_page_fault(read_cr2(), regs, error_code); + trace_page_fault_kernel(read_cr2(), regs, error_code); } dotraplinkage void __kprobes -- cgit v1.2.3