lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date:	Tue,  3 May 2011 15:52:10 -0700
From:	Vaibhav Nagarnaik <vnagarnaik@...gle.com>
To:	Steven Rostedt <rostedt@...dmis.org>,
	Thomas Gleixner <tglx@...utronix.de>,
	Ingo Molnar <mingo@...hat.com>
Cc:	Michael Rubin <mrubin@...gle.com>,
	David Sharp <dhsharp@...gle.com>, linux-kernel@...r.kernel.org,
	x86@...nel.org, Jiaying Zhang <jiayingz@...gle.com>,
	Vaibhav Nagarnaik <vnagarnaik@...gle.com>
Subject: [PATCH] trace: Add trap entry/exit tracepoints

From: Jiaying Zhang <jiayingz@...gle.com>

There are many ways that the system can move from user space to kernel
space and back. Of those, syscalls and interrupts are traced in ftrace.
Using traps is another way, but is not traced currently. Page faults,
general protection faults and others provide analysis of how the system
is behaving, who causes it and timing impact on the system performance
and running processes.

The following patch adds the event definition for trap entry/exit and
the instrumentation hooks for x86 platforms. Other platforms should be
able to use these events as well once they add the corresponding
instrumentation.

$ echo 1 > debug/tracing/events/trap/enable
run gdb to genrate some trap events
$ cat debug/tracing/trace
          <...>-13619 [003]   917.726602: trap_entry: number=3
          <...>-13619 [003]   917.726612: trap_exit: number=3
          <...>-13619 [003]   917.747263: trap_entry: number=1
          <...>-13619 [003]   917.747272: trap_exit: number=1
          <...>-13619 [003]   917.747567: trap_entry: number=3
          <...>-13619 [003]   917.747570: trap_exit: number=3
          <...>-13619 [003]   917.748101: trap_entry: number=1
          <...>-13619 [003]   917.748103: trap_exit: number=1

$ echo 1 > tracing_enabled; ~/trap pagefault; echo 0 > tracing_enabled
$ cat trace | grep "trap-" | grep number=14 | head
       trap-12528 [003]  1159.755792: trap_entry: number=14
       trap-12528 [003]  1159.755801: trap_entry: number=14
       trap-12528 [003]  1159.755804: trap_entry: number=14
       trap-12528 [003]  1159.755807: trap_entry: number=14
       trap-12528 [003]  1159.755810: trap_entry: number=14
       trap-12528 [003]  1159.755817: trap_entry: number=14
       trap-12528 [003]  1159.755819: trap_entry: number=14
       trap-12528 [003]  1159.755821: trap_entry: number=14
       trap-12528 [003]  1159.755824: trap_entry: number=14
       trap-12528 [003]  1159.755826: trap_entry: number=14
$ cat trace | grep "trap-" | grep number=7 | head
       trap-12528 [003]  1159.756283: trap_entry: number=7
       trap-12529 [003]  1159.757427: trap_entry: number=7
       trap-12530 [003]  1159.758277: trap_entry: number=7
       trap-12531 [003]  1159.759172: trap_entry: number=7
       trap-12532 [003]  1159.768643: trap_entry: number=7
       trap-12533 [003]  1159.778195: trap_entry: number=7
       trap-15026 [001]  1557.877722: trap_entry: number=7
       trap-15253 [001]  1621.395067: trap_entry: number=7

Signed-off-by: Vaibhav Nagarnaik <vnagarnaik@...gle.com>
---
 arch/x86/kernel/traps.c     |   19 ++++++++++++++++++
 arch/x86/mm/fault.c         |   13 ++++++++++-
 include/trace/events/trap.h |   44 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 2 deletions(-)
 create mode 100644 include/trace/events/trap.h

diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index b3efe9f..fbfd787 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -33,6 +33,9 @@
 #include <linux/io.h>
 #include <trace/events/irq.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/trap.h>
+
 #ifdef CONFIG_EISA
 #include <linux/ioport.h>
 #include <linux/eisa.h>
@@ -123,6 +126,7 @@ do_trap(int trapnr, int signr, char *str, struct pt_regs *regs,
 {
 	struct task_struct *tsk = current;
 
+	trace_trap_entry(trapnr);
 #ifdef CONFIG_X86_32
 	if (regs->flags & X86_VM_MASK) {
 		/*
@@ -169,6 +173,7 @@ trap_signal:
 		force_sig_info(signr, info, tsk);
 	else
 		force_sig(signr, tsk);
+	trace_trap_exit(trapnr);
 	return;
 
 kernel_trap:
@@ -177,6 +182,7 @@ kernel_trap:
 		tsk->thread.trap_no = trapnr;
 		die(str, regs, error_code);
 	}
+	trace_trap_exit(trapnr);
 	return;
 
 #ifdef CONFIG_X86_32
@@ -184,6 +190,7 @@ vm86_trap:
 	if (handle_vm86_trap((struct kernel_vm86_regs *) regs,
 						error_code, trapnr))
 		goto trap_signal;
+	trace_trap_exit(trapnr);
 	return;
 #endif
 }
@@ -288,7 +295,9 @@ do_general_protection(struct pt_regs *regs, long error_code)
 		printk("\n");
 	}
 
+	trace_trap_entry(tsk->thread.trap_no);
 	force_sig(SIGSEGV, tsk);
+	trace_trap_exit(tsk->thread.trap_no);
 	return;
 
 #ifdef CONFIG_X86_32
@@ -575,6 +584,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 							SIGTRAP) == NOTIFY_STOP)
 		return;
 
+	trace_trap_entry(tsk->thread.trap_no);
 	/* It's safe to allow irq's after DR6 has been saved */
 	preempt_conditional_sti(regs);
 
@@ -582,6 +592,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 		handle_vm86_trap((struct kernel_vm86_regs *) regs,
 				error_code, INTR_DEBUG);
 		preempt_conditional_cli(regs);
+		trace_trap_exit(tsk->thread.trap_no);
 		return;
 	}
 
@@ -602,6 +613,7 @@ dotraplinkage void __kprobes do_debug(struct pt_regs *regs, long error_code)
 		send_sigtrap(tsk, regs, error_code, si_code);
 	preempt_conditional_cli(regs);
 
+	trace_trap_exit(tsk->thread.trap_no);
 	return;
 }
 
@@ -691,7 +703,9 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr)
 		 */
 		return;		/* Spurious trap, no error */
 	}
+	trace_trap_entry(task->thread.trap_no);
 	force_sig_info(SIGFPE, &info, task);
+	trace_trap_exit(task->thread.trap_no);
 }
 
 dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code)
@@ -712,11 +726,13 @@ do_simd_coprocessor_error(struct pt_regs *regs, long error_code)
 dotraplinkage void
 do_spurious_interrupt_bug(struct pt_regs *regs, long error_code)
 {
+	trace_trap_entry(INTR_SPURIOUS);
 	conditional_sti(regs);
 #if 0
 	/* No need to warn about this any longer. */
 	printk(KERN_INFO "Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
 #endif
+	trace_trap_exit(INTR_SPURIOUS);
 }
 
 asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
@@ -788,6 +804,7 @@ EXPORT_SYMBOL_GPL(math_state_restore);
 dotraplinkage void __kprobes
 do_device_not_available(struct pt_regs *regs, long error_code)
 {
+	trace_trap_entry(INTR_NO_DEV);
 #ifdef CONFIG_MATH_EMULATION
 	if (read_cr0() & X86_CR0_EM) {
 		struct math_emu_info info = { };
@@ -796,6 +813,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 
 		info.regs = regs;
 		math_emulate(&info);
+		trace_trap_exit(INTR_NO_DEV);
 		return;
 	}
 #endif
@@ -803,6 +821,7 @@ do_device_not_available(struct pt_regs *regs, long error_code)
 #ifdef CONFIG_X86_32
 	conditional_sti(regs);
 #endif
+	trace_trap_exit(INTR_NO_DEV);
 }
 
 #ifdef CONFIG_X86_32
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 20e3f87..507f5af 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -11,6 +11,7 @@
 #include <linux/kprobes.h>		/* __kprobes, ...		*/
 #include <linux/mmiotrace.h>		/* kmmio_handler, ...		*/
 #include <linux/perf_event.h>		/* perf_sw_event		*/
+#include <trace/events/trap.h>		/* trap trace events		*/
 #include <linux/hugetlb.h>		/* hstate_index_to_shift	*/
 
 #include <asm/traps.h>			/* dotraplinkage, ...		*/
@@ -955,8 +956,8 @@ static int fault_in_kernel_space(unsigned long address)
  * and the problem, and then passes it off to one of the appropriate
  * routines.
  */
-dotraplinkage void __kprobes
-do_page_fault(struct pt_regs *regs, unsigned long error_code)
+static __always_inline void
+__do_page_fault(struct pt_regs *regs, unsigned long error_code)
 {
 	struct vm_area_struct *vma;
 	struct task_struct *tsk;
@@ -1164,3 +1165,11 @@ good_area:
 
 	up_read(&mm->mmap_sem);
 }
+
+dotraplinkage void __kprobes
+do_page_fault(struct pt_regs *regs, unsigned long error_code)
+{
+	trace_trap_entry(INTR_PAGE_FAULT);
+	__do_page_fault(regs, error_code);
+	trace_trap_exit(INTR_PAGE_FAULT);
+}
diff --git a/include/trace/events/trap.h b/include/trace/events/trap.h
new file mode 100644
index 0000000..cb38eb6
--- /dev/null
+++ b/include/trace/events/trap.h
@@ -0,0 +1,44 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM trap
+
+#if !defined(_TRACE_TRAP_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_TRAP_H
+
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(trap,
+
+	TP_PROTO(int id),
+
+	TP_ARGS(id),
+
+	TP_STRUCT__entry(
+		__field(	int,	id	)
+	),
+
+	TP_fast_assign(
+		__entry->id = id;
+	),
+
+	TP_printk("number=%d", __entry->id)
+);
+
+DEFINE_EVENT(trap, trap_entry,
+
+	TP_PROTO(int id),
+
+	TP_ARGS(id)
+);
+
+DEFINE_EVENT(trap, trap_exit,
+
+	TP_PROTO(int id),
+
+	TP_ARGS(id)
+);
+
+#endif /* _TRACE_TRAP_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
+
-- 
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ