You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
x86/kprobes: Use int3 instead of debug trap for single-step
[ Upstream commit6256e668b7] Use int3 instead of debug trap exception for single-stepping the probed instructions. Some instructions which change the ip registers or modify IF flags are emulated because those are not able to be single-stepped by int3 or may allow the interrupt while single-stepping. This actually changes the kprobes behavior. - kprobes can not probe following instructions; int3, iret, far jmp/call which get absolute address as immediate, indirect far jmp/call, indirect near jmp/call with addressing by memory (register-based indirect jmp/call are OK), and vmcall/vmlaunch/vmresume/vmxoff. - If the kprobe post_handler doesn't set before registering, it may not be called in some case even if you set it afterwards. (IOW, kprobe booster is enabled at registration, user can not change it) But both are rare issue, unsupported instructions will not be used in the kernel (or rarely used), and post_handlers are rarely used (I don't see it except for the test code). Suggested-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lkml.kernel.org/r/161469874601.49483.11985325887166921076.stgit@devnote2 [Huafei: Fix trivial conflict in arch/x86/kernel/kprobes/core.c due to the previously backported commit6dd3b8c9f5] Signed-off-by: Li Huafei <lihuafei1@huawei.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
2c57553a77
commit
ba7d1dae9f
@@ -65,10 +65,22 @@ struct arch_specific_insn {
|
||||
* a post_handler).
|
||||
*/
|
||||
unsigned boostable:1;
|
||||
unsigned if_modifier:1;
|
||||
unsigned is_call:1;
|
||||
unsigned is_pushf:1;
|
||||
unsigned is_abs_ip:1;
|
||||
unsigned char size; /* The size of insn */
|
||||
union {
|
||||
unsigned char opcode;
|
||||
struct {
|
||||
unsigned char type;
|
||||
} jcc;
|
||||
struct {
|
||||
unsigned char type;
|
||||
unsigned char asize;
|
||||
} loop;
|
||||
struct {
|
||||
unsigned char reg;
|
||||
} indirect;
|
||||
};
|
||||
s32 rel32; /* relative offset must be s32, s16, or s8 */
|
||||
void (*emulate_op)(struct kprobe *p, struct pt_regs *regs);
|
||||
/* Number of bytes of text poked */
|
||||
int tp_len;
|
||||
};
|
||||
@@ -107,7 +119,6 @@ extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
|
||||
extern int kprobe_exceptions_notify(struct notifier_block *self,
|
||||
unsigned long val, void *data);
|
||||
extern int kprobe_int3_handler(struct pt_regs *regs);
|
||||
extern int kprobe_debug_handler(struct pt_regs *regs);
|
||||
|
||||
#else
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -917,9 +917,6 @@ static __always_inline void exc_debug_kernel(struct pt_regs *regs,
|
||||
if ((dr6 & DR_STEP) && is_sysenter_singlestep(regs))
|
||||
dr6 &= ~DR_STEP;
|
||||
|
||||
if (kprobe_debug_handler(regs))
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* The kernel doesn't use INT1
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user