* [PATCH] 4/8 LTT for 2.5.33: i386 trace support
@ 2002-09-06 22:16 Karim Yaghmour
0 siblings, 0 replies; only message in thread
From: Karim Yaghmour @ 2002-09-06 22:16 UTC (permalink / raw)
To: linux-kernel; +Cc: LTT-Dev
This patch adds the trace support for the i386. Here are the files
modified:
arch/i386/config.in
arch/i386/kernel/entry.S
arch/i386/kernel/irq.c
arch/i386/kernel/process.c
arch/i386/kernel/sys_i386.c
arch/i386/kernel/traps.c
arch/i386/mm/fault.c
include/asm-i386/trace.h
Contrary to previous versions, this patch does not make unconditional
calls to the tracing functions in entry.S. Instead, the system call/exit
tracing functions are called only when these events are traced. The
cost for fast-path system calls becomes negligeable with this addition.
diff -urN linux-2.5.33/arch/i386/config.in linux-2.5.33-ltt/arch/i386/config.in
--- linux-2.5.33/arch/i386/config.in Sat Aug 31 18:04:55 2002
+++ linux-2.5.33-ltt/arch/i386/config.in Fri Sep 6 12:03:20 2002
@@ -399,6 +399,8 @@
source net/bluetooth/Config.in
+source drivers/trace/Config.in
+
mainmenu_option next_comment
comment 'Kernel hacking'
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
diff -urN linux-2.5.33/arch/i386/kernel/entry.S linux-2.5.33-ltt/arch/i386/kernel/entry.S
--- linux-2.5.33/arch/i386/kernel/entry.S Sat Aug 31 18:04:53 2002
+++ linux-2.5.33-ltt/arch/i386/kernel/entry.S Fri Sep 6 16:36:52 2002
@@ -233,9 +233,27 @@
testb $_TIF_SYSCALL_TRACE,TI_FLAGS(%ebx)
jnz syscall_trace_entry
syscall_call:
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+ 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_TRACE || CONFIG_TRACE_MODULE)
+ 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 -urN linux-2.5.33/arch/i386/kernel/irq.c linux-2.5.33-ltt/arch/i386/kernel/irq.c
--- linux-2.5.33/arch/i386/kernel/irq.c Sat Aug 31 18:04:48 2002
+++ linux-2.5.33-ltt/arch/i386/kernel/irq.c Fri Sep 6 13:59:58 2002
@@ -33,6 +33,8 @@
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
+#include <linux/trace.h>
+
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/smp.h>
@@ -202,6 +204,8 @@
{
int status = 1; /* Force the "do bottom halves" bit */
+ TRACE_IRQ_ENTRY(irq, !(user_mode(regs)));
+
if (!(action->flags & SA_INTERRUPT))
local_irq_enable();
@@ -213,6 +217,8 @@
if (status & SA_SAMPLE_RANDOM)
add_interrupt_randomness(irq);
local_irq_disable();
+
+ TRACE_IRQ_EXIT();
return status;
}
diff -urN linux-2.5.33/arch/i386/kernel/process.c linux-2.5.33-ltt/arch/i386/kernel/process.c
--- linux-2.5.33/arch/i386/kernel/process.c Sat Aug 31 18:04:45 2002
+++ linux-2.5.33-ltt/arch/i386/kernel/process.c Fri Sep 6 16:34:45 2002
@@ -34,6 +34,8 @@
#include <linux/init.h>
#include <linux/mc146818rtc.h>
+#include <linux/trace.h>
+
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -505,6 +507,10 @@
/* Ok, create the new process.. */
p = do_fork(flags | CLONE_VM, 0, ®s, 0, NULL);
+#if (CONFIG_TRACE || CONFIG_TRACE_MODULE)
+ if(!IS_ERR(p))
+ TRACE_PROCESS(TRACE_EV_PROCESS_KTHREAD, p->pid, (int) fn);
+#endif
return IS_ERR(p) ? PTR_ERR(p) : p->pid;
}
diff -urN linux-2.5.33/arch/i386/kernel/sys_i386.c linux-2.5.33-ltt/arch/i386/kernel/sys_i386.c
--- linux-2.5.33/arch/i386/kernel/sys_i386.c Sat Aug 31 18:04:59 2002
+++ linux-2.5.33-ltt/arch/i386/kernel/sys_i386.c Fri Sep 6 12:03:20 2002
@@ -19,6 +19,8 @@
#include <linux/file.h>
#include <linux/utsname.h>
+#include <linux/trace.h>
+
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -136,6 +138,8 @@
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
+
+ TRACE_IPC(TRACE_EV_IPC_CALL, call, first);
switch (call) {
case SEMOP:
diff -urN linux-2.5.33/arch/i386/kernel/traps.c linux-2.5.33-ltt/arch/i386/kernel/traps.c
--- linux-2.5.33/arch/i386/kernel/traps.c Sat Aug 31 18:04:51 2002
+++ linux-2.5.33-ltt/arch/i386/kernel/traps.c Fri Sep 6 12:03:20 2002
@@ -28,6 +28,8 @@
#include <linux/ioport.h>
#endif
+#include <linux/trace.h>
+
#ifdef CONFIG_MCA
#include <linux/mca.h>
#include <asm/processor.h>
@@ -275,6 +277,82 @@
printk("Kernel BUG\n");
}
+/* 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->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(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->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 */
+ 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;
void die(const char * str, struct pt_regs * regs, long err)
@@ -308,6 +386,8 @@
static void inline do_trap(int trapnr, int signr, char *str, int vm86,
struct pt_regs * regs, long error_code, siginfo_t *info)
{
+ TRACE_TRAP_ENTRY(trapnr, regs->eip);
+
if (vm86 && regs->eflags & VM_MASK)
goto vm86_trap;
@@ -322,6 +402,7 @@
force_sig_info(signr, info, tsk);
else
force_sig(signr, tsk);
+ TRACE_TRAP_EXIT();
return;
}
@@ -347,14 +428,17 @@
regs->eip = fixup;
else
die(str, regs, error_code);
+ TRACE_TRAP_EXIT();
return;
}
vm86_trap: {
int ret = handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, trapnr);
if (ret) goto trap_signal;
+ TRACE_TRAP_EXIT();
return;
}
+ TRACE_TRAP_EXIT();
}
#define DO_ERROR(trapnr, signr, str, name) \
@@ -414,11 +498,15 @@
current->thread.error_code = error_code;
current->thread.trap_no = 13;
+ TRACE_TRAP_ENTRY(13, regs->eip);
force_sig(SIGSEGV, current);
+ TRACE_TRAP_EXIT();
return;
gp_in_vm86:
+ TRACE_TRAP_ENTRY(13, regs->eip);
handle_vm86_fault((struct kernel_vm86_regs *) regs, error_code);
+ TRACE_TRAP_EXIT();
return;
gp_in_kernel:
@@ -478,6 +566,11 @@
{
unsigned char reason = inb(0x61);
+#ifndef CONFIG_SMP /* On an SMP machine NMIs are used to implement a watchdog and will hang
+ the machine if traced. */
+ TRACE_TRAP_ENTRY(2, regs->eip);
+#endif
+
++nmi_count(smp_processor_id());
if (!(reason & 0xc0)) {
@@ -488,10 +581,12 @@
*/
if (nmi_watchdog) {
nmi_watchdog_tick(regs);
+ TRACE_TRAP_EXIT();
return;
}
#endif
unknown_nmi_error(reason, regs);
+ TRACE_TRAP_EXIT();
return;
}
if (reason & 0x80)
@@ -506,6 +601,8 @@
inb(0x71); /* dummy */
outb(0x0f, 0x70);
inb(0x71); /* dummy */
+
+ TRACE_TRAP_EXIT();
}
/*
@@ -579,7 +676,9 @@
*/
info.si_addr = ((regs->xcs & 3) == 0) ? (void *)tsk->thread.eip :
(void *)regs->eip;
+ TRACE_TRAP_ENTRY(1, regs->eip);
force_sig_info(SIGTRAP, &info, tsk);
+ TRACE_TRAP_EXIT();
/* Disable additional traps. They'll be re-enabled when
* the signal is delivered.
@@ -591,7 +690,9 @@
return;
debug_vm86:
+ TRACE_TRAP_ENTRY(1, regs->eip);
handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
+ TRACE_TRAP_EXIT();
return;
clear_TF:
@@ -740,10 +841,12 @@
asmlinkage void do_spurious_interrupt_bug(struct pt_regs * regs,
long error_code)
{
+ TRACE_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
+ TRACE_TRAP_EXIT();
}
/*
@@ -772,8 +875,10 @@
{
printk("math-emulation not enabled and no coprocessor found.\n");
printk("killing %s.\n",current->comm);
+ TRACE_TRAP_ENTRY(7, 0);
force_sig(SIGFPE,current);
schedule();
+ TRACE_TRAP_EXIT();
}
#endif /* CONFIG_MATH_EMULATION */
@@ -804,7 +909,6 @@
:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
"3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
} while (0)
-
/*
* This needs to use 'idt_table' rather than 'idt', and
diff -urN linux-2.5.33/arch/i386/mm/fault.c linux-2.5.33-ltt/arch/i386/mm/fault.c
--- linux-2.5.33/arch/i386/mm/fault.c Sat Aug 31 18:04:45 2002
+++ linux-2.5.33-ltt/arch/i386/mm/fault.c Fri Sep 6 12:03:20 2002
@@ -20,6 +20,8 @@
#include <linux/tty.h>
#include <linux/vt_kern.h> /* For unblank_screen() */
+#include <linux/trace.h>
+
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgalloc.h>
@@ -180,6 +182,8 @@
mm = tsk->mm;
info.si_code = SEGV_MAPERR;
+ TRACE_TRAP_ENTRY(14, regs->eip);
+
/*
* If we're in an interrupt, have no user context or are running in an
* atomic region then we must not take the fault..
@@ -264,6 +268,7 @@
tsk->thread.screen_bitmap |= 1 << bit;
}
up_read(&mm->mmap_sem);
+ TRACE_TRAP_EXIT();
return;
/*
@@ -283,6 +288,7 @@
/* info.si_code has been set above */
info.si_addr = (void *)address;
force_sig_info(SIGSEGV, &info, tsk);
+ TRACE_TRAP_EXIT();
return;
}
@@ -297,6 +303,7 @@
if (nr == 6) {
do_invalid_op(regs, 0);
+ TRACE_TRAP_EXIT();
return;
}
}
@@ -306,6 +313,7 @@
/* Are we prepared to handle this kernel fault? */
if ((fixup = search_exception_table(regs->eip)) != 0) {
regs->eip = fixup;
+ TRACE_TRAP_EXIT();
return;
}
@@ -379,6 +387,7 @@
/* Kernel mode? Handle exceptions or die */
if (!(error_code & 4))
goto no_context;
+ TRACE_TRAP_EXIT();
return;
vmalloc_fault:
@@ -412,6 +421,8 @@
pte_k = pte_offset_kernel(pmd_k, address);
if (!pte_present(*pte_k))
goto no_context;
+ TRACE_TRAP_EXIT();
return;
}
+ TRACE_TRAP_EXIT();
}
diff -urN linux-2.5.33/include/asm-i386/trace.h linux-2.5.33-ltt/include/asm-i386/trace.h
--- linux-2.5.33/include/asm-i386/trace.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.33-ltt/include/asm-i386/trace.h Fri Sep 6 12:03:21 2002
@@ -0,0 +1,15 @@
+/*
+ * linux/include/asm-i386/trace.h
+ *
+ * Copyright (C) 2002, Karim Yaghmour
+ *
+ * i386 definitions for tracing system
+ */
+
+#include <linux/trace.h>
+
+/* Current arch type */
+#define TRACE_ARCH_TYPE TRACE_ARCH_TYPE_I386
+
+/* Current variant type */
+#define TRACE_ARCH_VARIANT TRACE_ARCH_VARIANT_NONE
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-09-06 22:10 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-09-06 22:16 [PATCH] 4/8 LTT for 2.5.33: i386 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.