* [PATCH] LTT for 2.5.36 9/9: ARM trace support
@ 2002-09-19 22:35 Karim Yaghmour
2002-09-19 23:15 ` Russell King
0 siblings, 1 reply; 3+ messages in thread
From: Karim Yaghmour @ 2002-09-19 22:35 UTC (permalink / raw)
To: linux-kernel; +Cc: LTT-Dev
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
diff -urpN linux-2.5.36/arch/arm/config.in linux-2.5.36-ltt/arch/arm/config.in
--- linux-2.5.36/arch/arm/config.in Tue Sep 17 20:58:48 2002
+++ linux-2.5.36-ltt/arch/arm/config.in Thu Sep 19 16:29:55 2002
@@ -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'
diff -urpN linux-2.5.36/arch/arm/kernel/entry-common.S linux-2.5.36-ltt/arch/arm/kernel/entry-common.S
--- linux-2.5.36/arch/arm/kernel/entry-common.S Tue Sep 17 20:58:42 2002
+++ linux-2.5.36-ltt/arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002
@@ -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
diff -urpN linux-2.5.36/arch/arm/kernel/irq.c linux-2.5.36-ltt/arch/arm/kernel/irq.c
--- linux-2.5.36/arch/arm/kernel/irq.c Tue Sep 17 20:58:40 2002
+++ linux-2.5.36-ltt/arch/arm/kernel/irq.c Thu Sep 19 16:29:55 2002
@@ -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();
diff -urpN linux-2.5.36/arch/arm/kernel/process.c linux-2.5.36-ltt/arch/arm/kernel/process.c
--- linux-2.5.36/arch/arm/kernel/process.c Tue Sep 17 20:59:16 2002
+++ linux-2.5.36-ltt/arch/arm/kernel/process.c Thu Sep 19 16:29:55 2002
@@ -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;
}
diff -urpN linux-2.5.36/arch/arm/kernel/sys_arm.c linux-2.5.36-ltt/arch/arm/kernel/sys_arm.c
--- linux-2.5.36/arch/arm/kernel/sys_arm.c Tue Sep 17 20:58:47 2002
+++ linux-2.5.36-ltt/arch/arm/kernel/sys_arm.c Thu Sep 19 16:29:55 2002
@@ -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:
diff -urpN linux-2.5.36/arch/arm/kernel/traps.c linux-2.5.36-ltt/arch/arm/kernel/traps.c
--- linux-2.5.36/arch/arm/kernel/traps.c Tue Sep 17 20:58:52 2002
+++ linux-2.5.36-ltt/arch/arm/kernel/traps.c Thu Sep 19 16:29:55 2002
@@ -24,6 +24,7 @@
#include <linux/elf.h>
#include <linux/interrupt.h>
#include <linux/init.h>
+#include <linux/trace.h>
#include <asm/atomic.h>
#include <asm/io.h>
@@ -174,6 +175,72 @@ void show_trace_task(struct task_struct
}
}
+#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;
+
+ 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;
+ end_code = current->mm->end_code;
+ start_code = current->mm->start_code;
+ start_stack = (unsigned long *)current->mm->start_stack;
+
+ while (!__get_user(lr, (unsigned long *)(fp - 1))) {
+ if ((lr > start_code) && (lr < end_code)) {
+ if (((use_depth == 1) && (depth >= seek_depth)) ||
+ ((use_bounds == 1) && (lr > lower_bound) && (lr < upper_bound))) {
+ trace_syscall_event.address = lr;
+ goto trace_syscall_end;
+ } else {
+ depth++;
+ }
+ }
+
+ if ((__get_user((unsigned long)prev_fp, (fp - 3))) ||
+ (prev_fp > start_stack) ||
+ (prev_fp <= fp)) {
+ goto trace_syscall_end;
+ }
+ fp = prev_fp;
+ }
+ }
+
+trace_syscall_end:
+ trace_event(TRACE_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+ trace_event(TRACE_EV_SYSCALL_EXIT, NULL);
+}
+#endif /* (CONFIG_TRACE || CONFIG_TRACE_MODULE) */
+
spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
/*
@@ -236,8 +303,12 @@ asmlinkage void do_undefinstr(struct pt_
info.si_code = ILL_ILLOPC;
info.si_addr = pc;
+ TRACE_TRAP_ENTRY(current->thread.trap_no, (uint32_t)pc);
+
force_sig_info(SIGILL, &info, current);
+ TRACE_TRAP_EXIT();
+
die_if_kernel("Oops - undefined instruction", regs, 0);
}
@@ -260,8 +331,12 @@ asmlinkage void do_excpt(unsigned long a
info.si_code = BUS_ADRERR;
info.si_addr = (void *)address;
+ TRACE_TRAP_ENTRY(current->thread.trap_no, instruction_pointer(regs));
+
force_sig_info(SIGBUS, &info, current);
+ TRACE_TRAP_EXIT();
+
die_if_kernel("Oops - address exception", regs, mode);
}
#endif
@@ -441,7 +516,12 @@ asmlinkage int arm_syscall(int no, struc
info.si_addr = (void *)instruction_pointer(regs) -
(thumb_mode(regs) ? 2 : 4);
+ TRACE_TRAP_ENTRY(1, (uint32_t)info.si_addr); /* debug */
+
force_sig_info(SIGILL, &info, current);
+
+ TRACE_TRAP_EXIT();
+
die_if_kernel("Oops", regs, no);
return 0;
}
@@ -475,7 +555,12 @@ baddataabort(int code, unsigned long ins
info.si_code = ILL_ILLOPC;
info.si_addr = (void *)addr;
+ TRACE_TRAP_ENTRY(18, addr); /* machine check */
+
force_sig_info(SIGILL, &info, current);
+
+ TRACE_TRAP_EXIT();
+
die_if_kernel("unknown data abort code", regs, instr);
}
diff -urpN linux-2.5.36/arch/arm/mm/fault-common.c linux-2.5.36-ltt/arch/arm/mm/fault-common.c
--- linux-2.5.36/arch/arm/mm/fault-common.c Tue Sep 17 20:58:43 2002
+++ linux-2.5.36-ltt/arch/arm/mm/fault-common.c Thu Sep 19 16:29:56 2002
@@ -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;
}
diff -urpN linux-2.5.36/include/asm-arm/trace.h linux-2.5.36-ltt/include/asm-arm/trace.h
--- linux-2.5.36/include/asm-arm/trace.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.36-ltt/include/asm-arm/trace.h Thu Sep 19 16:29:56 2002
@@ -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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] LTT for 2.5.36 9/9: ARM trace support
2002-09-19 22:35 [PATCH] LTT for 2.5.36 9/9: ARM trace support Karim Yaghmour
@ 2002-09-19 23:15 ` Russell King
2002-09-19 23:27 ` [ltt-dev] " Frank Rowand
0 siblings, 1 reply; 3+ messages in thread
From: Russell King @ 2002-09-19 23:15 UTC (permalink / raw)
To: Karim Yaghmour; +Cc: linux-kernel, LTT-Dev
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:
> diff -urpN linux-2.5.36/arch/arm/kernel/entry-common.S linux-2.5.36-ltt/arch/arm/kernel/entry-common.S
> --- linux-2.5.36/arch/arm/kernel/entry-common.S Tue Sep 17 20:58:42 2002
> +++ linux-2.5.36-ltt/arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002
> @@ -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.
> +#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;
> +
> + 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?
--
Russell King (rmk@arm.linux.org.uk) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [ltt-dev] Re: [PATCH] LTT for 2.5.36 9/9: ARM trace support
2002-09-19 23:15 ` Russell King
@ 2002-09-19 23:27 ` Frank Rowand
0 siblings, 0 replies; 3+ messages in thread
From: Frank Rowand @ 2002-09-19 23:27 UTC (permalink / raw)
To: Russell King; +Cc: Karim Yaghmour, linux-kernel, LTT-Dev, frowand
Russell King wrote:
>
> 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:
> > diff -urpN linux-2.5.36/arch/arm/kernel/entry-common.S linux-2.5.36-ltt/arch/arm/kernel/entry-common.S
> > --- linux-2.5.36/arch/arm/kernel/entry-common.S Tue Sep 17 20:58:42 2002
> > +++ linux-2.5.36-ltt/arch/arm/kernel/entry-common.S Thu Sep 19 16:29:55 2002
> > @@ -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.
>
> > +#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;
> > +
> > + 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?
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.
>
> --
> Russell King (rmk@arm.linux.org.uk) The developer of ARM Linux
> http://www.arm.linux.org.uk/personal/aboutme.html
>
> _______________________________________________
> ltt-dev mailing list
> ltt-dev@listserv.shafik.org
> http://www.listserv.shafik.org/listserv/listinfo/ltt-dev
Thanks for the comments!
-Frank
--
Frank Rowand <frank_rowand@mvista.com>
MontaVista Software, Inc
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2002-09-19 23:22 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-09-19 22:35 [PATCH] LTT for 2.5.36 9/9: ARM trace support Karim Yaghmour
2002-09-19 23:15 ` Russell King
2002-09-19 23:27 ` [ltt-dev] " Frank Rowand
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).