[PATCH] 4/8 LTT for 2.5.34: i386 trace support

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


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

diff -urN linux-2.5.34/arch/i386/config.in linux-2.5.34-ltt/arch/i386/config.in
--- linux-2.5.34/arch/i386/config.in Mon Sep 9 13:35:07 2002
+++ linux-2.5.34-ltt/arch/i386/config.in Mon Sep 9 19:06:34 2002
@@ -414,6 +414,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.34/arch/i386/kernel/entry.S linux-2.5.34-ltt/arch/i386/kernel/entry.S
--- linux-2.5.34/arch/i386/kernel/entry.S Mon Sep 9 13:35:06 2002
+++ linux-2.5.34-ltt/arch/i386/kernel/entry.S Mon Sep 9 19:06:34 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.34/arch/i386/kernel/irq.c linux-2.5.34-ltt/arch/i386/kernel/irq.c
--- linux-2.5.34/arch/i386/kernel/irq.c Mon Sep 9 13:35:01 2002
+++ linux-2.5.34-ltt/arch/i386/kernel/irq.c Mon Sep 9 19:06:34 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.34/arch/i386/kernel/process.c linux-2.5.34-ltt/arch/i386/kernel/process.c
--- linux-2.5.34/arch/i386/kernel/process.c Mon Sep 9 13:34:58 2002
+++ linux-2.5.34-ltt/arch/i386/kernel/process.c Mon Sep 9 19:06:34 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, &regs, 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.34/arch/i386/kernel/sys_i386.c linux-2.5.34-ltt/arch/i386/kernel/sys_i386.c
--- linux-2.5.34/arch/i386/kernel/sys_i386.c Mon Sep 9 13:35:09 2002
+++ linux-2.5.34-ltt/arch/i386/kernel/sys_i386.c Mon Sep 9 19:06:34 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.34/arch/i386/kernel/traps.c linux-2.5.34-ltt/arch/i386/kernel/traps.c
--- linux-2.5.34/arch/i386/kernel/traps.c Mon Sep 9 13:35:04 2002
+++ linux-2.5.34-ltt/arch/i386/kernel/traps.c Mon Sep 9 23:46:47 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,76 @@
         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 +380,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 +396,7 @@
                         force_sig_info(signr, info, tsk);
                 else
                         force_sig(signr, tsk);
+ TRACE_TRAP_EXIT();
                 return;
         }
 
@@ -347,14 +422,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 +492,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 +560,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 +575,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 +595,8 @@
         inb(0x71); /* dummy */
         outb(0x0f, 0x70);
         inb(0x71); /* dummy */
+
+ TRACE_TRAP_EXIT();
 }
 
 /*
@@ -579,7 +670,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 +684,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 +835,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 +869,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 +903,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.34/arch/i386/mm/fault.c linux-2.5.34-ltt/arch/i386/mm/fault.c
--- linux-2.5.34/arch/i386/mm/fault.c Mon Sep 9 13:34:59 2002
+++ linux-2.5.34-ltt/arch/i386/mm/fault.c Mon Sep 9 19:06:34 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.34/include/asm-i386/trace.h linux-2.5.34-ltt/include/asm-i386/trace.h
--- linux-2.5.34/include/asm-i386/trace.h Wed Dec 31 19:00:00 1969
+++ linux-2.5.34-ltt/include/asm-i386/trace.h Mon Sep 9 19:06:35 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
-
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