diff options
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 3 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 3 | ||||
-rw-r--r-- | arch/s390/kernel/ptrace.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/sys_s390.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/traps.c | 39 | ||||
-rw-r--r-- | arch/s390/mm/fault.c | 10 |
7 files changed, 58 insertions, 9 deletions
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index ad1382f7932..637ce13517a 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -94,6 +94,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ #define TIF_SECCOMP 10 /* secure computing */ #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ +#define TIF_KERNEL_TRACE 12 /* kernel trace active */ #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_31BIT 17 /* 32bit process */ @@ -113,6 +114,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) #define _TIF_SECCOMP (1<<TIF_SECCOMP) #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) +#define _TIF_KERNEL_TRACE (1<<TIF_KERNEL_TRACE) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) #define _TIF_31BIT (1<<TIF_31BIT) #define _TIF_SINGLE_STEP (1<<TIF_FREEZE) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 648f64239a9..831874ffbc6 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -52,7 +52,8 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_MCCK_PENDING) _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ - _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) + _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8 | \ + _TIF_KERNEL_TRACE>>8) STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER STACK_SIZE = 1 << STACK_SHIFT diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 9d3603d6c51..7b5255e3b94 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -55,7 +55,8 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ _TIF_MCCK_PENDING) _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ - _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) + _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8 | \ + _TIF_KERNEL_TRACE>>8) #define BASED(name) name-system_call(%r13) 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) diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 2c57806c085..f07b4d2cb53 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -5,6 +5,7 @@ * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation * Author(s): Hartmut Penner (hp@de.ibm.com) * Ulrich Weigand (uweigand@de.ibm.com) + * Portions added by T. Halloran: (C) Copyright 2002 IBM Poughkeepsie, IBM Corporation * * Derived from "arch/i386/mm/fault.c" * Copyright (C) 1995 Linus Torvalds @@ -31,6 +32,7 @@ #include <linux/kprobes.h> #include <linux/uaccess.h> #include <linux/hugetlb.h> +#include <trace/fault.h> #include <asm/asm-offsets.h> #include <asm/system.h> #include <asm/pgtable.h> @@ -39,6 +41,11 @@ #include <asm/compat.h> #include "../kernel/entry.h" +DEFINE_TRACE(page_fault_entry); +DEFINE_TRACE(page_fault_exit); +DEFINE_TRACE(page_fault_nosem_entry); +DEFINE_TRACE(page_fault_nosem_exit); + #ifndef CONFIG_64BIT #define __FAIL_ADDR_MASK 0x7ffff000 #define __SUBCODE_MASK 0x0200 @@ -272,7 +279,10 @@ static noinline void do_fault_error(struct pt_regs *regs, long int_code, /* User mode accesses just cause a SIGSEGV */ si_code = (fault == VM_FAULT_BADMAP) ? SEGV_MAPERR : SEGV_ACCERR; + trace_page_fault_nosem_entry(regs, int_code & 0xffff, + trans_exc_code); do_sigsegv(regs, int_code, si_code, trans_exc_code); + trace_page_fault_nosem_exit(); return; } case VM_FAULT_BADCONTEXT: |