Skip to contentSkip to conversation

LTTng : Linux Trace Toolkit Next Generation 0.5.95, kernel 2.6.17

PATCH New Mathieu Desnoyers 1 participant 1 message Aug 30, 2006

lore
Share & tools
lore
#0 lore raw

PATCH 16/16 LTTng : Linux Trace Toolkit Next Generation 0.5.95, kernel 2.6.17

16- LTTng architecture dependant instrumentation : x86_64 patch-2.6.17-lttng-0.5.95-instrumentation-x86_64.diff

OpenPGP public key:              http://krystal.dyndns.org:8080/key/compudj.gpg
Key fingerprint:     8CD5 52C3 8E3C 4140 715F  BA06 3F25 A8FE 3BAE 9A68 
arch/x86_64/ia32/ia32entry.S +76 -1
@@ -113,9 +113,34 @@ ENTRY(ia32_sysenter_target)
 sysenter_do_call:	
 	cmpl	$(IA32_NR_syscalls-1),%eax
 	ja	ia32_badsys
+
+#if (CONFIG_LTT)
+	/* trace_real_syscall32_entry expects a pointer to a pt_regs
+	   structure so that it can get %eax (%rax) and %eip (%rip).
+	   These are the only two members of the structure that are used,
+	   so we must be sure that their value will be at the proper
+	   offset from the pointer we give to trace_real_syscall32_entry. */
+	leaq	-ARGOFFSET(%rsp),%rdi	      # compensate for 6 regs that
+					      # we haven't saved on entry
+	movq	%r9,R9(%rdi)
+	call	trace_real_syscall32_entry
+	movq	ORIG_RAX-ARGOFFSET(%rsp),%rax # get the syscall # back into rax
+	movq	RCX-ARGOFFSET(%rsp),%rcx      # restore the argument registers
+	movq	RDX-ARGOFFSET(%rsp),%rdx
+	movq	RSI-ARGOFFSET(%rsp),%rsi
+	movq	RDI-ARGOFFSET(%rsp),%rdi
+	movq	R9-ARGOFFSET(%rsp),%r9
+#endif
+
 	IA32_ARG_FIXUP 1
 	call	*ia32_sys_call_table(,%rax,8)
 	movq	%rax,RAX-ARGOFFSET(%rsp)
+
+#if (CONFIG_LTT)
+	call trace_real_syscall_exit
+	movq RAX-ARGOFFSET(%rsp),%rax
+#endif
+
 	GET_THREAD_INFO(%r10)
 	cli
 	testl	$_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
@@ -214,9 +239,34 @@ ENTRY(ia32_cstar_target)
 cstar_do_call:	
 	cmpl $IA32_NR_syscalls-1,%eax
 	ja  ia32_badsys
+
+#if (CONFIG_LTT)
+	/* trace_real_syscall32_entry expects a pointer to a pt_regs
+	   structure so that it can get %eax (%rax) and %eip (%rip).
+	   These are the only two members of the structure that are used,
+	   so we must be sure that their value will be at the proper
+	   offset from the pointer we give to trace_real_syscall32_entry. */
+	leaq -ARGOFFSET(%rsp),%rdi	   # compensate for 6 regs that
+					   # we haven't saved on entry
+	movq %r9,R9(%rdi)
+	call trace_real_syscall32_entry
+	movq ORIG_RAX-ARGOFFSET(%rsp),%rax # get the syscall # back into rax
+	movl %ebp,%ecx			   # restore the argument registers
+	movq RDX-ARGOFFSET(%rsp),%rdx
+	movq RSI-ARGOFFSET(%rsp),%rsi
+	movq RDI-ARGOFFSET(%rsp),%rdi
+	movq R9-ARGOFFSET(%rsp),%r9
+#endif
+
 	IA32_ARG_FIXUP 1
 	call *ia32_sys_call_table(,%rax,8)
 	movq %rax,RAX-ARGOFFSET(%rsp)
+
+#if (CONFIG_LTT)
+	call trace_real_syscall_exit
+	movq RAX-ARGOFFSET(%rsp),%rax
+#endif
+
 	GET_THREAD_INFO(%r10)
 	cli
 	testl $_TIF_ALLWORK_MASK,threadinfo_flags(%r10)
@@ -252,7 +302,7 @@ cstar_tracesys:	
 				
 ia32_badarg:
 	movq $-EFAULT,%rax
-	jmp ia32_sysret
+	jmp ia32_sysret_notrace
 	CFI_ENDPROC
 
 /* 
@@ -300,9 +350,32 @@ ENTRY(ia32_syscall)
 ia32_do_syscall:	
 	cmpl $(IA32_NR_syscalls-1),%eax
 	ja  ia32_badsys
+#ifdef CONFIG_LTT
+	/* trace_real_syscall32_entry expects a pointer to a pt_regs
+	   structure so that it can get %eax (%rax) and %eip (%rip).
+	   These are the only two members of the structure that are used,
+	   so we must be sure that their value will be at the proper
+	   offset from the pointer we give to trace_real_syscall32_entry. */
+	leaq -ARGOFFSET(%rsp),%rdi	   # compensate for 6 regs that
+					   # we haven't saved on entry
+	call trace_real_syscall32_entry
+	movq ORIG_RAX-ARGOFFSET(%rsp),%rax # get the syscall back into rax
+	movq RCX-ARGOFFSET(%rsp),%rcx	   # restore the argument registers
+	movq RDX-ARGOFFSET(%rsp),%rdx
+	movq RSI-ARGOFFSET(%rsp),%rsi
+	movq RDI-ARGOFFSET(%rsp),%rdi
+#endif
 	IA32_ARG_FIXUP
 	call *ia32_sys_call_table(,%rax,8) # xxx: rip relative
 ia32_sysret:
+
+#if (CONFIG_LTT)
+	movq %rax,RAX-ARGOFFSET(%rsp)
+	call trace_real_syscall_exit
+	movq RAX-ARGOFFSET(%rsp),%rax
+#endif
+
+ia32_sysret_notrace:
 	movq %rax,RAX-ARGOFFSET(%rsp)
 	jmp int_ret_from_sys_call 
 
@@ -696,4 +769,6 @@ #endif
 	.quad sys_sync_file_range
 	.quad sys_tee
 	.quad compat_sys_vmsplice
+	.quad sys_ltt_trace_generic	/* 317 */
+	.quad sys_ltt_register_generic	/* 318 */
 ia32_syscall_end:		
arch/x86_64/ia32/ipc32.c +3 -0
index 369151d..88d42aa 100644
@@ -8,6 +8,7 @@ #include <linux/msg.h>
 #include <linux/shm.h>
 #include <linux/ipc.h>
 #include <linux/compat.h>
+#include <linux/ltt/ltt-facility-ipc.h>
 
 #include <asm-i386/ipc.h>
 
@@ -20,6 +21,8 @@ sys32_ipc(u32 call, int first, int secon
 	version = call >> 16; /* hack for backward compatibility */
 	call &= 0xffff;
 
+	trace_ipc_call(call, first);
+
 	switch (call) {
 	      case SEMOP:
 		/* struct sembuf is the same on 32 and 64bit :)) */
arch/x86_64/kernel/entry.S +68 -0

119 lines not on this page · raw message

arch/x86_64/kernel/ltt.c new file +39 -0
new file mode 100644
index 0000000..b06dfe5
@@ -0,0 +1,39 @@
+/*
+ * ltt.c
+ *
+ * We need to fallback on calling functions instead of inlining only because of
+ * headers re-inclusion in critical kernel headers. This is necessary for irq,
+ * spinlock, ...
+ */
+
+#include <linux/module.h>
+#include <linux/ltt/ltt-facility-locking.h>
+#include <asm/ltt/ltt-facility-custom-locking.h>
+
+void _trace_locking_irq_save(const void * lttng_param_RIP,
+			     unsigned long lttng_param_flags)
+{
+	trace_locking_irq_save(lttng_param_RIP, lttng_param_flags);
+}
+
+void _trace_locking_irq_restore(const void * lttng_param_RIP,
+				unsigned long lttng_param_flags)
+{
+	trace_locking_irq_restore(lttng_param_RIP, lttng_param_flags);
+}
+
+void _trace_locking_irq_disable(const void * lttng_param_RIP)
+{
+	trace_locking_irq_disable(lttng_param_RIP);
+}
+
+void _trace_locking_irq_enable(const void * lttng_param_RIP)
+{
+	trace_locking_irq_enable(lttng_param_RIP);
+}
+
+
+EXPORT_SYMBOL(_trace_locking_irq_save);
+EXPORT_SYMBOL(_trace_locking_irq_restore);
+EXPORT_SYMBOL(_trace_locking_irq_disable);
+EXPORT_SYMBOL(_trace_locking_irq_enable);
arch/x86_64/kernel/Makefile +1 -0
index 7392570..8d53184 100644
@@ -33,6 +33,7 @@ obj-$(CONFIG_SWIOTLB)		+= pci-swiotlb.o
 obj-$(CONFIG_KPROBES)		+= kprobes.o
 obj-$(CONFIG_X86_PM_TIMER)	+= pmtimer.o
 obj-$(CONFIG_X86_VSMP)		+= vsmp.o
+obj-$(CONFIG_LTT)		+= ltt.o
 
 obj-$(CONFIG_MODULES)		+= module.o
 
arch/x86_64/kernel/time.c +5 -0
index 586b34c..35dbe74 100644
@@ -36,6 +36,7 @@ #include <asm/timex.h>
 #include <asm/proto.h>
 #include <asm/hpet.h>
 #include <asm/sections.h>
+#include <asm/ltt.h>
 #include <linux/cpufreq.h>
 #include <linux/hpet.h>
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -355,6 +356,10 @@ void main_timer_handler(struct pt_regs *
 
 	write_seqlock(&xtime_lock);
 
+#ifdef CONFIG_LTT
+	ltt_reset_timestamp();
+#endif //CONFIG_LTT
+
 	if (vxtime.hpet_address)
 		offset = hpet_readl(HPET_COUNTER);
 
arch/x86_64/kernel/traps.c +71 -2

169 lines not on this page · raw message

arch/x86_64/mm/fault.c +26 -8
index 5525059..b1a4ce8 100644
@@ -24,6 +24,7 @@ #include <linux/vt_kern.h>		/* For unbla
 #include <linux/compiler.h>
 #include <linux/module.h>
 #include <linux/kprobes.h>
+#include <linux/ltt/ltt-facility-kernel.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -345,8 +346,11 @@ asmlinkage void __kprobes do_page_fault(
 		 */
 		if (!(error_code & (PF_RSVD|PF_USER|PF_PROT)) &&
 		      ((address >= VMALLOC_START && address < VMALLOC_END))) {
-			if (vmalloc_fault(address) >= 0)
+			if (vmalloc_fault(address) >= 0) {
+				trace_kernel_trap_entry(14, (void*)regs->rip);
+				trace_kernel_trap_exit();
 				return;
+			}
 		}
 		if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14,
 						SIGSEGV) == NOTIFY_STOP)
@@ -379,6 +383,7 @@ asmlinkage void __kprobes do_page_fault(
 	if (unlikely(in_atomic() || !mm))
 		goto bad_area_nosemaphore;
 
+	trace_kernel_trap_entry(14, (void*)regs->rip);
  again:
 	/* When running in the kernel we expect faults to occur only to
 	 * addresses in user space.  All other faults represent errors in the
@@ -403,19 +408,22 @@ asmlinkage void __kprobes do_page_fault(
 	}
 
 	vma = find_vma(mm, address);
-	if (!vma)
+	if (!vma) {
 		goto bad_area;
+	}
 	if (likely(vma->vm_start <= address))
 		goto good_area;
-	if (!(vma->vm_flags & VM_GROWSDOWN))
+	if (!(vma->vm_flags & VM_GROWSDOWN)) {
 		goto bad_area;
+	}
 	if (error_code & 4) {
 		// XXX: align red zone size with ABI 
 		if (address + 128 < regs->rsp)
 			goto bad_area;
 	}
-	if (expand_stack(vma, address))
+	if (expand_stack(vma, address)) {
 		goto bad_area;
+	}
 /*
  * Ok, we have a good vm_area for this memory access, so
  * we can handle it..
@@ -427,15 +435,17 @@ good_area:
 		default:	/* 3: write, present */
 			/* fall through */
 		case PF_WRITE:		/* write, not present */
-			if (!(vma->vm_flags & VM_WRITE))
+			if (!(vma->vm_flags & VM_WRITE)) {
 				goto bad_area;
+			}
 			write++;
 			break;
 		case PF_PROT:		/* read, present */
 			goto bad_area;
 		case 0:			/* read, not present */
-			if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+			if (!(vma->vm_flags & (VM_READ | VM_EXEC))) {
 				goto bad_area;
+			}
 	}
 
 	/*
@@ -457,6 +467,7 @@ good_area:
 	}
 
 	up_read(&mm->mmap_sem);
+	trace_kernel_trap_exit();
 	return;
 
 /*
@@ -469,6 +480,7 @@ bad_area:
 bad_area_nosemaphore:
 	/* User mode accesses just cause a SIGSEGV */
 	if (error_code & PF_USER) {
+		trace_kernel_trap_exit();
 		if (is_prefetch(regs, address, error_code))
 			return;
 
@@ -556,16 +568,19 @@ out_of_memory:
 		goto again;
 	}
 	printk("VM: killing process %s\n", tsk->comm);
-	if (error_code & 4)
+	if (error_code & 4) {
+		trace_kernel_trap_exit();
 		do_exit(SIGKILL);
+	}
 	goto no_context;
 
 do_sigbus:
 	up_read(&mm->mmap_sem);
 
 	/* Kernel mode? Handle exceptions or die */
-	if (!(error_code & PF_USER))
+	if (!(error_code & PF_USER)) {
 		goto no_context;
+	}
 
 	tsk->thread.cr2 = address;
 	tsk->thread.error_code = error_code;
@@ -575,6 +590,9 @@ do_sigbus:
 	info.si_code = BUS_ADRERR;
 	info.si_addr = (void __user *)address;
 	force_sig_info(SIGBUS, &info, tsk);
+	/* No need to test for kernel page fault, we know we are not
+	   in one or else we would have jumped to no_context */
+	trace_kernel_trap_exit();
 	return;
 }
 
include/asm-x86_64/ia32_unistd.h +5 -0
index 36f3a17..6c0690c 100644
@@ -317,4 +317,9 @@ #define __NR_ia32_pselect6		308
 #define __NR_ia32_ppoll			309
 #define __NR_ia32_unshare		310
 
+/* A few defines seem to have been forgotten by kernel developers.
+   See arch/x86_64/ia32/ia32entry.S and include/asm-i386/unistd.h */
+#define __NR_ia32_ltt_trace_generic	317
+#define __NR_ia32_ltt_register_generic	318
+
 #endif /* _ASM_X86_64_IA32_UNISTD_H_ */
include/asm-x86_64/unistd.h +5 -1
new file mode 100644
index 0000000..aa93db7
@@ -617,8 +617,12 @@ #define __NR_sync_file_range	277
 __SYSCALL(__NR_sync_file_range, sys_sync_file_range)
 #define __NR_vmsplice		278
 __SYSCALL(__NR_vmsplice, sys_vmsplice)
+#define __NR_ltt_trace_generic		279
+__SYSCALL(__NR_ltt_trace_generic,	sys_ltt_trace_generic)
+#define __NR_ltt_register_generic		280
+__SYSCALL(__NR_ltt_register_generic,	sys_ltt_register_generic)
 
-#define __NR_syscall_max __NR_vmsplice
+#define __NR_syscall_max __NR_ltt_register_generic
 
 #ifndef __NO_STUBS
 
include/asm-x86_64/system.h +39 -7

70 lines not on this page · raw message

include/asm-x86_64/unistd.h +0 -0
index feb77cb..97eee2c 100644