Skip to contentSkip to conversation

LTT for 2.5.36 5/9: PowerPC trace support

PATCH New Karim Yaghmour 1 participant 1 message Sep 19, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 LTT for 2.5.36 5/9: PowerPC trace support

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   
arch/ppc/config.in +2 -0
diff -urpN linux-2.5.36/arch/ppc/config.in linux-2.5.36-ltt/arch/ppc/config.in
@@ -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'
 
arch/ppc/kernel/entry.S +33 -0
diff -urpN linux-2.5.36/arch/ppc/kernel/entry.S linux-2.5.36-ltt/arch/ppc/kernel/entry.S
@@ -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
arch/ppc/kernel/irq.c +6 -0
diff -urpN linux-2.5.36/arch/ppc/kernel/irq.c linux-2.5.36-ltt/arch/ppc/kernel/irq.c
@@ -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 */
arch/ppc/kernel/misc.S +4 -0
diff -urpN linux-2.5.36/arch/ppc/kernel/misc.S linux-2.5.36-ltt/arch/ppc/kernel/misc.S
@@ -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)
arch/ppc/kernel/process.c +15 -0
diff -urpN linux-2.5.36/arch/ppc/kernel/process.c linux-2.5.36-ltt/arch/ppc/kernel/process.c
@@ -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)
 {
arch/ppc/kernel/syscalls.c +4 -0
diff -urpN linux-2.5.36/arch/ppc/kernel/syscalls.c linux-2.5.36-ltt/arch/ppc/kernel/syscalls.c
@@ -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) {
arch/ppc/kernel/time.c +6 -0
diff -urpN linux-2.5.36/arch/ppc/kernel/time.c linux-2.5.36-ltt/arch/ppc/kernel/time.c
@@ -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 */
 
arch/ppc/kernel/traps.c +82 -0

101 lines not on this page · raw message

arch/ppc/mm/fault.c +16 -1
diff -urpN linux-2.5.36/arch/ppc/mm/fault.c linux-2.5.36-ltt/arch/ppc/mm/fault.c
@@ -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();
 }
 
 /*
include/asm-ppc/trace.h +30 -0
diff -urpN linux-2.5.36/include/asm-ppc/trace.h linux-2.5.36-ltt/include/asm-ppc/trace.h
@@ -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