From: Karim Yaghmour <karim@opersys.com>
To: linux-kernel <linux-kernel@vger.kernel.org>
Cc: LTT-Dev <ltt-dev@shafik.org>
Subject: [PATCH] LTT for 2.5.36 5/9: PowerPC trace support
Date: Thu, 19 Sep 2002 18:34:11 -0400 [thread overview]
Message-ID: <3D8A50E3.434F29FA@opersys.com> (raw)
This patch adds trace support for the PowerPC.
Here are the file modifications:
arch/ppc/config.in | 2 +
arch/ppc/kernel/entry.S | 33 ++++++++++++++++++
arch/ppc/kernel/irq.c | 6 +++
arch/ppc/kernel/misc.S | 4 ++
arch/ppc/kernel/process.c | 15 ++++++++
arch/ppc/kernel/syscalls.c | 4 ++
arch/ppc/kernel/time.c | 6 +++
arch/ppc/kernel/traps.c | 82 +++++++++++++++++++++++++++++++++++++++++++++
arch/ppc/mm/fault.c | 17 ++++++++-
include/asm-ppc/trace.h | 30 ++++++++++++++++
10 files changed, 198 insertions, 1 deletion
diff -urpN linux-2.5.36/arch/ppc/config.in linux-2.5.36-ltt/arch/ppc/config.in
--- linux-2.5.36/arch/ppc/config.in Tue Sep 17 20:58:59 2002
+++ linux-2.5.36-ltt/arch/ppc/config.in Thu Sep 19 16:29:56 2002
@@ -588,6 +588,8 @@ source net/bluetooth/Config.in
source lib/Config.in
+source drivers/trace/Config.in
+
mainmenu_option next_comment
comment 'Kernel hacking'
diff -urpN linux-2.5.36/arch/ppc/kernel/entry.S linux-2.5.36-ltt/arch/ppc/kernel/entry.S
--- linux-2.5.36/arch/ppc/kernel/entry.S Tue Sep 17 20:59:13 2002
+++ linux-2.5.36-ltt/arch/ppc/kernel/entry.S Thu Sep 19 16:29:56 2002
@@ -106,6 +106,32 @@ stack_ovf:
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 @@ syscall_dotrace_cont:
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 -urpN linux-2.5.36/arch/ppc/kernel/irq.c linux-2.5.36-ltt/arch/ppc/kernel/irq.c
--- linux-2.5.36/arch/ppc/kernel/irq.c Tue Sep 17 20:58:49 2002
+++ linux-2.5.36-ltt/arch/ppc/kernel/irq.c Thu Sep 19 16:29:56 2002
@@ -48,6 +48,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>
@@ -426,6 +428,8 @@ void ppc_irq_dispatch_handler(struct pt_
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);
@@ -503,6 +507,8 @@ out:
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 -urpN linux-2.5.36/arch/ppc/kernel/misc.S linux-2.5.36-ltt/arch/ppc/kernel/misc.S
--- linux-2.5.36/arch/ppc/kernel/misc.S Tue Sep 17 20:58:51 2002
+++ linux-2.5.36-ltt/arch/ppc/kernel/misc.S Thu Sep 19 16:29:56 2002
@@ -1016,7 +1016,11 @@ _GLOBAL(cvt_df)
* 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 -urpN linux-2.5.36/arch/ppc/kernel/process.c linux-2.5.36-ltt/arch/ppc/kernel/process.c
--- linux-2.5.36/arch/ppc/kernel/process.c Tue Sep 17 20:58:58 2002
+++ linux-2.5.36-ltt/arch/ppc/kernel/process.c Thu Sep 19 16:29:56 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 @@ void show_regs(struct pt_regs * regs)
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 -urpN linux-2.5.36/arch/ppc/kernel/syscalls.c linux-2.5.36-ltt/arch/ppc/kernel/syscalls.c
--- linux-2.5.36/arch/ppc/kernel/syscalls.c Tue Sep 17 20:59:18 2002
+++ linux-2.5.36-ltt/arch/ppc/kernel/syscalls.c Thu Sep 19 16:29:56 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 @@ sys_ipc (uint call, int first, int secon
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
+
+ TRACE_IPC(TRACE_EV_IPC_CALL, call, first);
ret = -EINVAL;
switch (call) {
diff -urpN linux-2.5.36/arch/ppc/kernel/time.c linux-2.5.36-ltt/arch/ppc/kernel/time.c
--- linux-2.5.36/arch/ppc/kernel/time.c Tue Sep 17 20:58:48 2002
+++ linux-2.5.36-ltt/arch/ppc/kernel/time.c Thu Sep 19 16:29:56 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 @@ void timer_interrupt(struct pt_regs * re
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 @@ void timer_interrupt(struct pt_regs * re
ppc_md.heartbeat();
irq_exit();
+
+ TRACE_TRAP_EXIT();
}
#endif /* CONFIG_PPC_ISERIES */
diff -urpN linux-2.5.36/arch/ppc/kernel/traps.c linux-2.5.36-ltt/arch/ppc/kernel/traps.c
--- linux-2.5.36/arch/ppc/kernel/traps.c Tue Sep 17 20:58:48 2002
+++ linux-2.5.36-ltt/arch/ppc/kernel/traps.c Thu Sep 19 16:29:56 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 @@ _exception(int signr, struct pt_regs *re
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 @@ StackOverflow(struct pt_regs *regs)
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 -urpN linux-2.5.36/arch/ppc/mm/fault.c linux-2.5.36-ltt/arch/ppc/mm/fault.c
--- linux-2.5.36/arch/ppc/mm/fault.c Tue Sep 17 20:58:50 2002
+++ linux-2.5.36-ltt/arch/ppc/mm/fault.c Thu Sep 19 16:29:56 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 @@ void do_page_fault(struct pt_regs *regs,
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 @@ good_area:
_tlbie(address);
pte_unmap(ptep);
up_read(&mm->mmap_sem);
+ TRACE_TRAP_EXIT();
return;
}
if (ptep != NULL)
@@ -210,6 +220,7 @@ good_area:
* -- Cort
*/
pte_misses++;
+ TRACE_TRAP_EXIT();
return;
bad_area:
@@ -223,10 +234,12 @@ bad_area:
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 @@ out_of_memory:
if (user_mode(regs))
do_exit(SIGKILL);
bad_page_fault(regs, address, SIGKILL);
+ TRACE_TRAP_EXIT();
return;
do_sigbus:
@@ -255,6 +269,7 @@ do_sigbus:
force_sig_info (SIGBUS, &info, current);
if (!user_mode(regs))
bad_page_fault(regs, address, SIGBUS);
+ TRACE_TRAP_EXIT();
}
/*
diff -urpN linux-2.5.36/include/asm-ppc/trace.h linux-2.5.36-ltt/include/asm-ppc/trace.h
--- linux-2.5.36/include/asm-ppc/trace.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.36-ltt/include/asm-ppc/trace.h Thu Sep 19 16:29:56 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
reply other threads:[~2002-09-19 22:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3D8A50E3.434F29FA@opersys.com \
--to=karim@opersys.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ltt-dev@shafik.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.