diff options
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/entry.S | 2 | ||||
-rw-r--r-- | arch/mips/kernel/linux32.c | 5 | ||||
-rw-r--r-- | arch/mips/kernel/process.c | 9 | ||||
-rw-r--r-- | arch/mips/kernel/ptrace.c | 9 | ||||
-rw-r--r-- | arch/mips/kernel/scall32-o32.S | 2 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-64.S | 5 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-n32.S | 4 | ||||
-rw-r--r-- | arch/mips/kernel/scall64-o32.S | 10 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 3 | ||||
-rw-r--r-- | arch/mips/kernel/syscall.c | 66 | ||||
-rw-r--r-- | arch/mips/kernel/time.c | 1 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 25 | ||||
-rw-r--r-- | arch/mips/kernel/unaligned.c | 6 |
13 files changed, 131 insertions, 16 deletions
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index ffa331029e08..8c5410f97e7c 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S @@ -167,7 +167,7 @@ work_notifysig: # deal with pending signals and FEXPORT(syscall_exit_work_partial) SAVE_STATIC syscall_exit_work: - li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t0, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_KERNEL_TRACE and t0, a2 # a2 is preloaded with TI_FLAGS beqz t0, work_pending # trace bit set? local_irq_enable # could let do_syscall_trace() diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 876a75cc376f..76a82609626f 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -34,6 +34,7 @@ #include <linux/vfs.h> #include <linux/ipc.h> #include <linux/slab.h> +#include <trace/ipc.h> #include <net/sock.h> #include <net/scm.h> @@ -44,6 +45,8 @@ #include <asm/mmu_context.h> #include <asm/mman.h> +DEFINE_TRACE(ipc_call); + /* Use this to get at 32-bit user passed pointers. */ /* A() macro should be used for places where you e.g. have some internal variable u32 and just want to get @@ -166,6 +169,8 @@ SYSCALL_DEFINE6(32_ipc, u32, call, long, first, long, second, long, third, 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 :)) */ diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index ae167df73ddd..7d9bb1cdd7f9 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -25,6 +25,7 @@ #include <linux/completion.h> #include <linux/kallsyms.h> #include <linux/random.h> +#include <trace/sched.h> #include <asm/asm.h> #include <asm/bootinfo.h> @@ -42,6 +43,8 @@ #include <asm/inst.h> #include <asm/stacktrace.h> +DEFINE_TRACE(sched_kthread_create); + /* * The idle thread. There's no useful work to be done, so just try to conserve * power and have a low exit latency (ie sit in a loop waiting for somebody to @@ -234,6 +237,7 @@ static void __noreturn kernel_thread_helper(void *arg, int (*fn)(void *)) long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) { struct pt_regs regs; + long pid; memset(®s, 0, sizeof(regs)); @@ -249,7 +253,10 @@ long kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) #endif /* Ok, create the new process.. */ - return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); + pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, + 0, ®s, 0, NULL, NULL); + trace_sched_kthread_create(fn, pid); + return pid; } /* diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index d21c388c0116..79e1750cc7cc 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c @@ -25,6 +25,7 @@ #include <linux/security.h> #include <linux/audit.h> #include <linux/seccomp.h> +#include <trace/syscall.h> #include <asm/byteorder.h> #include <asm/cpu.h> @@ -39,6 +40,9 @@ #include <asm/bootinfo.h> #include <asm/reg.h> +DEFINE_TRACE(syscall_entry); +DEFINE_TRACE(syscall_exit); + /* * Called by kernel/ptrace.c when detaching.. * @@ -535,6 +539,11 @@ static inline int audit_arch(void) */ asmlinkage void do_syscall_trace(struct pt_regs *regs, int entryexit) { + if (!entryexit) + trace_syscall_entry(regs, regs->regs[2]); + else + trace_syscall_exit(regs->regs[2]); + /* do the secure computing check first */ if (!entryexit) secure_computing(regs->regs[2]); diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index fbaabad0e6e2..1b90e8255dab 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S @@ -52,7 +52,7 @@ NESTED(handle_sys, PT_SIZE, sp) stack_done: lw t0, TI_FLAGS($28) # syscall tracing enabled? - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_KERNEL_TRACE and t0, t1 bnez t0, syscall_trace_entry # -> yes diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 3f4179283207..c574a1a12f21 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S @@ -54,7 +54,7 @@ NESTED(handle_sys64, PT_SIZE, sp) sd a3, PT_R26(sp) # save a3 for syscall restarting - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_KERNEL_TRACE LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 bnez t0, syscall_trace_entry @@ -126,7 +126,8 @@ illegal_syscall: END(handle_sys64) .align 3 -sys_call_table: + .type sys_call_table,@object +EXPORT(sys_call_table) PTR sys_read /* 5000 */ PTR sys_write PTR sys_open diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index f08ece6d8acc..0d312c2d54d2 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S @@ -53,7 +53,7 @@ NESTED(handle_sysn32, PT_SIZE, sp) sd a3, PT_R26(sp) # save a3 for syscall restarting - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_KERNEL_TRACE LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 bnez t0, n32_syscall_trace_entry @@ -121,6 +121,8 @@ not_n32_scall: END(handle_sysn32) + .align 3 + .type sysn32_call_table,@object EXPORT(sysn32_call_table) PTR sys_read /* 6000 */ PTR sys_write diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 78d768a3e19d..635d0d84344e 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -53,7 +53,7 @@ NESTED(handle_sys, PT_SIZE, sp) sll a3, a3, 0 dsll t0, v0, 3 # offset into table - ld t2, (sys_call_table - (__NR_O32_Linux * 8))(t0) + ld t2, (syso32_call_table - (__NR_O32_Linux * 8))(t0) sd a3, PT_R26(sp) # save a3 for syscall restarting @@ -81,7 +81,7 @@ NESTED(handle_sys, PT_SIZE, sp) PTR 4b, bad_stack .previous - li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT + li t1, _TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_KERNEL_TRACE LONG_L t0, TI_FLAGS($28) # syscall tracing enabled? and t0, t1, t0 bnez t0, trace_a_syscall @@ -180,7 +180,7 @@ LEAF(sys32_syscall) beqz t0, einval # do not recurse dsll t1, t0, 3 beqz v0, einval - ld t2, sys_call_table(t1) # syscall routine + ld t2, syso32_call_table(t1) # syscall routine move a0, a1 # shift argument registers move a1, a2 @@ -202,8 +202,8 @@ einval: li v0, -ENOSYS END(sys32_syscall) .align 3 - .type sys_call_table,@object -sys_call_table: + .type syso32_call_table,@object +EXPORT(syso32_call_table) PTR sys32_syscall /* 4000 */ PTR sys_exit PTR sys_fork diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 383aeb95cb49..3faf9d20ee62 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -164,6 +164,9 @@ void __init smp_cpus_done(unsigned int max_cpus) { mp_ops->cpus_done(); synchronise_count_master(); +#ifdef CONFIG_HAVE_UNSYNCHRONIZED_TSC + test_tsc_synchronization(); +#endif } /* called from main before smp_init() */ diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 1dc6edff45e0..9965dedbcc15 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -31,6 +31,8 @@ #include <linux/slab.h> #include <linux/random.h> #include <linux/elf.h> +#include <linux/ipc.h> +#include <linux/kallsyms.h> #include <asm/asm.h> #include <asm/branch.h> @@ -464,3 +466,67 @@ int kernel_execve(const char *filename, return -__v0; } + +void ltt_dump_sys_call_table(void *call_data) +{ + int i; + char namebuf[KSYM_NAME_LEN]; + +#ifdef CONFIG_32BIT + for (i = 0; i < __NR_O32_Linux_syscalls; i++) { + extern struct { + unsigned long ptr; + long j; + } sys_call_table[]; + + sprint_symbol(namebuf, sys_call_table[i].ptr); + __trace_mark(0, syscall_state, sys_call_table, call_data, + "id %d address %p symbol %s", + i + __NR_O32_Linux, (void *)sys_call_table[i].ptr, + namebuf); + } +#endif +#ifdef CONFIG_64BIT +# ifdef CONFIG_MIPS32_O32 + for (i = 0; i < __NR_O32_Linux_syscalls; i++) { + extern unsigned long syso32_call_table[]; + + sprint_symbol(namebuf, syso32_call_table[i]); + __trace_mark(0, syscall_state, sys_call_table, call_data, + "id %d address %p symbol %s", + i + __NR_O32_Linux, (void *)syso32_call_table[i], + namebuf); + } +# endif + + for (i = 0; i < __NR_64_Linux_syscalls; i++) { + extern unsigned long sys_call_table[]; + + sprint_symbol(namebuf, sys_call_table[i]); + __trace_mark(0, syscall_state, sys_call_table, call_data, + "id %d address %p symbol %s", + i + __NR_64_Linux, (void *)sys_call_table[i], + namebuf); + } + +# ifdef CONFIG_MIPS32_N32 + for (i = 0; i < __NR_N32_Linux_syscalls; i++) { + extern unsigned long sysn32_call_table[]; + + sprint_symbol(namebuf, sysn32_call_table[i]); + __trace_mark(0, syscall_state, sys_call_table, call_data, + "id %d address %p symbol %s", + i + __NR_N32_Linux, (void *)sysn32_call_table[i], + namebuf); + } +# endif +#endif +} +EXPORT_SYMBOL_GPL(ltt_dump_sys_call_table); + +void ltt_dump_idt_table(void *call_data) +{ + /* No IDT information yet. */ + return; +} +EXPORT_SYMBOL_GPL(ltt_dump_idt_table); diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index fb7497405510..51561a75dcf5 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c @@ -70,6 +70,7 @@ EXPORT_SYMBOL(perf_irq); */ unsigned int mips_hpt_frequency; +EXPORT_SYMBOL(mips_hpt_frequency); /* * This function exists in order to cause an error due to a duplicate diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 71350f7f2d88..b6a12d70e8c6 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -30,6 +30,7 @@ #include <linux/kdb.h> #include <linux/irq.h> #include <linux/perf_event.h> +#include <trace/trap.h> #include <asm/bootinfo.h> #include <asm/branch.h> @@ -55,6 +56,12 @@ #include <asm/stacktrace.h> #include <asm/uasm.h> +/* + * Also used in unaligned.c and fault.c. + */ +DEFINE_TRACE(trap_entry); +DEFINE_TRACE(trap_exit); + extern void check_wait(void); extern asmlinkage void r4k_wait(void); extern asmlinkage void rollback_handle_int(void); @@ -321,7 +328,7 @@ static void __show_regs(const struct pt_regs *regs) printk("Cause : %08x\n", cause); - cause = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE; + cause = CAUSE_EXCCODE(cause); if (1 <= cause && cause <= 5) printk("BadVA : %0*lx\n", field, regs->cp0_badvaddr); @@ -698,6 +705,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) return; die_if_kernel("FP exception in kernel code", regs); + trace_trap_entry(regs, CAUSE_EXCCODE(regs->cp0_cause)); if (fcr31 & FPU_CSR_UNI_X) { int sig; void __user *fault_addr = NULL; @@ -730,7 +738,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) /* If something went wrong, signal */ process_fpemu_return(sig, fault_addr); - + trace_trap_exit(); return; } else if (fcr31 & FPU_CSR_INV_X) info.si_code = FPE_FLTINV; @@ -748,6 +756,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) info.si_errno = 0; info.si_addr = (void __user *) regs->cp0_epc; force_sig_info(SIGFPE, &info, current); + trace_trap_exit(); } static void do_trap_or_bp(struct pt_regs *regs, unsigned int code, @@ -979,6 +988,8 @@ asmlinkage void do_cpu(struct pt_regs *regs) int status; unsigned long __maybe_unused flags; + trace_trap_entry(regs, CAUSE_EXCCODE(regs->cp0_cause)); + die_if_kernel("do_cpu invoked from kernel context!", regs); cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; @@ -990,8 +1001,10 @@ asmlinkage void do_cpu(struct pt_regs *regs) opcode = 0; status = -1; - if (unlikely(compute_return_epc(regs) < 0)) + if (unlikely(compute_return_epc(regs) < 0)) { + trace_trap_exit(); return; + } if (unlikely(get_user(opcode, epc) < 0)) status = SIGSEGV; @@ -1009,7 +1022,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) regs->cp0_epc = old_epc; /* Undo skip-over. */ force_sig(status, current); } - + trace_trap_exit(); return; case 1: @@ -1029,11 +1042,12 @@ asmlinkage void do_cpu(struct pt_regs *regs) if (!process_fpemu_return(sig, fault_addr)) mt_ase_fp_affinity(); } - + trace_trap_exit(); return; case 2: raw_notifier_call_chain(&cu2_chain, CU2_EXCEPTION, regs); + trace_trap_exit(); return; case 3: @@ -1041,6 +1055,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) } force_sig(SIGILL, current); + trace_trap_exit(); } asmlinkage void do_mdmx(struct pt_regs *regs) diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index cfea1adfa153..d3af94de2402 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c @@ -79,6 +79,7 @@ #include <linux/sched.h> #include <linux/debugfs.h> #include <linux/perf_event.h> +#include <trace/trap.h> #include <asm/asm.h> #include <asm/branch.h> @@ -518,6 +519,7 @@ asmlinkage void do_ade(struct pt_regs *regs) perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, 0, regs, regs->cp0_badvaddr); + trace_trap_entry(regs, CAUSE_EXCCODE(regs->cp0_cause)); /* * Did we catch a fault trying to load an instruction? * Or are we running in MIPS16 mode? @@ -543,6 +545,8 @@ asmlinkage void do_ade(struct pt_regs *regs) emulate_load_store_insn(regs, (void __user *)regs->cp0_badvaddr, pc); set_fs(seg); + trace_trap_exit(); + return; sigbus: @@ -552,6 +556,8 @@ sigbus: /* * XXX On return from the signal handler we should advance the epc */ + + trace_trap_exit(); } #ifdef CONFIG_DEBUG_FS |