You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
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: Chris Smith <chris.smith@st.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
@@ -20,6 +20,8 @@ config SUPERH
|
||||
|
||||
config SUPERH32
|
||||
def_bool !SUPERH64
|
||||
select HAVE_KPROBES
|
||||
select HAVE_KRETPROBES
|
||||
|
||||
config SUPERH64
|
||||
def_bool y if CPU_SH5
|
||||
|
||||
59
arch/sh/include/asm/kprobes.h
Normal file
59
arch/sh/include/asm/kprobes.h
Normal file
@@ -0,0 +1,59 @@
|
||||
#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
|
||||
obj-$(CONFIG_STACKTRACE) += stacktrace.o
|
||||
obj-$(CONFIG_ELF_CORE) += dump_task.o
|
||||
obj-$(CONFIG_IO_TRAPPED) += io_trapped.o
|
||||
obj-$(CONFIG_KPROBES) += kprobes.o
|
||||
|
||||
EXTRA_CFLAGS += -Werror
|
||||
|
||||
568
arch/sh/kernel/kprobes.c
Normal file
568
arch/sh/kernel/kprobes.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,7 @@
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/kprobes.h>
|
||||
|
||||
#ifdef CONFIG_SH_KGDB
|
||||
#include <asm/kgdb.h>
|
||||
@@ -743,6 +744,10 @@ asmlinkage void do_illegal_slot_inst(unsigned long r4, unsigned long r5,
|
||||
struct pt_regs *regs = RELOC_HIDE(&__regs, 0);
|
||||
unsigned long error_code;
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
if (kprobe_handle_illslot(regs->pc) == 0)
|
||||
return;
|
||||
|
||||
#ifdef CONFIG_SH_FPU_EMU
|
||||
unsigned short inst = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user