LTT for 2.5.37 9/9: ARM trace support

LTT for 2.5.37 9/9: ARM trace support

Post by Karim Yaghmou » Mon, 23 Sep 2002 08:30:09



This patch adds ARM trace support. Russell's suggestion has not yet
been incorporated in this version.

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.37/arch/arm/config.in linux-2.5.37-ltt/arch/arm/config.in
--- linux-2.5.37/arch/arm/config.in     Fri Sep 20 11:20:19 2002
+++ linux-2.5.37-ltt/arch/arm/config.in Fri Sep 20 12:43:26 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.37/arch/arm/kernel/entry-common.S linux-2.5.37-ltt/arch/arm/kernel/entry-common.S
--- linux-2.5.37/arch/arm/kernel/entry-common.S Fri Sep 20 11:20:14 2002
+++ linux-2.5.37-ltt/arch/arm/kernel/entry-common.S     Fri Sep 20 12:43:26 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.37/arch/arm/kernel/irq.c linux-2.5.37-ltt/arch/arm/kernel/irq.c
--- linux-2.5.37/arch/arm/kernel/irq.c  Fri Sep 20 11:20:13 2002
+++ linux-2.5.37-ltt/arch/arm/kernel/irq.c      Fri Sep 20 12:43:26 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.37/arch/arm/kernel/process.c linux-2.5.37-ltt/arch/arm/kernel/process.c
--- linux-2.5.37/arch/arm/kernel/process.c      Fri Sep 20 11:20:35 2002
+++ linux-2.5.37-ltt/arch/arm/kernel/process.c  Fri Sep 20 12:43:26 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.37/arch/arm/kernel/sys_arm.c linux-2.5.37-ltt/arch/arm/kernel/sys_arm.c
--- linux-2.5.37/arch/arm/kernel/sys_arm.c      Fri Sep 20 11:20:19 2002
+++ linux-2.5.37-ltt/arch/arm/kernel/sys_arm.c  Fri Sep 20 12:43:26 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.37/arch/arm/kernel/traps.c linux-2.5.37-ltt/arch/arm/kernel/traps.c
--- linux-2.5.37/arch/arm/kernel/traps.c        Fri Sep 20 11:20:24 2002
+++ linux-2.5.37-ltt/arch/arm/kernel/traps.c    Fri Sep 20 12:43:26 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.37/arch/arm/mm/fault-common.c linux-2.5.37-ltt/arch/arm/mm/fault-common.c
--- linux-2.5.37/arch/arm/mm/fault-common.c     Fri Sep 20 11:20:15 2002
+++ linux-2.5.37-ltt/arch/arm/mm/fault-common.c Fri Sep 20 12:43:26 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.37/include/asm-arm/trace.h linux-2.5.37-ltt/include/asm-arm/trace.h
--- linux-2.5.37/include/asm-arm/trace.h        Wed Dec 31 19:00:00 1969
+++ linux-2.5.37-ltt/include/asm-arm/trace.h    Fri Sep 20 12:43:27 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
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/