Commit 33e53ae1 authored by Guo Ren's avatar Guo Ren
Browse files

csky: Add kprobes supported



This patch enable kprobes, kretprobes, ftrace interface. It utilized
software breakpoint and single step debug exceptions, instructions
simulation on csky.

We use USR_BKPT replace origin instruction, and the kprobe handler
prepares an excutable memory slot for out-of-line execution with a
copy of the original instruction being probed. Most of instructions
could be executed by single-step, but some instructions need origin
pc value to execute and we need software simulate these instructions.

Signed-off-by: default avatarGuo Ren <guoren@linux.alibaba.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Steven Rostedt (VMware) <rostedt@goodmis.org>
parent 000591f1
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ config CSKY
	select HAVE_KERNEL_GZIP
	select HAVE_KERNEL_LZO
	select HAVE_KERNEL_LZMA
	select HAVE_KPROBES if !CPU_CK610
	select HAVE_KPROBES_ON_FTRACE if !CPU_CK610
	select HAVE_KRETPROBES if !CPU_CK610
	select HAVE_PERF_EVENTS
	select HAVE_PERF_REGS
	select HAVE_PERF_USER_STACK_DUMP
+0 −1
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ generic-y += irq_regs.h
generic-y += irq_work.h
generic-y += kdebug.h
generic-y += kmap_types.h
generic-y += kprobes.h
generic-y += kvm_para.h
generic-y += linkage.h
generic-y += local.h
+48 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef __ASM_CSKY_KPROBES_H
#define __ASM_CSKY_KPROBES_H

#include <asm-generic/kprobes.h>

#ifdef CONFIG_KPROBES
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/percpu.h>

#define __ARCH_WANT_KPROBES_INSN_SLOT
#define MAX_INSN_SIZE			1

#define flush_insn_slot(p)		do { } while (0)
#define kretprobe_blacklist_size	0

#include <asm/probes.h>

struct prev_kprobe {
	struct kprobe *kp;
	unsigned int status;
};

/* Single step context for kprobe */
struct kprobe_step_ctx {
	unsigned long ss_pending;
	unsigned long match_addr;
};

/* per-cpu kprobe control block */
struct kprobe_ctlblk {
	unsigned int kprobe_status;
	unsigned long saved_sr;
	struct prev_kprobe prev_kprobe;
	struct kprobe_step_ctx ss_ctx;
};

void arch_remove_kprobe(struct kprobe *p);
int kprobe_fault_handler(struct pt_regs *regs, unsigned int trapnr);
int kprobe_breakpoint_handler(struct pt_regs *regs);
int kprobe_single_step_handler(struct pt_regs *regs);
void kretprobe_trampoline(void);
void __kprobes *trampoline_probe_handler(struct pt_regs *regs);

#endif /* CONFIG_KPROBES */
#endif /* __ASM_CSKY_KPROBES_H */
+24 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef __ASM_CSKY_PROBES_H
#define __ASM_CSKY_PROBES_H

typedef u32 probe_opcode_t;
typedef void (probes_handler_t) (u32 opcode, long addr, struct pt_regs *);

/* architecture specific copy of original instruction */
struct arch_probe_insn {
	probe_opcode_t *insn;
	probes_handler_t *handler;
	/* restore address after simulation */
	unsigned long restore;
};

#ifdef CONFIG_KPROBES
typedef u32 kprobe_opcode_t;
struct arch_specific_insn {
	struct arch_probe_insn api;
};
#endif

#endif /* __ASM_CSKY_PROBES_H */
+2 −0
Original line number Diff line number Diff line
@@ -13,6 +13,8 @@

#define PS_S	0x80000000 /* Supervisor Mode */

#define USR_BKPT	0x1464

#define arch_has_single_step() (1)
#define current_pt_regs() \
({ (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1; })
Loading