From: Oleg Nesterov <oleg@redhat.com>
To: Denys Vlasenko <dvlasenk@redhat.com>
Cc: linux-kernel@vger.kernel.org, Jim Keniston <jkenisto@us.ibm.com>,
Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
Ingo Molnar <mingo@kernel.org>
Subject: Re: [PATCH] uprobes: use BX register for rip-relative fixups, not AX
Date: Mon, 28 Apr 2014 19:34:32 +0200 [thread overview]
Message-ID: <20140428173432.GA27363@redhat.com> (raw)
In-Reply-To: <1398704774-25173-2-git-send-email-dvlasenk@redhat.com>
Thanks...
Again, the change in riprel_analyze() needs the review from someone
who understands the instruction decoding/encoding.
On 04/28, Denys Vlasenko wrote:
>
> Otherwise, instructions such as cmpxchg and div will be mishandled.
It seems that you are right. But it would be really great if you also
provide the test-case which proves the fix ;)
> Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
> CC: Jim Keniston <jkenisto@us.ibm.com>
> CC: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> CC: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
> CC: Ingo Molnar <mingo@kernel.org>
> CC: Oleg Nesterov <oleg@redhat.com>
> ---
> arch/x86/kernel/uprobes.c | 57 ++++++++++++++++++++++++++++++-----------------
> 1 file changed, 37 insertions(+), 20 deletions(-)
>
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index ae6df8e..bc70182 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -41,7 +41,7 @@
> /* Instruction will modify TF, don't change it */
> #define UPROBE_FIX_SETF 0x04
>
> -#define UPROBE_FIX_RIP_AX 0x08
> +#define UPROBE_FIX_RIP_BX 0x08
> #define UPROBE_FIX_RIP_CX 0x10
>
> #define UPROBE_TRAP_NR UINT_MAX
> @@ -282,7 +282,7 @@ static void riprel_analyze(struct arch_uprobe *auprobe, struct insn *insn)
> /*
> * insn_rip_relative() would have decoded rex_prefix, modrm.
> * Clear REX.b bit (extension of MODRM.rm field):
> - * we want to encode rax/rcx, not r8/r9.
> + * we want to encode rbx/rcx, not r11/r9.
> */
> if (insn->rex_prefix.nbytes) {
> cursor = auprobe->insn + insn_offset_rex_prefix(insn);
> @@ -296,41 +296,58 @@ static void riprel_analyze(struct arch_uprobe *auprobe, struct insn *insn)
> */
> cursor = auprobe->insn + insn_offset_modrm(insn);
> /*
> - * Convert from rip-relative addressing to register-relative addressing
> - * via a scratch register.
> + * Convert from rip-relative addressing
> + * to register-relative addressing via a scratch register.
> */
> reg = MODRM_REG(insn);
> - if (reg == 0) {
> + if (reg == 3) {
> /*
> - * The register operand (if any) is either the A register
> - * (%rax, %eax, etc.) or (if the 0x4 bit is set in the
> - * REX prefix) %r8. In any case, we know the C register
> + * The register operand (if any) is either the B register
> + * (%rbx, %ebx, etc.) or (if the 0x4 bit is set in the
> + * REX prefix) %r11. In any case, we know the C register
> * is NOT the register operand, so we use %rcx (register
> * #1) for the scratch register.
> */
> auprobe->def.fixups |= UPROBE_FIX_RIP_CX;
> /*
> - * Change modrm from "00 000 101" to "10 000 001". Example:
> - * 89 05 disp32 mov %eax,disp32(%rip) becomes
> - * 89 81 disp32 mov %eax,disp32(%rcx)
> + * Change modrm from "00 011 101" to "10 011 001". Example:
> + * 89 1d disp32 mov %ebx,disp32(%rip) becomes
> + * 89 99 disp32 mov %ebx,disp32(%rcx)
> */
> - *cursor = 0x81;
> + *cursor = 0x99;
> } else {
> - /* Use %rax (register #0) for the scratch register. */
> - auprobe->def.fixups |= UPROBE_FIX_RIP_AX;
> + /* Use %rbx (register #3) for the scratch register. */
> + auprobe->def.fixups |= UPROBE_FIX_RIP_BX;
> /*
> - * Change modrm from "00 reg 101" to "10 reg 000". Example:
> + * Change modrm from "00 reg 101" to "10 reg 011". Example:
> * 89 1d disp32 mov %edx,disp32(%rip) becomes
> - * 89 98 disp32 mov %edx,disp32(%rax)
> + * 89 9b disp32 mov %edx,disp32(%rbx)
> */
> - *cursor = (reg << 3) | 0x80;
> + *cursor = (reg << 3) | 0x83;
> }
> + /*
> + * Note: we can't use rax or rdx registers as scratch!
> + * There are 3-operand insns which use rax or rdx:rax
> + * as an implicit operand, _and_ they use modrm byte
> + * whose reg field indicates third register or opcode extension.
> + * In particular, these insns:
> + * f7/6 r/m div r/m
> + * 0f b1 r/m cmpxchg r/m,reg
> + * 0f c7/1 mem cmpxchg{8b,16b} mem
> + * Looking at "reg" field won't allow to detect that rax or rdx
> + * are in use.
> + *
> + * FIXME: handle vex-encoded 3-operand insns too:
> + * c4 e2 60 f7 0d disp32 bextr %ebx,disp32(%rip),%ecx
> + * %ebx is encoded in the vex.vvvv field, which we don't check
> + * (in this example, it's in byte 60 bits 6..3).
> + */
> }
>
> static inline unsigned long *
> scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs)
> {
> - return (auprobe->def.fixups & UPROBE_FIX_RIP_AX) ? ®s->ax : ®s->cx;
> + return (auprobe->def.fixups & UPROBE_FIX_RIP_BX) ? ®s->bx : ®s->cx;
> }
>
> /*
> @@ -339,7 +356,7 @@ scratch_reg(struct arch_uprobe *auprobe, struct pt_regs *regs)
> */
> static void riprel_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
> {
> - if (auprobe->def.fixups & (UPROBE_FIX_RIP_AX | UPROBE_FIX_RIP_CX)) {
> + if (auprobe->def.fixups & (UPROBE_FIX_RIP_BX | UPROBE_FIX_RIP_CX)) {
> struct uprobe_task *utask = current->utask;
> unsigned long *sr = scratch_reg(auprobe, regs);
>
> @@ -350,7 +367,7 @@ static void riprel_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
>
> static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
> {
> - if (auprobe->def.fixups & (UPROBE_FIX_RIP_AX | UPROBE_FIX_RIP_CX)) {
> + if (auprobe->def.fixups & (UPROBE_FIX_RIP_BX | UPROBE_FIX_RIP_CX)) {
> struct uprobe_task *utask = current->utask;
> unsigned long *sr = scratch_reg(auprobe, regs);
>
> --
> 1.8.1.4
>
next parent reply other threads:[~2014-04-28 20:29 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1398704774-25173-1-git-send-email-dvlasenk@redhat.com>
[not found] ` <1398704774-25173-2-git-send-email-dvlasenk@redhat.com>
2014-04-28 17:34 ` Oleg Nesterov [this message]
2014-04-28 19:06 ` [PATCH] uprobes: use BX register for rip-relative fixups, not AX Denys Vlasenko
2014-04-28 19:23 ` Oleg Nesterov
2014-04-29 10:16 ` Denys Vlasenko
2014-04-28 17:44 ` Denys Vlasenko
2014-05-01 0:29 ` Jim Keniston
2014-04-29 19:09 ` [PATCH v3] uprobes: simplify rip-relative handling Oleg Nesterov
2014-05-01 0:17 ` Jim Keniston
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140428173432.GA27363@redhat.com \
--to=oleg@redhat.com \
--cc=dvlasenk@redhat.com \
--cc=jkenisto@us.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=masami.hiramatsu.pt@hitachi.com \
--cc=mingo@kernel.org \
--cc=srikar@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.