summaryrefslogtreecommitdiff
path: root/arch/sh
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>2011-03-16 19:05:00 -0400
committerMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>2011-03-16 19:05:00 -0400
commiteedb8dd005de7301c4ebf913edab768c6f5f3c22 (patch)
tree75b122d1b044b48b208e0a846908228228444937 /arch/sh
parentb6fe057e20fd792a5a6e16b48451de6cc6938c2b (diff)
lttng-instrumentation/lttng-instrumentation-sh
LTTng - instrumentation SH Partial SH64 instrumentation. Changelog: - fix do_fork instrumentation - fix redeclaration of ‘pid’ within process_<32/64>. - sh: spare fixes for LTTng (includes headers, DEFINE_TRACE) Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Diffstat (limited to 'arch/sh')
-rw-r--r--arch/sh/kernel/process_32.c5
-rw-r--r--arch/sh/kernel/process_64.c10
-rw-r--r--arch/sh/kernel/ptrace_32.c8
-rw-r--r--arch/sh/kernel/ptrace_64.c4
-rw-r--r--arch/sh/kernel/sys_sh.c3
-rw-r--r--arch/sh/kernel/traps_32.c11
-rw-r--r--arch/sh/mm/fault_32.c60
7 files changed, 88 insertions, 13 deletions
diff --git a/arch/sh/kernel/process_32.c b/arch/sh/kernel/process_32.c
index 762a13984bb..ddffe37d968 100644
--- a/arch/sh/kernel/process_32.c
+++ b/arch/sh/kernel/process_32.c
@@ -21,12 +21,15 @@
#include <linux/fs.h>
#include <linux/ftrace.h>
#include <linux/hw_breakpoint.h>
+#include <trace/sched.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/system.h>
#include <asm/fpu.h>
#include <asm/syscalls.h>
+DEFINE_TRACE(sched_kthread_create);
+
void show_regs(struct pt_regs * regs)
{
printk("\n");
@@ -94,6 +97,8 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
&regs, 0, NULL, NULL);
+ trace_sched_kthread_create(fn, pid);
+
return pid;
}
EXPORT_SYMBOL(kernel_thread);
diff --git a/arch/sh/kernel/process_64.c b/arch/sh/kernel/process_64.c
index 210c1cabcb7..4b17fd9ed79 100644
--- a/arch/sh/kernel/process_64.c
+++ b/arch/sh/kernel/process_64.c
@@ -25,12 +25,15 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <trace/sched.h>
#include <asm/syscalls.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
#include <asm/fpu.h>
+DEFINE_TRACE(sched_kthread_create);
+
struct task_struct *last_task_used_math = NULL;
void show_regs(struct pt_regs *regs)
@@ -300,6 +303,7 @@ ATTRIB_NORET void kernel_thread_helper(void *arg, int (*fn)(void *))
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{
+ int pid;
struct pt_regs regs;
memset(&regs, 0, sizeof(regs));
@@ -310,8 +314,12 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
regs.sr = (1 << 30);
/* Ok, create the new process.. */
- return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
+ pid = do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0,
&regs, 0, NULL, NULL);
+
+ trace_sched_kthread_create(fn, pid);
+
+ return pid;
}
EXPORT_SYMBOL(kernel_thread);
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c
index 90a15d29fee..df61c55de26 100644
--- a/arch/sh/kernel/ptrace_32.c
+++ b/arch/sh/kernel/ptrace_32.c
@@ -26,6 +26,7 @@
#include <linux/elf.h>
#include <linux/regset.h>
#include <linux/hw_breakpoint.h>
+#include <trace/syscall.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -37,6 +38,9 @@
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
+DEFINE_TRACE(syscall_entry);
+DEFINE_TRACE(syscall_exit);
+
/*
* This routine will get a word off of the process kernel stack.
*/
@@ -491,6 +495,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
long ret = 0;
+ trace_syscall_entry(regs, regs->regs[3]);
+
secure_computing(regs->regs[0]);
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
@@ -517,6 +523,8 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
{
int step;
+ trace_syscall_exit(regs->regs[0]);
+
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->regs[0]),
regs->regs[0]);
diff --git a/arch/sh/kernel/ptrace_64.c b/arch/sh/kernel/ptrace_64.c
index 4436eacddb1..c893d20483b 100644
--- a/arch/sh/kernel/ptrace_64.c
+++ b/arch/sh/kernel/ptrace_64.c
@@ -31,6 +31,7 @@
#include <linux/tracehook.h>
#include <linux/elf.h>
#include <linux/regset.h>
+#include <trace/syscall.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -43,6 +44,9 @@
#define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h>
+DEFINE_TRACE(syscall_entry);
+DEFINE_TRACE(syscall_exit);
+
/* This mask defines the bits of the SR which the user is not allowed to
change, which are everything except S, Q, M, PR, SZ, FR. */
#define SR_MASK (0xffff8cfd)
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 8c6a350df75..b519b22b575 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -27,6 +27,9 @@
#include <asm/unistd.h>
#include <asm/cacheflush.h>
#include <asm/cachectl.h>
+#include <trace/ipc.h>
+
+DEFINE_TRACE(ipc_call);
asmlinkage int old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
diff --git a/arch/sh/kernel/traps_32.c b/arch/sh/kernel/traps_32.c
index 3484c2f65ab..5abd87752eb 100644
--- a/arch/sh/kernel/traps_32.c
+++ b/arch/sh/kernel/traps_32.c
@@ -27,6 +27,7 @@
#include <linux/sysfs.h>
#include <linux/uaccess.h>
#include <linux/perf_event.h>
+#include <trace/trap.h>
#include <asm/system.h>
#include <asm/alignment.h>
#include <asm/fpu.h>
@@ -47,6 +48,9 @@
#define TRAP_ILLEGAL_SLOT_INST 13
#endif
+DEFINE_TRACE(trap_entry);
+DEFINE_TRACE(trap_exit);
+
static void dump_mem(const char *str, unsigned long bottom, unsigned long top)
{
unsigned long p;
@@ -545,6 +549,8 @@ asmlinkage void do_address_error(struct pt_regs *regs,
error_code = lookup_exception_vector();
#endif
+ trace_trap_entry(regs, error_code >> 5);
+
oldfs = get_fs();
if (user_mode(regs)) {
@@ -589,8 +595,10 @@ fixup:
address);
set_fs(oldfs);
- if (tmp == 0)
+ if (!tmp) {
+ trace_trap_exit();
return; /* sorted */
+ }
uspace_segv:
printk(KERN_NOTICE "Sending SIGBUS to \"%s\" due to unaligned "
"access (PC %lx PR %lx)\n", current->comm, regs->pc,
@@ -623,6 +631,7 @@ uspace_segv:
0, address);
set_fs(oldfs);
}
+ trace_trap_exit();
}
#ifdef CONFIG_SH_DSP
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c
index d4c34d757f0..22695763403 100644
--- a/arch/sh/mm/fault_32.c
+++ b/arch/sh/mm/fault_32.c
@@ -16,11 +16,17 @@
#include <linux/hardirq.h>
#include <linux/kprobes.h>
#include <linux/perf_event.h>
+#include <trace/fault.h>
#include <asm/io_trapped.h>
#include <asm/system.h>
#include <asm/mmu_context.h>
#include <asm/tlbflush.h>
+DEFINE_TRACE(page_fault_entry);
+DEFINE_TRACE(page_fault_exit);
+DEFINE_TRACE(page_fault_nosem_entry);
+DEFINE_TRACE(page_fault_nosem_exit);
+
static inline int notify_page_fault(struct pt_regs *regs, int trap)
{
int ret = 0;
@@ -200,7 +206,14 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
+ trace_page_fault_entry(regs,
+ ({
+ unsigned long trapnr;
+ asm volatile("stc r2_bank,%0": "=r" (trapnr));
+ trapnr;
+ }) >> 5, mm, vma, address, writeaccess);
fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0);
+ trace_page_fault_exit(fault);
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -230,11 +243,18 @@ bad_area:
bad_area_nosemaphore:
if (user_mode(regs)) {
+ trace_page_fault_nosem_entry(regs,
+ ({
+ unsigned long trapnr;
+ asm volatile("stc r2_bank,%0": "=r" (trapnr));
+ trapnr;
+ }) >> 5, address);
info.si_signo = SIGSEGV;
info.si_errno = 0;
info.si_code = si_code;
info.si_addr = (void *) address;
force_sig_info(SIGSEGV, &info, tsk);
+ trace_page_fault_nosem_exit();
return;
}
@@ -324,6 +344,11 @@ handle_tlbmiss(struct pt_regs *regs, unsigned long writeaccess,
pmd_t *pmd;
pte_t *pte;
pte_t entry;
+ int ret;
+ int irqvec;
+
+ irqvec = lookup_exception_vector();
+ trace_page_fault_nosem_entry(regs, irqvec, address);
/*
* We don't take page faults for P1, P2, and parts of P4, these
@@ -333,24 +358,34 @@ handle_tlbmiss(struct pt_regs *regs, unsigned long writeaccess,
if (address >= P3SEG && address < P3_ADDR_MAX) {
pgd = pgd_offset_k(address);
} else {
- if (unlikely(address >= TASK_SIZE || !current->mm))
- return 1;
+ if (unlikely(address >= TASK_SIZE || !current->mm)) {
+ ret = 1;
+ goto out;
+ }
pgd = pgd_offset(current->mm, address);
}
pud = pud_offset(pgd, address);
- if (pud_none_or_clear_bad(pud))
- return 1;
+ if (pud_none_or_clear_bad(pud)) {
+ ret = 1;
+ goto out;
+ }
pmd = pmd_offset(pud, address);
- if (pmd_none_or_clear_bad(pmd))
- return 1;
+ if (pmd_none_or_clear_bad(pmd)) {
+ ret = 1;
+ goto out;
+ }
pte = pte_offset_kernel(pmd, address);
entry = *pte;
- if (unlikely(pte_none(entry) || pte_not_present(entry)))
- return 1;
- if (unlikely(writeaccess && !pte_write(entry)))
- return 1;
+ if (unlikely(pte_none(entry) || pte_not_present(entry))) {
+ ret = 1;
+ goto out;
+ }
+ if (unlikely(writeaccess && !pte_write(entry))) {
+ ret = 1;
+ goto out;
+ }
if (writeaccess)
entry = pte_mkdirty(entry);
@@ -370,5 +405,8 @@ handle_tlbmiss(struct pt_regs *regs, unsigned long writeaccess,
update_mmu_cache(NULL, address, pte);
- return 0;
+ ret = 0;
+out:
+ trace_page_fault_nosem_exit();
+ return ret;
}