aboutsummaryrefslogtreecommitdiff
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>2011-03-16 19:05:01 -0400
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>2011-03-16 19:05:01 -0400
commita7224dc2eeaa82a85b80ee21168881bfb321f770 (patch)
treed13eb9fbfb726dab91740d2a469ed571f2678a09 /arch/s390/kernel
parent26549e025525e49e53ef68b01c15ff793c3d3c24 (diff)
lttng-instrumentation/lttng-instrumentation-s390
LTTng - s390 instrumentation Changelog : - added syscall entry/exit instrumentation. - 2.6.37: large update (style changes in mainline). Added space_switch_exception. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/ptrace.c5
-rw-r--r--arch/s390/kernel/sys_s390.c5
-rw-r--r--arch/s390/kernel/traps.c39
3 files changed, 42 insertions, 7 deletions
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index ef86ad24398..df0af62a76d 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -45,6 +45,9 @@ enum s390_regset {
REGSET_GENERAL_EXTENDED,
};
+DEFINE_TRACE(syscall_entry);
+DEFINE_TRACE(syscall_exit);
+
void update_per_regs(struct task_struct *task)
{
static const struct per_regs per_single_step = {
@@ -723,6 +726,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
/* Do the secure computing check first. */
secure_computing(regs->gprs[2]);
+ trace_syscall_entry(regs, regs->gprs[2]);
/*
* The sysc_tracesys code in entry.S stored the system
* call number to gprs[2].
@@ -753,6 +757,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)
{
+ trace_syscall_exit(regs->gprs[2]);
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),
regs->gprs[2]);
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 476081440df..dcc9d509af0 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -29,9 +29,12 @@
#include <linux/personality.h>
#include <linux/unistd.h>
#include <linux/ipc.h>
+#include <trace/ipc.h>
#include <asm/uaccess.h>
#include "entry.h"
+DEFINE_TRACE(ipc_call);
+
/*
* Perform the mmap() system call. Linux for S/390 isn't able to handle more
* than 5 system call parameters, so this system call uses a memory block
@@ -70,6 +73,8 @@ SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
struct ipc_kludge tmp;
int ret;
+ trace_ipc_call(call, first);
+
switch (call) {
case SEMOP:
return sys_semtimedop(first, (struct sembuf __user *)ptr,
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index b5a4a739b47..ff0dc02adc3 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -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
@@ -33,6 +34,7 @@
#include <linux/kprobes.h>
#include <linux/bug.h>
#include <linux/utsname.h>
+#include <trace/trap.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -65,6 +67,12 @@ static int kstack_depth_to_print = 20;
#endif /* CONFIG_64BIT */
/*
+ * Also used in fault.c.
+ */
+DEFINE_TRACE(trap_entry);
+DEFINE_TRACE(trap_exit);
+
+/*
* For show_trace we have tree different stack to consider:
* - the panic stack which is used if the kernel stack has overflown
* - the asynchronous interrupt stack (cpu related)
@@ -299,6 +307,8 @@ static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str,
pgm_int_code, signr) == NOTIFY_STOP)
return;
+ trace_trap_entry(regs, pgm_int_code & 0xffff);
+
if (regs->psw.mask & PSW_MASK_PSTATE) {
struct task_struct *tsk = current;
@@ -314,11 +324,14 @@ static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str,
enum bug_trap_type btt;
btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
- if (btt == BUG_TRAP_TYPE_WARN)
+ if (btt == BUG_TRAP_TYPE_WARN) {
+ trace_trap_exit();
return;
+ }
die(str, regs, pgm_int_code);
}
}
+ trace_trap_exit();
}
static inline void __user *get_psw_address(struct pt_regs *regs,
@@ -422,9 +435,11 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
location = get_psw_address(regs, pgm_int_code);
+ trace_trap_entry(regs, pgm_int_code & 0xffff);
+
if (regs->psw.mask & PSW_MASK_PSTATE) {
if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
- return;
+ goto end;
if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
if (tracehook_consider_fatal_signal(current, SIGTRAP))
force_sig(SIGTRAP, current);
@@ -433,24 +448,24 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
#ifdef CONFIG_MATHEMU
} else if (opcode[0] == 0xb3) {
if (get_user(*((__u16 *) (opcode+2)), location+1))
- return;
+ goto end;
signal = math_emu_b3(opcode, regs);
} else if (opcode[0] == 0xed) {
if (get_user(*((__u32 *) (opcode+2)),
(__u32 __user *)(location+1)))
- return;
+ goto end;
signal = math_emu_ed(opcode, regs);
} else if (*((__u16 *) opcode) == 0xb299) {
if (get_user(*((__u16 *) (opcode+2)), location+1))
- return;
+ goto end;
signal = math_emu_srnm(opcode, regs);
} else if (*((__u16 *) opcode) == 0xb29c) {
if (get_user(*((__u16 *) (opcode+2)), location+1))
- return;
+ goto end;
signal = math_emu_stfpc(opcode, regs);
} else if (*((__u16 *) opcode) == 0xb29d) {
if (get_user(*((__u16 *) (opcode+2)), location+1))
- return;
+ goto end;
signal = math_emu_lfpc(opcode, regs);
#endif
} else
@@ -486,6 +501,8 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
do_trap(pgm_int_code, signal,
"illegal operation", regs, &info);
}
+end:
+ trace_trap_exit();
}
@@ -500,6 +517,8 @@ asmlinkage void specification_exception(struct pt_regs *regs,
location = (__u16 __user *) get_psw_address(regs, pgm_int_code);
+ trace_trap_entry(regs, pgm_int_code & 0xffff);
+
if (regs->psw.mask & PSW_MASK_PSTATE) {
get_user(*((__u16 *) opcode), location);
switch (opcode[0]) {
@@ -544,6 +563,7 @@ asmlinkage void specification_exception(struct pt_regs *regs,
do_trap(pgm_int_code, signal,
"specification exception", regs, &info);
}
+ trace_trap_exit();
}
#else
DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
@@ -558,6 +578,8 @@ static void data_exception(struct pt_regs *regs, long pgm_int_code,
location = get_psw_address(regs, pgm_int_code);
+ trace_trap_entry(regs, pgm_int_code & 0xffff);
+
if (MACHINE_HAS_IEEE)
asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
@@ -631,6 +653,7 @@ static void data_exception(struct pt_regs *regs, long pgm_int_code,
info.si_addr = location;
do_trap(pgm_int_code, signal, "data exception", regs, &info);
}
+ trace_trap_exit();
}
static void space_switch_exception(struct pt_regs *regs, long pgm_int_code,
@@ -638,6 +661,7 @@ static void space_switch_exception(struct pt_regs *regs, long pgm_int_code,
{
siginfo_t info;
+ trace_trap_entry(regs, pgm_int_code & 0xffff);
/* Set user psw back to home space mode. */
if (regs->psw.mask & PSW_MASK_PSTATE)
regs->psw.mask |= PSW_ASC_HOME;
@@ -647,6 +671,7 @@ static void space_switch_exception(struct pt_regs *regs, long pgm_int_code,
info.si_code = ILL_PRVOPC;
info.si_addr = get_psw_address(regs, pgm_int_code);
do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
+ trace_trap_exit();
}
asmlinkage void __kprobes kernel_stack_overflow(struct pt_regs * regs)