Skip to contentSkip to conversation

LTT for 2.5.36 9/9: ARM trace support

PATCH In review Karim Yaghmour 3 participants 3 messages Sep 19, 2002 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 LTT for 2.5.36 9/9: ARM trace support

This patch adds trace support for the ARM. ARM support was implemented by Frank Rowand. Thanks Frank.

Here are the file modifications:

 arch/arm/config.in             |    2
 arch/arm/kernel/entry-common.S |   18 ++++++++
 arch/arm/kernel/irq.c          |    5 ++
 arch/arm/kernel/process.c      |    5 ++
 arch/arm/kernel/sys_arm.c      |    3 +
 arch/arm/kernel/traps.c        |   85 +++++++++++++++++++++++++++++++++++++++++
 arch/arm/mm/fault-common.c     |   15 +++++--
 include/asm-arm/trace.h        |   15 +++++++
 8 files changed, 145 insertions, 3 deletions 
arch/arm/config.in +2 -0
diff -urpN linux-2.5.36/arch/arm/config.in linux-2.5.36-ltt/arch/arm/config.in
@@ -655,6 +655,8 @@ source drivers/usb/Config.in
 
 source net/bluetooth/Config.in
 
+source drivers/trace/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
arch/arm/kernel/entry-common.S +18 -0
diff -urpN linux-2.5.36/arch/arm/kernel/entry-common.S linux-2.5.36-ltt/arch/arm/kernel/entry-common.S
@@ -35,6 +35,11 @@ ENTRY(__do_softirq)
  * stack.
  */
 ret_fast_syscall:
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+	mov	r7, r0				@ save returned r0
+	bl	SYMBOL_NAME(trace_real_syscall_exit)
+	mov	r0, r7
+#endif
 	disable_irq r1				@ disable interrupts
 	ldr	r1, [tsk, #TI_FLAGS]
 	tst	r1, #_TIF_WORK_MASK
@@ -134,6 +139,16 @@ ENTRY(vector_swi)
 	mcr	p15, 0, ip, c1, c0		@ update control register
 #endif
 	enable_irq ip
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+	/* zzz note that validity of scno is not yet checked.
+	 * zzz The visualizer checks it.
+	 */
+	add	r1, sp, #S_R0			@ pointer to regs
+	mov	r0, scno  		        @ syscall number
+	bl	SYMBOL_NAME(trace_real_syscall_entry)
+	add	r1, sp, #S_R0			@ pointer to regs
+	ldmia	r1, {r0 - r3}			@ have to reload r0 - r3
+#endif
 
 	str	r4, [sp, #-S_OFF]!		@ push fifth arg
 
@@ -174,6 +189,9 @@ __sys_trace:
 
 __sys_trace_return:
 	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+	bl	SYMBOL_NAME(trace_real_syscall_exit)
+#endif
 	mov	r1, sp
 	mov	r0, #1				@ trace exit [IP = 1]
 	bl	syscall_trace
arch/arm/kernel/irq.c +5 -0
diff -urpN linux-2.5.36/arch/arm/kernel/irq.c linux-2.5.36-ltt/arch/arm/kernel/irq.c
@@ -30,6 +30,7 @@
 #include <linux/init.h>
 #include <linux/seq_file.h>
 #include <linux/errno.h>
+#include <linux/trace.h>
 
 #include <asm/irq.h>
 #include <asm/system.h>
@@ -338,6 +339,8 @@ asmlinkage void asm_do_IRQ(int irq, stru
 {
 	struct irqdesc *desc = irq_desc + irq;
 
+	TRACE_IRQ_ENTRY(irq, !(user_mode(regs)));
+
 	/*
 	 * Some hardware gives randomly wrong interrupts.  Rather
 	 * than crashing, do something sensible.
@@ -348,6 +351,8 @@ asmlinkage void asm_do_IRQ(int irq, stru
 	spin_lock(&irq_controller_lock);
 	desc->handle(irq, desc, regs);
 	spin_unlock(&irq_controller_lock);
+
+	TRACE_IRQ_EXIT();
 
 	if (softirq_pending(smp_processor_id()))
 		do_softirq();
arch/arm/kernel/process.c +5 -0
diff -urpN linux-2.5.36/arch/arm/kernel/process.c linux-2.5.36-ltt/arch/arm/kernel/process.c
@@ -24,6 +24,7 @@
 #include <linux/reboot.h>
 #include <linux/interrupt.h>
 #include <linux/init.h>
+#include <linux/trace.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -398,6 +399,10 @@ pid_t kernel_thread(int (*fn)(void *), v
         : "=r" (__ret)
         : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg)
 	: "r0", "r1", "lr");
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+	if (__ret > 0)
+		TRACE_PROCESS(TRACE_EV_PROCESS_KTHREAD, __ret, (int) fn);
+#endif
 	return __ret;
 }
 
arch/arm/kernel/sys_arm.c +3 -0
diff -urpN linux-2.5.36/arch/arm/kernel/sys_arm.c linux-2.5.36-ltt/arch/arm/kernel/sys_arm.c
@@ -24,6 +24,7 @@
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/utsname.h>
+#include <linux/trace.h>
 
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
@@ -166,6 +167,8 @@ asmlinkage int sys_ipc (uint call, int f
 
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
+
+	TRACE_IPC(TRACE_EV_IPC_CALL, call, first);
 
 	switch (call) {
 	case SEMOP:
arch/arm/kernel/traps.c +85 -0

127 lines not on this page · raw message

arch/arm/mm/fault-common.c +12 -3
diff -urpN linux-2.5.36/arch/arm/mm/fault-common.c linux-2.5.36-ltt/arch/arm/mm/fault-common.c
@@ -21,6 +21,7 @@
 #include <linux/interrupt.h>
 #include <linux/proc_fs.h>
 #include <linux/init.h>
+#include <linux/trace.h>
 
 #include <asm/system.h>
 #include <asm/pgtable.h>
@@ -253,6 +254,8 @@ int do_page_fault(unsigned long addr, un
 	if (in_interrupt() || !mm)
 		goto no_context;
 
+	TRACE_TRAP_ENTRY(14, instruction_pointer(regs));
+
 	down_read(&mm->mmap_sem);
 	fault = __do_page_fault(mm, addr, fsr, tsk);
 	up_read(&mm->mmap_sem);
@@ -260,8 +263,10 @@ int do_page_fault(unsigned long addr, un
 	/*
 	 * Handle the "normal" case first
 	 */
-	if (fault > 0)
-		return 0;
+	if (fault > 0) {
+		TRACE_TRAP_EXIT();
+ 		return 0;
+	}
 
 	/*
 	 * We had some memory, but were unable to
@@ -287,6 +292,7 @@ int do_page_fault(unsigned long addr, un
 	} else
 		__do_user_fault(tsk, addr, fsr, fault == -1 ?
 				SEGV_ACCERR : SEGV_MAPERR, regs);
+	TRACE_TRAP_EXIT();
 	return 0;
 
 
@@ -309,11 +315,14 @@ do_sigbus:
 #endif
 
 	/* Kernel mode? Handle exceptions or die */
-	if (user_mode(regs))
+	if (user_mode(regs)) {
+		TRACE_TRAP_EXIT();
 		return 0;
+	}
 
 no_context:
 	__do_kernel_fault(mm, addr, fsr, regs);
+	TRACE_TRAP_EXIT();
 	return 0;
 }
 
include/asm-arm/trace.h +15 -0
diff -urpN linux-2.5.36/include/asm-arm/trace.h linux-2.5.36-ltt/include/asm-arm/trace.h
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-arm/trace.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * ARM definitions for tracing system
+ */
+
+#include <linux/trace.h>
+
+/* Current arch type */
+#define TRACE_ARCH_TYPE TRACE_ARCH_TYPE_ARM
+
+/* Current variant type */
+#define TRACE_ARCH_VARIANT TRACE_ARCH_VARIANT_NONE
#1 lore raw

You should probably explicitly CC the architecture maintainers with these patches. Generally, there is no guarantee that they'll read lkml.

arch/arm/kernel/entry-common.S ENTRY(__do_softirq) · line 42

Quoted 12 lines · Karim Yaghmour

diff -urpN linux-2.5.36/arch/arm/kernel/entry-common.S linux-2.5.36-ltt/arch/arm/kernel/entry-common.S

arch/arm/kernel/entry-common.S +5 -0
@@ -35,6 +35,11 @@ ENTRY(__do_softirq)
  * stack.
  */
 ret_fast_syscall:
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+	mov	r7, r0				@ save returned r0
+	bl	SYMBOL_NAME(trace_real_syscall_exit)
+	mov	r0, r7
+#endif

This misses the slow syscall exit path.

Quoted 22 lines
arch/arm/kernel/entry-common.S +22 -0
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+asmlinkage void trace_real_syscall_entry(int scno,struct pt_regs * regs)
+{
+	int			depth = 0;
+	unsigned long           end_code;
+	unsigned long		*fp;			/* frame pointer */
+	unsigned long		lower_bound;
+	unsigned long		lr;			/* link register */
+	unsigned long		*prev_fp;
+	int			seek_depth;
+	unsigned long           start_code;
+	unsigned long           *start_stack;
+	trace_syscall_entry	trace_syscall_event;
+	unsigned long		upper_bound;
+	int			use_bounds;
+	int			use_depth;
+
+	trace_syscall_event.syscall_id = (uint8_t)scno;
+	trace_syscall_event.address    = instruction_pointer(regs);
+	
+	if (! (user_mode(regs) ))
+		goto trace_syscall_end;

arch/arm/kernel/entry-common.S ENTRY(__do_softirq)

Quoted 10 lines
arch/arm/kernel/entry-common.S +10 -0
+
+	if (trace_get_config(&use_depth,
+			     &use_bounds,
+			     &seek_depth,
+			     (void*)&lower_bound,
+			     (void*)&upper_bound) < 0)
+		goto trace_syscall_end;
+
+	if ((use_depth == 1) || (use_bounds == 1)) {
+		fp          = (unsigned long *)regs->ARM_fp;

You can't rely on FP being set to anything real. Although the "APCS" ABI defines that FP will be either zero or a pointer to a valid frame, this isn't always true; a binary built with -fomit-frame-pointer will use FP for its own purposes. This means that there exists the possibility for a program without any frames on the stack (although we could be many functions deep within the program.)

Do you care about this?

Signature · 2 lines
Russell King ([email protected])                The developer of ARM Linux
             http://www.arm.linux.org.uk/personal/aboutme.html
#2 lore raw
Quoted 6 lines · Russell King

You should probably explicitly CC the architecture maintainers with these patches. Generally, there is no guarantee that they'll read lkml.

On Thu, Sep 19, 2002 at 06:35:06PM -0400, Karim Yaghmour wrote:

Quoted 14 lines

arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002 ENTRY(__do_softirq) · line 42

Quoted 12 lines

diff -urpN linux-2.5.36/arch/arm/kernel/entry-common.S linux-2.5.36-ltt/arch/arm/kernel/entry-common.S

arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002 renamed from arch/arm/kernel/entry-common.S Tue Sep 17 20:58:42 2002 +5 -0
@@ -35,6 +35,11 @@ ENTRY(__do_softirq)
  * stack.
  */
 ret_fast_syscall:
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+     mov     r7, r0                          @ save returned r0
+     bl      SYMBOL_NAME(trace_real_syscall_exit)
+     mov     r0, r7
+#endif

This misses the slow syscall exit path.

Thanks, I'll fix that.

Quoted 41 lines
Quoted 23 lines
arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002 renamed from arch/arm/kernel/entry-common.S Tue Sep 17 20:58:42 2002 +22 -0
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+asmlinkage void trace_real_syscall_entry(int scno,struct pt_regs * regs)
+{
+     int                     depth = 0;
+     unsigned long           end_code;
+     unsigned long           *fp;                    /* frame pointer */
+     unsigned long           lower_bound;
+     unsigned long           lr;                     /* link register */
+     unsigned long           *prev_fp;
+     int                     seek_depth;
+     unsigned long           start_code;
+     unsigned long           *start_stack;
+     trace_syscall_entry     trace_syscall_event;
+     unsigned long           upper_bound;
+     int                     use_bounds;
+     int                     use_depth;
+
+     trace_syscall_event.syscall_id = (uint8_t)scno;
+     trace_syscall_event.address    = instruction_pointer(regs);
+
+     if (! (user_mode(regs) ))
+             goto trace_syscall_end;

arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002 ENTRY(__do_softirq)

Quoted 10 lines
arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002 renamed from arch/arm/kernel/entry-common.S Tue Sep 17 20:58:42 2002 +10 -0
+
+     if (trace_get_config(&use_depth,
+                          &use_bounds,
+                          &seek_depth,
+                          (void*)&lower_bound,
+                          (void*)&upper_bound) < 0)
+             goto trace_syscall_end;
+
+     if ((use_depth == 1) || (use_bounds == 1)) {
+             fp          = (unsigned long *)regs->ARM_fp;

You can't rely on FP being set to anything real. Although the "APCS" ABI defines that FP will be either zero or a pointer to a valid frame, this isn't always true; a binary built with -fomit-frame-pointer will use FP for its own purposes. This means that there exists the possibility for a program without any frames on the stack (although we could be many functions deep within the program.)

Quoted 1 line

Do you care about this?

Yes, but there isn't much we can to about it. If a program doesn't have valid frame pointers then we just won't be able to capture a valid address of where the program made the syscall from. There are plenty of paranoia checks to limit the search through the frames (even with non-existent frame pointers), so this won't be catastrophic.

It looks like I could add one more paranoia check for the initial value of regs->ARM_fp.

Quoted 9 lines

--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html

_______________________________________________
ltt-dev mailing list
[email protected]
http://www.listserv.shafik.org/listserv/listinfo/ltt-dev

Thanks for the comments!

-Frank

Signature · 2 lines
Frank Rowand <[email protected]>
MontaVista Software, Inc