* [PATCH] 5/8 LTT for 2.5.34: PowerPC trace support
@ 2002-09-10 18:16 Karim Yaghmour
0 siblings, 0 replies; only message in thread
From: Karim Yaghmour @ 2002-09-10 18:16 UTC (permalink / raw)
To: linux-kernel; +Cc: LTT-Dev
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
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-09-10 18:11 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-09-10 18:16 [PATCH] 5/8 LTT for 2.5.34: PowerPC trace support Karim Yaghmour
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.