Walk the instructions before the target with for_each_addr_kprobe() and pass each matching kprobe to recover_probed_instruction(). Reuse the iterator’s kprobe for the target instruction as well. Signed-off-by: Jiri Olsa --- arch/x86/kernel/kprobes/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 6ad8b89a9ba1..4d63826f6c04 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -287,6 +287,8 @@ static inline bool is_exception_insn(struct insn *insn) static bool can_probe(unsigned long paddr) { unsigned long addr, __addr, offset = 0; + struct kprobe_iter iter; + struct kprobe *kp; struct insn insn; kprobe_opcode_t buf[MAX_INSN_SIZE]; @@ -295,7 +297,9 @@ static bool can_probe(unsigned long paddr) /* Decode instructions */ addr = paddr - offset; - while (addr < paddr) { + for_each_addr_kprobe(iter, kp, addr, paddr) { + if (addr == paddr) + break; /* * Check if the instruction has been modified by another * kprobe, in which case we replace the breakpoint by the @@ -304,7 +308,7 @@ static bool can_probe(unsigned long paddr) * relative-jump. Since the relative-jump itself is * normally used, we just go through if there is no kprobe. */ - __addr = recover_probed_instruction(buf, addr, NULL); + __addr = recover_probed_instruction(buf, addr, &kp); if (!__addr) return false; @@ -327,7 +331,7 @@ static bool can_probe(unsigned long paddr) if (addr != paddr) return false; - __addr = recover_probed_instruction(buf, addr, NULL); + __addr = recover_probed_instruction(buf, addr, &kp); if (!__addr) return false; -- 2.43.0