From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753408AbdDLHjV (ORCPT ); Wed, 12 Apr 2017 03:39:21 -0400 Received: from terminus.zytor.com ([65.50.211.136]:52143 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753279AbdDLHjS (ORCPT ); Wed, 12 Apr 2017 03:39:18 -0400 Date: Wed, 12 Apr 2017 00:33:33 -0700 From: tip-bot for Masami Hiramatsu Message-ID: Cc: bp@alien8.de, davem@davemloft.net, ananth@linux.vnet.ibm.com, dvlasenk@redhat.com, peterz@infradead.org, brgerst@gmail.com, mhiramat@kernel.org, torvalds@linux-foundation.org, anil.s.keshavamurthy@intel.com, aryabinin@virtuozzo.com, tglx@linutronix.de, xiaolong.ye@intel.com, linux-kernel@vger.kernel.org, jpoimboe@redhat.com, hpa@zytor.com, mingo@kernel.org Reply-To: jpoimboe@redhat.com, linux-kernel@vger.kernel.org, mingo@kernel.org, hpa@zytor.com, tglx@linutronix.de, anil.s.keshavamurthy@intel.com, aryabinin@virtuozzo.com, torvalds@linux-foundation.org, brgerst@gmail.com, mhiramat@kernel.org, xiaolong.ye@intel.com, ananth@linux.vnet.ibm.com, peterz@infradead.org, dvlasenk@redhat.com, davem@davemloft.net, bp@alien8.de In-Reply-To: <149076361560.22469.1610155860343077495.stgit@devbox> References: <149076361560.22469.1610155860343077495.stgit@devbox> To: linux-tip-commits@vger.kernel.org Subject: [tip:perf/core] kprobes/x86: Do not modify singlestep buffer while resuming Git-Commit-ID: 804dec5bda9b4fcdab5f67fe61db4a0498af5221 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: 804dec5bda9b4fcdab5f67fe61db4a0498af5221 Gitweb: http://git.kernel.org/tip/804dec5bda9b4fcdab5f67fe61db4a0498af5221 Author: Masami Hiramatsu AuthorDate: Wed, 29 Mar 2017 14:00:25 +0900 Committer: Ingo Molnar CommitDate: Wed, 12 Apr 2017 09:23:45 +0200 kprobes/x86: Do not modify singlestep buffer while resuming Do not modify singlestep execution buffer (kprobe.ainsn.insn) while resuming from single-stepping, instead, modifies the buffer to add a jump back instruction at preparing buffer. Signed-off-by: Masami Hiramatsu Cc: Ananth N Mavinakayanahalli Cc: Andrey Ryabinin Cc: Anil S Keshavamurthy Cc: Borislav Petkov Cc: Brian Gerst Cc: David S . Miller Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Josh Poimboeuf Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Ye Xiaolong Link: http://lkml.kernel.org/r/149076361560.22469.1610155860343077495.stgit@devbox Signed-off-by: Ingo Molnar --- arch/x86/kernel/kprobes/core.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index 6327f95..a654054 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -399,23 +399,36 @@ int __copy_instruction(u8 *dest, u8 *src) return length; } +/* Prepare reljump right after instruction to boost */ +static void prepare_boost(struct kprobe *p, int length) +{ + if (can_boost(p->ainsn.insn, p->addr) && + MAX_INSN_SIZE - length >= RELATIVEJUMP_SIZE) { + /* + * These instructions can be executed directly if it + * jumps back to correct address. + */ + synthesize_reljump(p->ainsn.insn + length, p->addr + length); + p->ainsn.boostable = 1; + } else { + p->ainsn.boostable = -1; + } +} + static int arch_copy_kprobe(struct kprobe *p) { - int ret; + int len; /* Copy an instruction with recovering if other optprobe modifies it.*/ - ret = __copy_instruction(p->ainsn.insn, p->addr); - if (!ret) + len = __copy_instruction(p->ainsn.insn, p->addr); + if (!len) return -EINVAL; /* * __copy_instruction can modify the displacement of the instruction, * but it doesn't affect boostable check. */ - if (can_boost(p->ainsn.insn, p->addr)) - p->ainsn.boostable = 0; - else - p->ainsn.boostable = -1; + prepare_boost(p, len); /* Check whether the instruction modifies Interrupt Flag or not */ p->ainsn.if_modifier = is_IF_modifier(p->ainsn.insn); @@ -878,21 +891,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs, break; } - if (p->ainsn.boostable == 0) { - if ((regs->ip > copy_ip) && - (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) { - /* - * These instructions can be executed directly if it - * jumps back to correct address. - */ - synthesize_reljump((void *)regs->ip, - (void *)orig_ip + (regs->ip - copy_ip)); - p->ainsn.boostable = 1; - } else { - p->ainsn.boostable = -1; - } - } - regs->ip += orig_ip - copy_ip; no_change: