[PATCH] 5/8 LTT for 2.5.34: PowerPC trace support

From: Karim Yaghmour (karim@opersys.com)
Date: Tue Sep 10 2002 - 13:16:52 EST


This patch adds trace support for the PowerPC. Here are the files
modified:
arch/ppc/config.in
arch/ppc/kernel/entry.S
arch/ppc/kernel/irq.c
arch/ppc/kernel/misc.S
arch/ppc/kernel/process.c
arch/ppc/kernel/syscalls.c
arch/ppc/kernel/time.c
arch/ppc/kernel/traps.c
arch/ppc/mm/fault.c
include/asm-ppc/trace.h

diff -urN linux-2.5.34/arch/ppc/config.in linux-2.5.34-ltt/arch/ppc/config.in
--- linux-2.5.34/arch/ppc/config.in Mon Sep 9 13:34:59 2002
+++ linux-2.5.34-ltt/arch/ppc/config.in Mon Sep 9 19:06:34 2002
@@ -588,6 +588,8 @@
 
 source lib/Config.in
 
+source drivers/trace/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
diff -urN linux-2.5.34/arch/ppc/kernel/entry.S linux-2.5.34-ltt/arch/ppc/kernel/entry.S
--- linux-2.5.34/arch/ppc/kernel/entry.S Mon Sep 9 13:35:15 2002
+++ linux-2.5.34-ltt/arch/ppc/kernel/entry.S Mon Sep 9 19:06:34 2002
@@ -106,6 +106,32 @@
         RFI
 #endif /* CONFIG_PPC_ISERIES */
 
+/* LTT stuff */
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+#define TRACE_REAL_ASM_SYSCALL_ENTRY \
+ addi r3,r1,STACK_FRAME_OVERHEAD; /* Put pointer to registers into r3 */ \
+ mflr r29; /* Save LR */ \
+ bl trace_real_syscall_entry; /* Call real trace function */ \
+ mtlr r29; /* Restore LR */ \
+ lwz r0,GPR0(r1); /* Restore original registers */ \
+ lwz r3,GPR3(r1); \
+ lwz r4,GPR4(r1); \
+ lwz r5,GPR5(r1); \
+ lwz r6,GPR6(r1); \
+ lwz r7,GPR7(r1); \
+ lwz r8,GPR8(r1);
+#define TRACE_REAL_ASM_SYSCALL_EXIT \
+ bl trace_real_syscall_exit; /* Call real trace function */ \
+ lwz r0,GPR0(r1); /* Restore original registers */ \
+ lwz r3,RESULT(r1); \
+ lwz r4,GPR4(r1); \
+ lwz r5,GPR5(r1); \
+ lwz r6,GPR6(r1); \
+ lwz r7,GPR7(r1); \
+ lwz r8,GPR8(r1); \
+ addi r9,r1,STACK_FRAME_OVERHEAD;
+#endif
+
 /*
  * Handle a system call.
  */
@@ -136,12 +162,19 @@
         slwi r0,r0,2
         lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
         mtlr r10
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+ TRACE_REAL_ASM_SYSCALL_ENTRY ;
+#endif
         addi r9,r1,STACK_FRAME_OVERHEAD
         blrl /* Call handler */
         .globl ret_from_syscall
 ret_from_syscall:
 #ifdef SHOW_SYSCALLS
         bl do_show_syscall_exit
+#endif
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+ stw r3,RESULT(r1) /* Save result */
+ TRACE_REAL_ASM_SYSCALL_EXIT ;
 #endif
         mr r6,r3
         li r11,-_LAST_ERRNO
diff -urN linux-2.5.34/arch/ppc/kernel/irq.c linux-2.5.34-ltt/arch/ppc/kernel/irq.c
--- linux-2.5.34/arch/ppc/kernel/irq.c Mon Sep 9 13:35:06 2002
+++ linux-2.5.34-ltt/arch/ppc/kernel/irq.c Mon Sep 9 19:06:34 2002
@@ -49,6 +49,8 @@
 #include <linux/random.h>
 #include <linux/seq_file.h>
 
+#include <linux/trace.h>
+
 #include <asm/uaccess.h>
 #include <asm/bitops.h>
 #include <asm/system.h>
@@ -427,6 +429,8 @@
         int cpu = smp_processor_id();
         irq_desc_t *desc = irq_desc + irq;
 
+ TRACE_IRQ_ENTRY(irq, !(user_mode(regs)));
+
         kstat.irqs[cpu][irq]++;
         spin_lock(&desc->lock);
         ack_irq(irq);
@@ -504,6 +508,8 @@
                         irq_desc[irq].handler->enable(irq);
         }
         spin_unlock(&desc->lock);
+
+ TRACE_IRQ_EXIT();
 }
 
 #ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_pic.c */
diff -urN linux-2.5.34/arch/ppc/kernel/misc.S linux-2.5.34-ltt/arch/ppc/kernel/misc.S
--- linux-2.5.34/arch/ppc/kernel/misc.S Mon Sep 9 13:35:08 2002
+++ linux-2.5.34-ltt/arch/ppc/kernel/misc.S Mon Sep 9 19:06:34 2002
@@ -1016,7 +1016,11 @@
  * Create a kernel thread
  * kernel_thread(fn, arg, flags)
  */
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+_GLOBAL(original_kernel_thread)
+#else
 _GLOBAL(kernel_thread)
+#endif /* (CONFIG_TRACE || CONFIG_TRACE_MODULE) */
         stwu r1,-16(r1)
         stw r30,8(r1)
         stw r31,12(r1)
diff -urN linux-2.5.34/arch/ppc/kernel/process.c linux-2.5.34-ltt/arch/ppc/kernel/process.c
--- linux-2.5.34/arch/ppc/kernel/process.c Mon Sep 9 13:35:11 2002
+++ linux-2.5.34-ltt/arch/ppc/kernel/process.c Mon Sep 9 19:06:34 2002
@@ -37,6 +37,8 @@
 #include <linux/prctl.h>
 #include <linux/init_task.h>
 
+#include <linux/trace.h>
+
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -296,6 +298,19 @@
         printk("\n");
         show_stack((unsigned long *)regs->gpr[1]);
 }
+
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+long original_kernel_thread(int (*fn) (void *), void* arg, unsigned long flags);
+long kernel_thread(int (*fn) (void *), void* arg, unsigned long flags)
+{
+ long retval;
+
+ retval = original_kernel_thread(fn, arg, flags);
+ if (retval > 0)
+ TRACE_PROCESS(TRACE_EV_PROCESS_KTHREAD, retval, (int) fn);
+ return retval;
+}
+#endif /* (CONFIG_TRACE || CONFIG_TRACE_MODULE) */
 
 void exit_thread(void)
 {
diff -urN linux-2.5.34/arch/ppc/kernel/syscalls.c linux-2.5.34-ltt/arch/ppc/kernel/syscalls.c
--- linux-2.5.34/arch/ppc/kernel/syscalls.c Mon Sep 9 13:35:19 2002
+++ linux-2.5.34-ltt/arch/ppc/kernel/syscalls.c Mon Sep 9 19:06:34 2002
@@ -39,6 +39,8 @@
 #include <linux/utsname.h>
 #include <linux/file.h>
 
+#include <linux/trace.h>
+
 #include <asm/uaccess.h>
 #include <asm/ipc.h>
 #include <asm/semaphore.h>
@@ -84,6 +86,8 @@
 
         version = call >> 16; /* hack for backward compatibility */
         call &= 0xffff;
+
+ TRACE_IPC(TRACE_EV_IPC_CALL, call, first);
 
         ret = -EINVAL;
         switch (call) {
diff -urN linux-2.5.34/arch/ppc/kernel/time.c linux-2.5.34-ltt/arch/ppc/kernel/time.c
--- linux-2.5.34/arch/ppc/kernel/time.c Mon Sep 9 13:35:05 2002
+++ linux-2.5.34-ltt/arch/ppc/kernel/time.c Mon Sep 9 19:06:34 2002
@@ -60,6 +60,8 @@
 #include <linux/time.h>
 #include <linux/init.h>
 
+#include <linux/trace.h>
+
 #include <asm/segment.h>
 #include <asm/io.h>
 #include <asm/processor.h>
@@ -161,6 +163,8 @@
         if (atomic_read(&ppc_n_lost_interrupts) != 0)
                 do_IRQ(regs);
 
+ TRACE_TRAP_ENTRY(regs->trap, instruction_pointer(regs));
+
         irq_enter();
         
         while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0) {
@@ -215,6 +219,8 @@
                 ppc_md.heartbeat();
 
         irq_exit();
+
+ TRACE_TRAP_EXIT();
 }
 #endif /* CONFIG_PPC_ISERIES */
 
diff -urN linux-2.5.34/arch/ppc/kernel/traps.c linux-2.5.34-ltt/arch/ppc/kernel/traps.c
--- linux-2.5.34/arch/ppc/kernel/traps.c Mon Sep 9 13:35:05 2002
+++ linux-2.5.34-ltt/arch/ppc/kernel/traps.c Mon Sep 9 23:48:31 2002
@@ -33,6 +33,8 @@
 #include <linux/config.h>
 #include <linux/init.h>
 
+#include <linux/trace.h>
+
 #include <asm/pgtable.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -111,7 +113,9 @@
                 debugger(regs);
                 die("Exception in kernel mode", regs, signr);
         }
+ TRACE_TRAP_ENTRY(regs->trap, instruction_pointer(regs));
         force_sig(signr, current);
+ TRACE_TRAP_EXIT();
 }
 
 void
@@ -369,6 +373,84 @@
         show_regs(regs);
         panic("kernel stack overflow");
 }
+
+/* Trace related code */
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+asmlinkage void trace_real_syscall_entry(struct pt_regs *regs)
+{
+ int use_depth;
+ int use_bounds;
+ int depth = 0;
+ int seek_depth;
+ unsigned long lower_bound;
+ unsigned long upper_bound;
+ unsigned long addr;
+ unsigned long *stack;
+ trace_syscall_entry trace_syscall_event;
+
+ /* Set the syscall ID */
+ trace_syscall_event.syscall_id = (uint8_t) regs->gpr[0];
+
+ /* Set the address in any case */
+ trace_syscall_event.address = instruction_pointer(regs);
+
+ /* Are we in the kernel (This is a kernel thread)? */
+ if (!user_mode(regs))
+ /* Don't go digining anywhere */
+ goto trace_syscall_end;
+
+ /* Get the trace configuration */
+ if (trace_get_config(&use_depth,
+ &use_bounds,
+ &seek_depth,
+ (void *) &lower_bound,
+ (void *) &upper_bound) < 0)
+ goto trace_syscall_end;
+
+ /* Do we have to search for an eip address range */
+ if ((use_depth == 1) || (use_bounds == 1)) {
+ /* Start at the top of the stack (bottom address since stacks grow downward) */
+ stack = (unsigned long *) regs->gpr[1];
+
+ /* Skip over first stack frame as the return address isn't valid */
+ if (get_user(addr, stack))
+ goto trace_syscall_end;
+ stack = (unsigned long *) addr;
+
+ /* Keep on going until we reach the end of the process' stack limit (wherever it may be) */
+ while (!get_user(addr, stack + 1)) { /* "stack + 1", since this is where the IP is */
+ /* Does this LOOK LIKE an address in the program */
+ if ((addr > current->mm->start_code)
+ && (addr < current->mm->end_code)) {
+ /* Does this address fit the description */
+ if (((use_depth == 1) && (depth == seek_depth))
+ || ((use_bounds == 1) && (addr > lower_bound) && (addr < upper_bound))) {
+ /* Set the address */
+ trace_syscall_event.address = addr;
+
+ /* We're done */
+ goto trace_syscall_end;
+ } else
+ /* We're one depth more */
+ depth++;
+ }
+ /* Go on to the next address */
+ if (get_user(addr, stack))
+ goto trace_syscall_end;
+ stack = (unsigned long *) addr;
+ }
+ }
+trace_syscall_end:
+ /* Trace the event */
+ 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) */
 
 void nonrecoverable_exception(struct pt_regs *regs)
 {
diff -urN linux-2.5.34/arch/ppc/mm/fault.c linux-2.5.34-ltt/arch/ppc/mm/fault.c
--- linux-2.5.34/arch/ppc/mm/fault.c Mon Sep 9 13:35:06 2002
+++ linux-2.5.34-ltt/arch/ppc/mm/fault.c Mon Sep 9 19:11:51 2002
@@ -31,6 +31,8 @@
 #include <linux/interrupt.h>
 #include <linux/highmem.h>
 
+#include <linux/trace.h>
+
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
@@ -88,22 +90,29 @@
                 is_write = error_code & 0x02000000;
 #endif /* CONFIG_4xx */
 
+ TRACE_TRAP_ENTRY(regs->trap, instruction_pointer(regs));
+
+
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
         if (debugger_fault_handler && TRAP(regs) == 0x300) {
                 debugger_fault_handler(regs);
+ TRACE_TRAP_EXIT();
                 return;
         }
 #if !defined(CONFIG_4xx)
         if (error_code & 0x00400000) {
                 /* DABR match */
- if (debugger_dabr_match(regs))
+ if (debugger_dabr_match(regs)){
+ TRACE_TRAP_EXIT();
                         return;
+ }
         }
 #endif /* !CONFIG_4xx */
 #endif /* CONFIG_XMON || CONFIG_KGDB */
 
         if (in_atomic() || mm == NULL) {
                 bad_page_fault(regs, address, SIGSEGV);
+ TRACE_TRAP_EXIT();
                 return;
         }
         down_read(&mm->mmap_sem);
@@ -168,6 +177,7 @@
                         _tlbie(address);
                         pte_unmap(ptep);
                         up_read(&mm->mmap_sem);
+ TRACE_TRAP_EXIT();
                         return;
                 }
                 if (ptep != NULL)
@@ -210,6 +220,7 @@
          * -- Cort
          */
         pte_misses++;
+ TRACE_TRAP_EXIT();
         return;
 
 bad_area:
@@ -223,10 +234,12 @@
                 info.si_code = code;
                 info.si_addr = (void *) address;
                 force_sig_info(SIGSEGV, &info, current);
+ TRACE_TRAP_EXIT();
                 return;
         }
 
         bad_page_fault(regs, address, SIGSEGV);
+ TRACE_TRAP_EXIT();
         return;
 
 /*
@@ -244,6 +257,7 @@
         if (user_mode(regs))
                 do_exit(SIGKILL);
         bad_page_fault(regs, address, SIGKILL);
+ TRACE_TRAP_EXIT();
         return;
 
 do_sigbus:
@@ -255,6 +269,7 @@
         force_sig_info (SIGBUS, &info, current);
         if (!user_mode(regs))
                 bad_page_fault(regs, address, SIGBUS);
+ TRACE_TRAP_EXIT();
 }
 
 /*
diff -urN linux-2.5.34/include/asm-ppc/trace.h linux-2.5.34-ltt/include/asm-ppc/trace.h
--- linux-2.5.34/include/asm-ppc/trace.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.34-ltt/include/asm-ppc/trace.h Mon Sep 9 19:06:35 2002
@@ -0,0 +1,30 @@
+/*
+ * linux/include/asm-ppc/trace.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * PowerPC definitions for tracing system
+ */
+
+#include <linux/config.h>
+#include <linux/trace.h>
+
+/* Current arch type */
+#define TRACE_ARCH_TYPE TRACE_ARCH_TYPE_PPC
+
+/* PowerPC variants */
+#define TRACE_ARCH_VARIANT_PPC_4xx 1 /* 4xx systems (IBM embedded series) */
+#define TRACE_ARCH_VARIANT_PPC_6xx 2 /* 6xx/7xx/74xx/8260/POWER3 systems (desktop flavor) */
+#define TRACE_ARCH_VARIANT_PPC_8xx 3 /* 8xx system (Motoral embedded series) */
+#define TRACE_ARCH_VARIANT_PPC_ISERIES 4 /* 8xx system (iSeries) */
+
+/* Current variant type */
+#if defined(CONFIG_4xx)
+#define TRACE_ARCH_VARIANT TRACE_ARCH_VARIANT_PPC_4xx
+#elif defined(CONFIG_6xx)
+#define TRACE_ARCH_VARIANT TRACE_ARCH_VARIANT_PPC_6xx
+#elif defined(CONFIG_8xx)
+#define TRACE_ARCH_VARIANT TRACE_ARCH_VARIANT_PPC_8xx
+#elif defined(CONFIG_PPC_ISERIES)
+#define TRACE_ARCH_VARIANT TRACE_ARCH_VARIANT_PPC_ISERIES
+#endif
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Sep 15 2002 - 22:00:22 EST