Commit d39f5450 authored by Chris Smith's avatar Chris Smith Committed by Paul Mundt

sh: Add kprobes support.

Initial support for kprobes/kretprobes for 32-bit SH platforms.

[ General cleanup and some rework for the kretprobe hash lock. -- PFM ]
Signed-off-by: default avatarChris Smith <chris.smith@st.com>
Signed-off-by: default avatarPaul Mundt <lethal@linux-sh.org>
parent b6c20e42
...@@ -20,6 +20,8 @@ config SUPERH ...@@ -20,6 +20,8 @@ config SUPERH
config SUPERH32 config SUPERH32
def_bool !SUPERH64 def_bool !SUPERH64
select HAVE_KPROBES
select HAVE_KRETPROBES
config SUPERH64 config SUPERH64
def_bool y if CPU_SH5 def_bool y if CPU_SH5
......
#ifndef __ASM_SH_KPROBES_H
#define __ASM_SH_KPROBES_H
#ifdef CONFIG_KPROBES
#include <linux/types.h>
#include <linux/ptrace.h>
struct pt_regs;
typedef u16 kprobe_opcode_t;
#define BREAKPOINT_INSTRUCTION 0xc3ff
#define MAX_INSN_SIZE 16
#define MAX_STACK_SIZE 64
#define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \
(((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) \
? (MAX_STACK_SIZE) \
: (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
#define regs_return_value(regs) ((regs)->regs[0])
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
struct kprobe;
void arch_remove_kprobe(struct kprobe *);
void kretprobe_trampoline(void);
void jprobe_return_end(void);
/* Architecture specific copy of original instruction*/
struct arch_specific_insn {
/* copy of the original instruction */
kprobe_opcode_t insn[MAX_INSN_SIZE];
};
struct prev_kprobe {
struct kprobe *kp;
unsigned long status;
};
/* per-cpu kprobe control block */
struct kprobe_ctlblk {
unsigned long kprobe_status;
unsigned long jprobe_saved_r15;
struct pt_regs jprobe_saved_regs;
kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE];
struct prev_kprobe prev_kprobe;
};
extern int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
extern int kprobe_handle_illslot(unsigned long pc);
#else
#define kprobe_handle_illslot(pc) (-1)
#endif /* CONFIG_KPROBES */
#endif /* __ASM_SH_KPROBES_H */
...@@ -23,5 +23,6 @@ obj-$(CONFIG_PM) += pm.o ...@@ -23,5 +23,6 @@ obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-$(CONFIG_ELF_CORE) += dump_task.o obj-$(CONFIG_ELF_CORE) += dump_task.o
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
obj-$(CONFIG_KPROBES) += kprobes.o
EXTRA_CFLAGS += -Werror EXTRA_CFLAGS += -Werror
This diff is collapsed.
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/fpu.h> #include <asm/fpu.h>
#include <asm/kprobes.h>
#ifdef CONFIG_SH_KGDB #ifdef CONFIG_SH_KGDB
#include <asm/kgdb.h> #include <asm/kgdb.h>
...@@ -743,6 +744,10 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5, ...@@ -743,6 +744,10 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
struct pt_regs *regs = RELOC_HIDE(&__regs, 0); struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
unsigned long error_code; unsigned long error_code;
struct task_struct *tsk = current; struct task_struct *tsk = current;
if (kprobe_handle_illslot(regs->pc) == 0)
return;
#ifdef CONFIG_SH_FPU_EMU #ifdef CONFIG_SH_FPU_EMU
unsigned short inst = 0; unsigned short inst = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment