| From: |
| Karim Yaghmour <karim@opersys.com> |
| To: |
| Andrew Morton <akpm@osdl.org> |
| Subject: |
| [PATCH 4/4] LTT architecture support |
| Date: |
| Tue, 14 Dec 2004 23:05:22 -0500 |
| Cc: |
| linux-kernel <linux-kernel@vger.kernel.org>,
LTT-Dev <ltt-dev@shafik.org> |
| Archive-link: |
| Article,
Thread
|
Support for i386, PPC, ARM, MIPS, S/390, SH
Signed-off-by: Karim Yaghmour <karim@opersys.com>
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/entry-common.S
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/entry-common.S
--- linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/entry-common.S 2004-10-18 17:53:06.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/entry-common.S 2004-12-14 17:58:04.000000000
-0500
@@ -29,6 +29,11 @@
* stack.
*/
ret_fast_syscall:
+#if (CONFIG_LTT)
+ 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
@@ -126,6 +131,16 @@ ENTRY(vector_swi)
mcr p15, 0, ip, c1, c0 @ update control register
#endif
enable_irq ip
+#if (CONFIG_LTT)
+ /* 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
@@ -166,6 +181,9 @@ __sys_trace:
__sys_trace_return:
str r0, [sp, #S_R0 + S_OFF]! @ save returned r0
+#if (CONFIG_LTT)
+ 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.6.10-rc3-bk8-relayfs/arch/arm/kernel/irq.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/irq.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/irq.c 2004-12-14 17:43:55.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/irq.c 2004-12-14 17:58:04.000000000
-0500
@@ -31,6 +31,7 @@
#include <linux/seq_file.h>
#include <linux/errno.h>
#include <linux/list.h>
+#include <linux/ltt-events.h>
#include <linux/kallsyms.h>
#include <asm/irq.h>
@@ -486,6 +487,8 @@ asmlinkage void asm_do_IRQ(unsigned int
{
struct irqdesc *desc = irq_desc + irq;
+ ltt_ev_irq_entry(irq, !(user_mode(regs)));
+
/*
* Some hardware gives randomly wrong interrupts. Rather
* than crashing, do something sensible.
@@ -505,6 +508,8 @@ asmlinkage void asm_do_IRQ(unsigned int
spin_unlock(&irq_controller_lock);
irq_exit();
+
+ ltt_ev_irq_exit();
}
void __set_irq_handler(unsigned int irq, irq_handler_t handle, int
is_chained)
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/process.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/process.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/process.c 2004-12-14 17:43:55.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/process.c 2004-12-14 17:58:04.000000000
-0500
@@ -26,6 +26,7 @@
#include <linux/interrupt.h>
#include <linux/kallsyms.h>
#include <linux/init.h>
+#include <linux/ltt-events.h>
#include <asm/system.h>
#include <asm/io.h>
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/sys_arm.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/sys_arm.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/sys_arm.c 2004-10-18 17:53:43.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/sys_arm.c 2004-12-14 17:58:04.000000000
-0500
@@ -26,6 +26,7 @@
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ltt-events.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -169,6 +170,8 @@ asmlinkage int sys_ipc(uint call, int fi
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
+ ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
switch (call) {
case SEMOP:
return sys_semop(first, (struct sembuf __user *)ptr, second);
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/traps.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/traps.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/arm/kernel/traps.c 2004-10-18 17:53:51.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/arm/kernel/traps.c 2004-12-14 17:58:04.000000000
-0500
@@ -20,6 +20,7 @@
#include <linux/ptrace.h>
#include <linux/kallsyms.h>
#include <linux/init.h>
+#include <linux/ltt-events.h>
#include <asm/atomic.h>
#include <asm/cacheflush.h>
@@ -200,6 +201,72 @@ void show_stack(struct task_struct *tsk,
barrier();
}
+#if (CONFIG_LTT)
+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;
+ ltt_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 (ltt_get_trace_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:
+ ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+ ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+#endif /* (CONFIG_LTT) */
+
spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
/*
@@ -307,8 +374,12 @@ asmlinkage void do_undefinstr(struct pt_
info.si_code = ILL_ILLOPC;
info.si_addr = pc;
+ ltt_ev_trap_entry(current->thread.trap_no, (uint32_t)pc);
+
force_sig_info(SIGILL, &info, current);
+ ltt_ev_trap_exit();
+
die_if_kernel("Oops - undefined instruction", regs, 0);
}
@@ -521,7 +592,12 @@ baddataabort(int code, unsigned long ins
info.si_code = ILL_ILLOPC;
info.si_addr = (void __user *)addr;
+ ltt_ev_trap_entry(18, addr); /* machine check */
+
force_sig_info(SIGILL, &info, current);
+
+ ltt_ev_trap_exit();
+
die_if_kernel("unknown data abort code", regs, instr);
}
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/entry.S
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/entry.S
--- linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/entry.S 2004-12-14 17:45:05.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/entry.S 2004-12-14 17:58:04.000000000
-0500
@@ -251,9 +251,27 @@ ENTRY(system_call)
cmpl $(nr_syscalls), %eax
jae syscall_badsys
syscall_call:
+#if (CONFIG_LTT)
+ movl syscall_entry_trace_active, %eax
+ cmpl $1, %eax # are we tracing system call entries
+ jne no_syscall_entry_trace
+ movl %esp, %eax # copy the stack pointer
+ pushl %eax # pass the stack pointer copy
+ call trace_real_syscall_entry
+ addl $4,%esp # return stack to state before pass
+no_syscall_entry_trace:
+ movl ORIG_EAX(%esp),%eax # restore eax to it's original content
+#endif
call *sys_call_table(,%eax,4)
movl %eax,EAX(%esp) # store the return value
syscall_exit:
+#if (CONFIG_LTT)
+ movl syscall_exit_trace_active, %eax
+ cmpl $1, %eax # are we tracing system call exits
+ jne no_syscall_exit_trace
+ call trace_real_syscall_exit
+no_syscall_exit_trace:
+#endif
cli # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/handler
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/handler
--- linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/handler 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/handler 2004-12-14 21:49:22.000000000
-0500
@@ -0,0 +1,8 @@
+irq.c: seq_printf(p, " %s", action->name);
+irq.c: for (action=action->next; action; action = action->next)
+irq.c: seq_printf(p, ", %s", action->name);
+irq.c.orig: seq_printf(p, " %s", action->name);
+irq.c.orig: for (action=action->next; action; action = action->next)
+irq.c.orig: seq_printf(p, ", %s", action->name);
+irq.c.rej: if (!(action->flags & SA_INTERRUPT))
+irq.c.rej: if (!(action->flags & SA_INTERRUPT))
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/process.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/process.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/process.c 2004-12-14 17:45:05.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/process.c 2004-12-14 17:58:04.000000000
-0500
@@ -36,6 +36,7 @@
#include <linux/module.h>
#include <linux/kallsyms.h>
#include <linux/ptrace.h>
+#include <linux/ltt-events.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -281,6 +282,7 @@ __asm__(".section .text\n"
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
struct pt_regs regs;
+ long pid;
memset(®s, 0, sizeof(regs));
@@ -295,7 +297,12 @@ int kernel_thread(int (*fn)(void *), voi
regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
/* Ok, create the new process.. */
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
+ pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
+#if (CONFIG_LTT)
+ if(pid >= 0)
+ ltt_ev_process(LTT_EV_PROCESS_KTHREAD, pid, (int) fn);
+#endif
+ return pid;
}
/*
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/sys_i386.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/sys_i386.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/sys_i386.c 2004-10-18 17:55:28.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/sys_i386.c 2004-12-14 17:58:04.000000000
-0500
@@ -19,6 +19,7 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ltt-events.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -136,6 +137,8 @@ asmlinkage int sys_ipc (uint call, int f
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
+ ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
switch (call) {
case SEMOP:
return sys_semtimedop (first, (struct sembuf __user *)ptr, second, NULL);
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/traps.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/traps.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/i386/kernel/traps.c 2004-12-14 17:43:55.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/kernel/traps.c 2004-12-14 21:53:54.000000000
-0500
@@ -27,6 +27,7 @@
#include <linux/ptrace.h>
#include <linux/utsname.h>
#include <linux/kprobes.h>
+#include <linux/ltt-events.h>
#ifdef CONFIG_EISA
#include <linux/ioport.h>
@@ -293,6 +294,76 @@ bug:
printk("Kernel BUG\n");
}
+/* Trace related code */
+#if (CONFIG_LTT)
+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;
+ ltt_syscall_entry trace_syscall_event;
+
+ /* Set the syscall ID */
+ trace_syscall_event.syscall_id = (uint8_t) regs->orig_eax;
+
+ /* Set the address in any case */
+ trace_syscall_event.address = regs->eip;
+
+ /* Are we in the kernel (This is a kernel thread)? */
+ if (!(regs->xcs & 3))
+ /* Don't go digining anywhere */
+ goto trace_syscall_end;
+
+ /* Get the trace configuration */
+ if (ltt_get_trace_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->esp;
+
+ /* Keep on going until we reach the end of the process' stack limit (wherever it may be)
*/
+ while (!get_user(addr, stack)) {
+ /* 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 */
+ stack++;
+ }
+ }
+trace_syscall_end:
+ /* Trace the event */
+ ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+ ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+#endif /* (CONFIG_LTT) */
+
void die(const char * str, struct pt_regs * regs, long err)
{
static struct {
@@ -361,6 +432,8 @@ static inline void die_if_kernel(const c
static void do_trap(int trapnr, int signr, char *str, int vm86,
struct pt_regs * regs, long error_code, siginfo_t *info)
{
+ ltt_ev_trap_entry(trapnr, regs->eip);
+
if (regs->eflags & VM_MASK) {
if (vm86)
goto vm86_trap;
@@ -378,20 +451,24 @@ static void do_trap(int trapnr, int sign
force_sig_info(signr, info, tsk);
else
force_sig(signr, tsk);
+ ltt_ev_trap_exit();
return;
}
kernel_trap: {
if (!fixup_exception(regs))
die(str, regs, error_code);
+ ltt_ev_trap_exit();
return;
}
vm86_trap: {
int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code,
trapnr);
if (ret) goto trap_signal;
+ ltt_ev_trap_exit();
return;
}
+ ltt_ev_trap_exit();
}
#define DO_ERROR(trapnr, signr, str, name) \
@@ -493,12 +570,16 @@ fastcall void do_general_protection(stru
current->thread.error_code = error_code;
current->thread.trap_no = 13;
+ ltt_ev_trap_entry(13, regs->eip);
force_sig(SIGSEGV, current);
+ ltt_ev_trap_exit();
return;
gp_in_vm86:
local_irq_enable();
+ ltt_ev_trap_entry(13, regs->eip);
handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
+ ltt_ev_trap_exit();
return;
gp_in_kernel:
@@ -580,6 +661,12 @@ static void default_do_nmi(struct pt_reg
if (!smp_processor_id())
reason = get_nmi_reason();
+#ifndef CONFIG_X86_LOCAL_APIC
+/* On an machines with APIC enabled, NMIs are used to implement a watchdog
+and will hang the machine if traced. */
+ ltt_ev_trap_entry(2, regs->eip);
+#endif
+
if (!(reason & 0xc0)) {
if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT)
== NOTIFY_STOP)
@@ -595,6 +682,9 @@ static void default_do_nmi(struct pt_reg
}
#endif
unknown_nmi_error(reason, regs);
+#ifndef CONFIG_X86_LOCAL_APIC
+ ltt_ev_trap_exit();
+#endif
return;
}
if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP)
@@ -608,6 +698,10 @@ static void default_do_nmi(struct pt_reg
* as it's edge-triggered.
*/
reassert_nmi();
+
+#ifndef CONFIG_X86_LOCAL_APIC
+ ltt_ev_trap_exit();
+#endif
}
static int dummy_nmi_callback(struct pt_regs * regs, int cpu)
@@ -734,7 +828,9 @@ fastcall void do_debug(struct pt_regs *
*/
info.si_addr = ((regs->xcs & 3) == 0) ? (void __user *)tsk->thread.eip
: (void __user *)regs->eip;
+ ltt_ev_trap_entry(1, regs->eip);
force_sig_info(SIGTRAP, &info, tsk);
+ ltt_ev_trap_exit();
/* Disable additional traps. They'll be re-enabled when
* the signal is delivered.
@@ -746,7 +842,9 @@ clear_dr7:
return;
debug_vm86:
+ ltt_ev_trap_entry(1, regs->eip);
handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
+ ltt_ev_trap_exit();
return;
clear_TF_reenable:
@@ -898,10 +996,12 @@ fastcall void do_simd_coprocessor_error(
fastcall void do_spurious_interrupt_bug(struct pt_regs * regs,
long error_code)
{
+ ltt_ev_trap_entry(16, regs->eip);
#if 0
/* No need to warn about this any longer. */
printk("Ignoring P6 Local APIC Spurious Interrupt Bug...\n");
#endif
+ ltt_ev_trap_exit();
}
/*
@@ -932,8 +1032,10 @@ asmlinkage void math_emulate(long arg)
{
printk("math-emulation not enabled and no coprocessor found.\n");
printk("killing %s.\n",current->comm);
+ ltt_ev_trap_entry(7, 0);
force_sig(SIGFPE,current);
schedule();
+ ltt_ev_trap_exit();
}
#endif /* CONFIG_MATH_EMULATION */
@@ -965,7 +1067,6 @@ do { \
"3" ((char *) (addr)),"2" ((seg) << 16)); \
} while (0)
-
/*
* This needs to use 'idt_table' rather than 'idt', and
* thus use the _nonmapped_ version of the IDT, as the
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/i386/mm/fault.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/mm/fault.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/i386/mm/fault.c 2004-12-14 17:43:55.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/i386/mm/fault.c 2004-12-14 17:58:04.000000000
-0500
@@ -21,6 +21,7 @@
#include <linux/vt_kern.h> /* For unblank_screen() */
#include <linux/highmem.h>
#include <linux/module.h>
+#include <linux/ltt-events.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -269,6 +270,8 @@ fastcall void do_page_fault(struct pt_re
if (in_atomic() || !mm)
goto bad_area_nosemaphore;
+ ltt_ev_trap_entry(14, regs->eip);
+
/* When running in the kernel we expect faults to occur only to
* addresses in user space. All other faults represent errors in the
* kernel and should generate an OOPS. Unfortunatly, in the case of an
@@ -366,6 +369,7 @@ good_area:
tsk->thread.screen_bitmap |= 1 << bit;
}
up_read(&mm->mmap_sem);
+ ltt_ev_trap_exit();
return;
/*
@@ -408,6 +412,7 @@ bad_area_nosemaphore:
if (nr == 6) {
do_invalid_op(regs, 0);
+ ltt_ev_trap_exit();
return;
}
}
@@ -415,16 +420,20 @@ bad_area_nosemaphore:
no_context:
/* Are we prepared to handle this kernel fault? */
- if (fixup_exception(regs))
+ if (fixup_exception(regs)) {
+ ltt_ev_trap_exit();
return;
+ }
/*
* Valid to do another page fault here, because if this fault
* had been triggered by is_prefetch fixup_exception would have
* handled it.
*/
- if (is_prefetch(regs, address, error_code))
+ if (is_prefetch(regs, address, error_code)) {
+ ltt_ev_trap_exit();
return;
+ }
/*
* Oops. The kernel tried to access some bad page. We'll have to
@@ -493,8 +502,10 @@ do_sigbus:
goto no_context;
/* User space => ok to do another page fault */
- if (is_prefetch(regs, address, error_code))
+ if (is_prefetch(regs, address, error_code)) {
+ ltt_ev_trap_exit();
return;
+ }
tsk->thread.cr2 = address;
tsk->thread.error_code = error_code;
@@ -504,6 +515,7 @@ do_sigbus:
info.si_code = BUS_ADRERR;
info.si_addr = (void __user *)address;
force_sig_info(SIGBUS, &info, tsk);
+ ltt_ev_trap_exit();
return;
vmalloc_fault:
@@ -542,6 +554,9 @@ vmalloc_fault:
pte_k = pte_offset_kernel(pmd_k, address);
if (!pte_present(*pte_k))
goto no_context;
+ ltt_ev_trap_entry(14, regs->eip);
+ ltt_ev_trap_exit();
return;
}
+ ltt_ev_trap_exit();
}
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/mips/kernel/irq.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/kernel/irq.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/mips/kernel/irq.c 2004-12-14 17:43:55.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/kernel/irq.c 2004-12-14 17:58:04.000000000
-0500
@@ -51,6 +51,8 @@ asmlinkage unsigned int do_IRQ(unsigned
__do_IRQ(irq, regs);
+ ltt_ev_irq_exit();
+
irq_exit();
return 1;
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/mips/kernel/traps.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/kernel/traps.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/mips/kernel/traps.c 2004-12-14 17:43:55.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/kernel/traps.c 2004-12-14 17:58:04.000000000
-0500
@@ -501,6 +501,7 @@ asmlinkage void do_ov(struct pt_regs *re
*/
asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
{
+ ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs));
if (fcr31 & FPU_CSR_UNI_X) {
int sig;
@@ -640,6 +641,8 @@ asmlinkage void do_cpu(struct pt_regs *r
die_if_kernel("do_cpu invoked from kernel context!", regs);
+ ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs));
+
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
switch (cpid) {
@@ -1060,3 +1063,75 @@ void __init trap_init(void)
flush_icache_range(CAC_BASE, CAC_BASE + 0x400);
}
+
+#if (CONFIG_LTT)
+asmlinkage void trace_real_syscall_entry(struct pt_regs * regs)
+{
+ unsigned long addr;
+ int depth = 0;
+ unsigned long end_code;
+ unsigned long lower_bound;
+ int seek_depth;
+ unsigned long *stack;
+ unsigned long start_code;
+ unsigned long *start_stack;
+ ltt_syscall_entry trace_syscall_event;
+ unsigned long upper_bound;
+ int use_bounds;
+ int use_depth;
+
+ /* syscall_id will be negative for SVR4, IRIX5, BSD43, and POSIX
+ * syscalls -- these are not supported at this point by LTT
+ */
+ trace_syscall_event.syscall_id = (uint8_t) (regs->regs[2] - __NR_Linux);
+
+ trace_syscall_event.address = regs->cp0_epc;
+
+ 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;
+
+ /* Heuristic that might work:
+ * (BUT DOESN'T WORK for any of the cases I tested...) zzz
+ * Search through stack until a value is found that is within the
+ * range start_code .. end_code. (This is looking for a return
+ * pointer to where a shared library was called from.) If a stack
+ * variable contains a valid code address then an incorrect
+ * result will be generated.
+ */
+ if ((use_depth == 1) || (use_bounds == 1)) {
+ stack = (unsigned long*) regs->regs[29];
+ end_code = current->mm->end_code;
+ start_code = current->mm->start_code;
+ start_stack = (unsigned long *)current->mm->start_stack;
+
+ while ((stack <= start_stack) && (!__get_user(addr, stack))) {
+ if ((addr > start_code) && (addr < end_code)) {
+ if (((use_depth == 1) && (depth == seek_depth)) ||
+ ((use_bounds == 1) && (addr > lower_bound) && (addr < upper_bound)))
{
+ trace_syscall_event.address = addr;
+ goto trace_syscall_end;
+ } else {
+ depth++;
+ }
+ }
+ stack++;
+ }
+ }
+
+trace_syscall_end:
+ trace_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+ trace_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+
+#endif /* (CONFIG_LTT) */
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/mips/kernel/unaligned.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/kernel/unaligned.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/mips/kernel/unaligned.c 2004-10-18 17:55:36.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/kernel/unaligned.c 2004-12-14 17:58:04.000000000
-0500
@@ -78,6 +78,7 @@
#include <linux/signal.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
+#include <linux/ltt-events.h>
#include <asm/asm.h>
#include <asm/branch.h>
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/mips/mm/fault.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/mm/fault.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/mips/mm/fault.c 2004-10-18 17:53:45.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/mips/mm/fault.c 2004-12-14 17:58:04.000000000
-0500
@@ -60,6 +60,8 @@ asmlinkage void do_page_fault(struct pt_
if (unlikely(address >= VMALLOC_START))
goto vmalloc_fault;
+ ltt_ev_trap_entry(CAUSE_EXCCODE(regs), CAUSE_EPC(regs));
+
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
@@ -114,6 +116,7 @@ survive:
}
up_read(&mm->mmap_sem);
+ ltt_ev_trap_exit();
return;
/*
@@ -142,6 +145,7 @@ bad_area_nosemaphore:
/* info.si_code has been set above */
info.si_addr = (void *) address;
force_sig_info(SIGSEGV, &info, tsk);
+ ltt_ev_trap_exit();
return;
}
@@ -199,6 +203,7 @@ do_sigbus:
info.si_addr = (void *) address;
force_sig_info(SIGBUS, &info, tsk);
+ ltt_ev_trap_exit();
return;
vmalloc_fault:
@@ -233,4 +238,5 @@ vmalloc_fault:
goto no_context;
return;
}
+ ltt_ev_trap_exit();
}
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/entry.S
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/entry.S
--- linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/entry.S 2004-10-18 17:55:06.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/entry.S 2004-12-14 17:58:04.000000000
-0500
@@ -156,6 +156,34 @@ transfer_to_handler_cont:
SYNC
RFI /* jump to handler, enable MMU */
+/* LTT stuff */
+#if (CONFIG_LTT)
+#define TRACE_REAL_ASM_SYSCALL_ENTRY \
+ SAVE_NVGPRS(r1); \
+ 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); \
+ REST_NVGPRS(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
+
/*
* On kernel stack overflow, load up an initial stack pointer
* and call StackOverflow(regs), which should not return.
@@ -213,6 +241,9 @@ syscall_dotrace_cont:
bge- 66f
lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
mtlr r10
+#if (CONFIG_LTT)
+ TRACE_REAL_ASM_SYSCALL_ENTRY ;
+#endif
addi r9,r1,STACK_FRAME_OVERHEAD
blrl /* Call handler */
.globl ret_from_syscall
@@ -220,6 +251,10 @@ ret_from_syscall:
#ifdef SHOW_SYSCALLS
bl do_show_syscall_exit
#endif
+#if (CONFIG_LTT)
+ stw r3,RESULT(r1) /* Save result */
+ TRACE_REAL_ASM_SYSCALL_EXIT ;
+#endif
mr r6,r3
li r11,-_LAST_ERRNO
cmplw 0,r3,r11
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/misc.S
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/misc.S
--- linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/misc.S 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/misc.S 2004-12-14 17:58:04.000000000
-0500
@@ -1130,7 +1130,11 @@ _GLOBAL(cvt_df)
* Create a kernel thread
* kernel_thread(fn, arg, flags)
*/
+#if (CONFIG_LTT)
+_GLOBAL(original_kernel_thread)
+#else
_GLOBAL(kernel_thread)
+#endif /* (CONFIG_LTT) */
stwu r1,-16(r1)
stw r30,8(r1)
stw r31,12(r1)
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/process.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/process.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/process.c 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/process.c 2004-12-14 17:58:04.000000000
-0500
@@ -37,6 +37,7 @@
#include <linux/kallsyms.h>
#include <linux/mqueue.h>
#include <linux/hardirq.h>
+#include <linux/ltt-events.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -364,6 +365,19 @@ void show_regs(struct pt_regs * regs)
show_stack(current, (unsigned long *) regs->gpr[1]);
}
+#if (CONFIG_LTT)
+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_LTT) */
+
void exit_thread(void)
{
if (last_task_used_math == current)
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/syscalls.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/syscalls.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/syscalls.c 2004-10-18 17:55:28.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/syscalls.c 2004-12-14 17:58:04.000000000
-0500
@@ -36,6 +36,7 @@
#include <linux/utsname.h>
#include <linux/file.h>
#include <linux/unistd.h>
+#include <linux/ltt-events.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -59,6 +60,8 @@ sys_ipc (uint call, int first, int secon
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
+ ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
ret = -ENOSYS;
switch (call) {
case SEMOP:
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/time.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/time.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/time.c 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/time.c 2004-12-14 17:58:04.000000000
-0500
@@ -57,6 +57,7 @@
#include <linux/time.h>
#include <linux/init.h>
#include <linux/profile.h>
+#include <linux/ltt-events.h>
#include <asm/segment.h>
#include <asm/io.h>
@@ -136,6 +137,8 @@ void timer_interrupt(struct pt_regs * re
if (atomic_read(&ppc_n_lost_interrupts) != 0)
do_IRQ(regs);
+ ltt_ev_trap_entry(regs->trap, instruction_pointer(regs));
+
irq_enter();
while ((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) <= 0) {
@@ -194,6 +197,8 @@ void timer_interrupt(struct pt_regs * re
ppc_md.heartbeat();
irq_exit();
+
+ ltt_ev_trap_exit();
}
/*
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/traps.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/traps.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/ppc/kernel/traps.c 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/kernel/traps.c 2004-12-14 17:58:04.000000000
-0500
@@ -31,6 +31,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/prctl.h>
+#include <linux/ltt-events.h>
#include <asm/pgtable.h>
#include <asm/uaccess.h>
@@ -601,6 +602,84 @@ void StackOverflow(struct pt_regs *regs)
panic("kernel stack overflow");
}
+/* Trace related code */
+#if (CONFIG_LTT)
+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;
+ ltt_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 (ltt_get_trace_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 */
+ ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+ ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+
+#endif /* (CONFIG_LTT) */
+
void nonrecoverable_exception(struct pt_regs *regs)
{
printk(KERN_ERR "Non-recoverable exception at PC=%lx MSR=%lx\n",
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/ppc/mm/fault.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/mm/fault.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/ppc/mm/fault.c 2004-10-18 17:53:45.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/ppc/mm/fault.c 2004-12-14 17:58:04.000000000
-0500
@@ -28,6 +28,7 @@
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <linux/module.h>
+#include <linux/ltt-events.h>
#include <asm/page.h>
#include <asm/pgtable.h>
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/s390/kernel/entry.S
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/kernel/entry.S
--- linux-2.6.10-rc3-bk8-relayfs/arch/s390/kernel/entry.S 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/kernel/entry.S 2004-12-14 17:58:04.000000000
-0500
@@ -7,6 +7,7 @@
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
* Hartmut Penner (hp@de.ibm.com),
* Denis Joseph Barrow
(djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ * Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM
Corporation
*/
#include <linux/sys.h>
@@ -182,6 +183,13 @@ sysc_do_restart:
# ATTENTION: check sys_execve_glue before
# changing anything here !!
+#if (CONFIG_LTT) /* tjh - ltt port */
+ /* add call to trace_real_syscall_exit */
+ la %r2,SP_PTREGS(%r15) # load pt_regs as first parameter
+ l %r1,BASED(.Ltracesysext)
+ basr %r14,%r1
+ lm %r0,%r6,SP_R0(%r15) /* restore call clobbered regs */
+#endif
sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
bno BASED(sysc_leave)
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/s390/kernel/sys_s390.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/kernel/sys_s390.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/s390/kernel/sys_s390.c 2004-10-18 17:53:51.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/kernel/sys_s390.c 2004-12-14 17:58:04.000000000
-0500
@@ -151,6 +151,8 @@ asmlinkage long sys_ipc(uint call, int f
struct ipc_kludge tmp;
int ret;
+ ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
switch (call) {
case SEMOP:
return sys_semtimedop (first, (struct sembuf __user *) ptr, second,
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/s390/kernel/traps.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/kernel/traps.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/s390/kernel/traps.c 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/kernel/traps.c 2004-12-14 22:02:55.000000000
-0500
@@ -5,6 +5,7 @@
* Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM
Corporation
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
* Denis Joseph Barrow
(djbarrow@de.ibm.com,barrow_dj@yahoo.com),
+ * Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM
Corporation
*
* Derived from "arch/i386/kernel/traps.c"
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -29,6 +30,7 @@
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/ltt-events.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -311,6 +313,9 @@ report_user_fault(long interruption_code
static void inline do_trap(long interruption_code, int signr, char *str,
struct pt_regs *regs, siginfo_t *info)
{
+ trapid_t ltt_interruption_code;
+ char * ic_ptr = (char *) <t_interruption_code;
+
/*
* We got all needed information from the lowcore and can
* now safely switch on interrupts.
@@ -318,6 +323,10 @@ static void inline do_trap(long interrup
if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable();
+ memset(<t_interruption_code,0,sizeof(ltt_interruption_code));
+ memcpy(ic_ptr+4,&interruption_code,sizeof(interruption_code));
+ ltt_ev_trap_entry(ltt_interruption_code, (regs->psw.addr & PSW_ADDR_INSN));
+
if (regs->psw.mask & PSW_MASK_PSTATE) {
struct task_struct *tsk = current;
@@ -332,6 +341,7 @@ static void inline do_trap(long interrup
else
die(str, regs, interruption_code);
}
+ ltt_ev_trap_exit();
}
static inline void *get_check_address(struct pt_regs *regs)
@@ -428,6 +438,8 @@ asmlinkage void illegal_op(struct pt_reg
siginfo_t info;
__u8 opcode[6];
__u16 *location;
+ trapid_t ltt_interruption_code;
+ char * ic_ptr = (char *) <t_interruption_code;
int signal = 0;
location = (__u16 *) get_check_address(regs);
@@ -490,6 +502,7 @@ asmlinkage void illegal_op(struct pt_reg
do_trap(interruption_code, signal,
"illegal operation", regs, &info);
}
+ ltt_ev_trap_exit();
}
@@ -499,6 +512,8 @@ specification_exception(struct pt_regs *
{
__u8 opcode[6];
__u16 *location = NULL;
+ trapid_t ltt_interruption_code;
+ char * ic_ptr = (char *) <t_interruption_code;
int signal = 0;
location = (__u16 *) get_check_address(regs);
@@ -554,6 +569,7 @@ specification_exception(struct pt_regs *
do_trap(interruption_code, signal,
"specification exception", regs, &info);
}
+ ltt_ev_trap_exit();
}
#else
DO_ERROR_INFO(SIGILL, "specification exception", specification_exception,
@@ -563,6 +579,8 @@ DO_ERROR_INFO(SIGILL, "specification exc
asmlinkage void data_exception(struct pt_regs * regs, long
interruption_code)
{
__u16 *location;
+ trapid_t ltt_interruption_code;
+ char * ic_ptr = (char *) <t_interruption_code;
int signal = 0;
location = (__u16 *) get_check_address(regs);
@@ -574,6 +592,10 @@ asmlinkage void data_exception(struct pt
if (regs->psw.mask & PSW_MASK_PSTATE)
local_irq_enable();
+ memset(<t_interruption_code,0,sizeof(ltt_interruption_code));
+ memcpy(ic_ptr+4,&interruption_code,sizeof(interruption_code));
+ ltt_ev_trap_entry(ltt_interruption_code, (regs->psw.addr & PSW_ADDR_INSN));
+
if (MACHINE_HAS_IEEE)
__asm__ volatile ("stfpc %0\n\t"
: "=m" (current->thread.fp_regs.fpc));
@@ -649,6 +671,7 @@ asmlinkage void data_exception(struct pt
do_trap(interruption_code, signal,
"data exception", regs, &info);
}
+ ltt_ev_trap_exit();
}
asmlinkage void space_switch_exception(struct pt_regs * regs, long int_code)
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/s390/mm/fault.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/mm/fault.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/s390/mm/fault.c 2004-10-18 17:55:43.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/s390/mm/fault.c 2004-12-14 17:58:04.000000000
-0500
@@ -5,6 +5,7 @@
* Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Hartmut Penner (hp@de.ibm.com)
* Ulrich Weigand (uweigand@de.ibm.com)
+ * Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM
Corporation
*
* Derived from "arch/i386/mm/fault.c"
* Copyright (C) 1995 Linus Torvalds
@@ -169,6 +170,8 @@ do_exception(struct pt_regs *regs, unsig
int user_address;
const struct exception_table_entry *fixup;
int si_code = SEGV_MAPERR;
+ trapid_t ltt_interruption_code;
+ char * ic_ptr = (char *) <t_interruption_code;
tsk = current;
mm = tsk->mm;
@@ -216,6 +219,9 @@ do_exception(struct pt_regs *regs, unsig
*/
local_irq_enable();
+ memset(<t_interruption_code,0,sizeof(ltt_interruption_code));
+ memcpy(ic_ptr+4,&error_code,sizeof(error_code));
+ ltt_ev_trap_entry(ltt_interruption_code,(regs->psw.addr &
PSW_ADDR_INSN));
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
@@ -283,6 +289,7 @@ bad_area:
tsk->thread.prot_addr = address;
tsk->thread.trap_no = error_code;
do_sigsegv(regs, error_code, si_code, address);
+ ltt_ev_trap_exit();
return;
}
@@ -338,6 +345,8 @@ do_sigbus:
/* Kernel mode? Handle exceptions or die */
if (!(regs->psw.mask & PSW_MASK_PSTATE))
goto no_context;
+
+ ltt_ev_trap_exit();
}
void do_protection_exception(struct pt_regs *regs, unsigned long error_code)
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/irq.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/irq.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/irq.c 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/irq.c 2004-12-14 22:04:01.000000000
-0500
@@ -32,6 +32,7 @@
#include <linux/seq_file.h>
#include <linux/kallsyms.h>
#include <linux/bitops.h>
+#include <linux/ltt-events.h>
#include <asm/system.h>
#include <asm/io.h>
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/process.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/process.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/process.c 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/process.c 2004-12-14 17:58:04.000000000
-0500
@@ -20,6 +20,7 @@
#include <linux/ptrace.h>
#include <linux/platform.h>
#include <linux/kallsyms.h>
+#include <linux/ltt-events.h>
#include <asm/io.h>
#include <asm/uaccess.h>
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/sys_sh.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/sys_sh.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/sys_sh.c 2004-10-18 17:55:36.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/sys_sh.c 2004-12-14 17:58:04.000000000
-0500
@@ -21,6 +21,7 @@
#include <linux/mman.h>
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/ltt-events.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -166,6 +167,8 @@ asmlinkage int sys_ipc(uint call, int fi
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
+ ltt_ev_ipc(LTT_EV_IPC_CALL, call, first);
+
if (call <= SEMCTL)
switch (call) {
case SEMOP:
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/traps.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/traps.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/sh/kernel/traps.c 2004-12-14 17:43:59.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/kernel/traps.c 2004-12-14 17:58:04.000000000
-0500
@@ -27,6 +27,7 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/kallsyms.h>
+#include <linux/ltt-events.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -500,6 +501,8 @@ asmlinkage void do_address_error(struct
asm volatile("stc r2_bank,%0": "=r" (error_code));
+ ltt_ev_trap_entry(error_code >> 5, regs->pc);
+
oldfs = get_fs();
if (user_mode(regs)) {
@@ -523,8 +526,10 @@ asmlinkage void do_address_error(struct
tmp = handle_unaligned_access(instruction, regs);
set_fs(oldfs);
- if (tmp==0)
- return; /* sorted */
+ if (tmp==0) {
+ ltt_ev_trap_exit();
+ return; /* sorted */
+ }
uspace_segv:
printk(KERN_NOTICE "Killing process \"%s\" due to unaligned access\n",
current->comm);
@@ -545,6 +550,7 @@ asmlinkage void do_address_error(struct
handle_unaligned_access(instruction, regs);
set_fs(oldfs);
}
+ ltt_ev_trap_exit();
}
#ifdef CONFIG_SH_DSP
@@ -704,6 +710,77 @@ void show_task(unsigned long *sp)
{
show_stack(NULL, sp);
}
+/* Trace related code */
+#if (CONFIG_LTT)
+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;
+ ltt_syscall_entry trace_syscall_event;
+
+ /* Set the syscall ID */
+ trace_syscall_event.syscall_id = (uint8_t) regs->regs[REG_REG0 + 3];
+
+ /* Set the address in any case */
+ trace_syscall_event.address = regs->pc;
+
+ /* 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 (ltt_get_trace_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->regs[REG_REG15];
+
+ /* Keep on going until we reach the end of the process' stack limit (wherever it may be)
*/
+ while (!get_user(addr, stack)) {
+ /* Does this LOOK LIKE an address in the program */
+ /* TODO: does this work with shared libraries?? - Greg Banks */
+ 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 */
+ stack++;
+ }
+ }
+trace_syscall_end:
+ /* Trace the event */
+ ltt_log_event(LTT_EV_SYSCALL_ENTRY, &trace_syscall_event);
+}
+
+asmlinkage void trace_real_syscall_exit(void)
+{
+ ltt_log_event(LTT_EV_SYSCALL_EXIT, NULL);
+}
+
+#endif /* (CONFIG_LTT) */
void dump_stack(void)
{
diff -urpN linux-2.6.10-rc3-bk8-relayfs/arch/sh/mm/fault.c
linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/mm/fault.c
--- linux-2.6.10-rc3-bk8-relayfs/arch/sh/mm/fault.c 2004-10-18 17:53:45.000000000
-0400
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/arch/sh/mm/fault.c 2004-12-14 17:58:04.000000000
-0500
@@ -21,6 +21,7 @@
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
#include <linux/module.h>
+#include <linux/ltt-events.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -53,6 +54,14 @@ asmlinkage void do_page_fault(struct pt_
tsk = current;
mm = tsk->mm;
+#if (CONFIG_LTT)
+ {
+ unsigned long trapnr;
+ asm volatile("stc r2_bank,%0": "=r" (trapnr));
+ ltt_ev_trap_entry(trapnr >> 5, regs->pc); /* trap 4,5 or 6 */
+ }
+#endif
+
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
@@ -106,6 +115,7 @@ survive:
}
up_read(&mm->mmap_sem);
+ ltt_ev_trap_exit();
return;
/*
@@ -119,6 +129,7 @@ bad_area:
tsk->thread.address = address;
tsk->thread.error_code = writeaccess;
force_sig(SIGSEGV, tsk);
+ ltt_ev_trap_exit();
return;
}
@@ -185,6 +196,8 @@ do_sigbus:
/* Kernel mode? Handle exceptions or die */
if (!user_mode(regs))
goto no_context;
+
+ ltt_ev_trap_exit();
}
/*
diff -urpN linux-2.6.10-rc3-bk8-relayfs/include/asm-arm/ltt.h
linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-arm/ltt.h
--- linux-2.6.10-rc3-bk8-relayfs/include/asm-arm/ltt.h 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-arm/ltt.h 2004-12-14 17:58:04.000000000
-0500
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-arm/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * ARM definitions for tracing system
+ */
+
+#include <linux/ltt-events.h>
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_ARM
+
+/* Current variant type */
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE
diff -urpN linux-2.6.10-rc3-bk8-relayfs/include/asm-i386/ltt.h
linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-i386/ltt.h
--- linux-2.6.10-rc3-bk8-relayfs/include/asm-i386/ltt.h 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-i386/ltt.h 2004-12-14 17:58:04.000000000
-0500
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-i386/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * i386 definitions for tracing system
+ */
+
+#include <linux/ltt-events.h>
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_I386
+
+/* Current variant type */
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE
diff -urpN linux-2.6.10-rc3-bk8-relayfs/include/asm-mips/ltt.h
linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-mips/ltt.h
--- linux-2.6.10-rc3-bk8-relayfs/include/asm-mips/ltt.h 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-mips/ltt.h 2004-12-14 17:58:04.000000000
-0500
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-mips/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * MIPS definitions for tracing system
+ */
+
+#include <linux/ltt-events.h>
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_MIPS
+
+/* Current variant type */
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE
diff -urpN linux-2.6.10-rc3-bk8-relayfs/include/asm-ppc/ltt.h
linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-ppc/ltt.h
--- linux-2.6.10-rc3-bk8-relayfs/include/asm-ppc/ltt.h 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-ppc/ltt.h 2004-12-14 17:58:04.000000000
-0500
@@ -0,0 +1,30 @@
+/*
+ * linux/include/asm-ppc/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * PowerPC definitions for tracing system
+ */
+
+#include <linux/config.h>
+#include <linux/ltt-events.h>
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_PPC
+
+/* PowerPC variants */
+#define LTT_ARCH_VARIANT_PPC_4xx 1 /* 4xx systems (IBM embedded series)
*/
+#define LTT_ARCH_VARIANT_PPC_6xx 2 /* 6xx/7xx/74xx/8260/POWER3 systems (desktop flavor)
*/
+#define LTT_ARCH_VARIANT_PPC_8xx 3 /* 8xx system (Motoral embedded series)
*/
+#define LTT_ARCH_VARIANT_PPC_ISERIES 4 /* 8xx system (iSeries) */
+
+/* Current variant type */
+#if defined(CONFIG_4xx)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_4xx
+#elif defined(CONFIG_6xx)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_6xx
+#elif defined(CONFIG_8xx)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_8xx
+#elif defined(CONFIG_PPC_ISERIES)
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_PPC_ISERIES
+#endif
diff -urpN linux-2.6.10-rc3-bk8-relayfs/include/asm-s390/ltt.h
linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-s390/ltt.h
--- linux-2.6.10-rc3-bk8-relayfs/include/asm-s390/ltt.h 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-s390/ltt.h 2004-12-14 17:58:04.000000000
-0500
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-s390/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * S/390 definitions for tracing system
+ */
+
+#include <linux/ltt-events.h>
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_S390
+
+/* Current variant type */
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE
diff -urpN linux-2.6.10-rc3-bk8-relayfs/include/asm-sh/ltt.h
linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-sh/ltt.h
--- linux-2.6.10-rc3-bk8-relayfs/include/asm-sh/ltt.h 1969-12-31 19:00:00.000000000
-0500
+++ linux-2.6.10-rc3-bk8-relayfs-ltt/include/asm-sh/ltt.h 2004-12-14 17:58:04.000000000
-0500
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-sh/ltt.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * SuperH definitions for tracing system
+ */
+
+#include <linux/ltt-events.h>
+
+/* Current arch type */
+#define LTT_ARCH_TYPE LTT_ARCH_TYPE_SH
+
+/* Current variant type */
+#define LTT_ARCH_VARIANT LTT_ARCH_VARIANT_NONE