FAILED: patch "[PATCH] x86_64: Allow breakpoints to emulate call instructions" failed to apply to 4.9-stable tree
Subsystems (3)
gregkh at linuxfoundation.org (gregkh at linuxfoundation.org)
The patch below does not apply to the 4.9-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <stable at vger.kernel.org>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
4b33dadf37666c0860b88f9e52a16d07bf6d0b03Mon Sep 17 00:00:00 2001
From: Peter Zijlstra <[email protected]>
Date: Wed, 1 May 2019 15:11:17 +0200
Subject: [PATCH] x86_64: Allow breakpoints to emulate call instructions
In order to allow breakpoints to emulate call instructions, they need to push the return address onto the stack. The x86_64 int3 handler adds a small gap to allow the stack to grow some. Use this gap to add the return address to be able to emulate a call instruction at the breakpoint location.
These helper functions are added:
int3_emulate_jmp(): changes the location of the regs->ip to return there.
(The next two are only for x86_64)
int3_emulate_push(): to push the address onto the gap in the stack int3_emulate_call(): push the return address and change regs->ip
arch/x86/include/asm/text-patching.h +28 -0
@@ -39,4 +39,32 @@ extern int poke_int3_handler(struct pt_regs *regs);extern void *text_poke_bp (void *addr,const void *opcode,size_t len,void *handler);extern int after_bootmem; +static inline void int3_emulate_jmp (struct pt_regs *regs,unsigned long ip) +{ + regs->ip = ip; +} + +#define INT3_INSN_SIZE 1 +#define CALL_INSN_SIZE 5 + +#ifdef CONFIG_X86_64 +static inline void int3_emulate_push (struct pt_regs *regs,unsigned long val) +{ +/* +* The int3 handler in entry_64.S adds a gap between the +* stack where the break point happened, and the saving of +* pt_regs. We can extend the original stack because of +* this gap. See the idtentry macro's create_gap option. +*/ + regs->sp -=sizeof (unsigned long ); + *(unsigned long *)regs->sp = val; +} + +static inline void int3_emulate_call (struct pt_regs *regs,unsigned long func) +{ +int3_emulate_push (regs, regs->ip -INT3_INSN_SIZE +CALL_INSN_SIZE ); +int3_emulate_jmp (regs, func); +} +#endif +#endif /* _ASM_X86_TEXT_PATCHING_H */