| From 68187872c76a96ed4db7bfb064272591f02e208b Mon Sep 17 00:00:00 2001 |
| From: Denys Vlasenko <dvlasenk@redhat.com> |
| Date: Thu, 11 Aug 2016 17:45:21 +0200 |
| Subject: uprobes/x86: Fix RIP-relative handling of EVEX-encoded instructions |
| |
| From: Denys Vlasenko <dvlasenk@redhat.com> |
| |
| commit 68187872c76a96ed4db7bfb064272591f02e208b upstream. |
| |
| Since instruction decoder now supports EVEX-encoded instructions, two fixes |
| are needed to correctly handle them in uprobes. |
| |
| Extended bits for MODRM.rm field need to be sanitized just like we do it |
| for VEX3, to avoid encoding wrong register for register-relative access. |
| |
| EVEX has _two_ extended bits: b and x. Theoretically, EVEX.x should be |
| ignored by the CPU (since GPRs go only up to 15, not 31), but let's be |
| paranoid here: proper encoding for register-relative access |
| should have EVEX.x = 1. |
| |
| Secondly, we should fetch vex.vvvv for EVEX too. |
| This is now super easy because instruction decoder populates |
| vex_prefix.bytes[2] for all flavors of (e)vex encodings, even for VEX2. |
| |
| Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com> |
| Acked-by: Masami Hiramatsu <mhiramat@kernel.org> |
| Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com> |
| Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> |
| Cc: Andy Lutomirski <luto@kernel.org> |
| Cc: Arnaldo Carvalho de Melo <acme@redhat.com> |
| Cc: Borislav Petkov <bp@alien8.de> |
| Cc: Brian Gerst <brgerst@gmail.com> |
| Cc: H. Peter Anvin <hpa@zytor.com> |
| Cc: Jim Keniston <jkenisto@us.ibm.com> |
| Cc: Jiri Olsa <jolsa@redhat.com> |
| Cc: Josh Poimboeuf <jpoimboe@redhat.com> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org> |
| Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> |
| Cc: Oleg Nesterov <oleg@redhat.com> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Cc: Stephane Eranian <eranian@google.com> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Vince Weaver <vincent.weaver@maine.edu> |
| Cc: linux-kernel@vger.kernel.org |
| Fixes: 8a764a875fe3 ("x86/asm/decoder: Create artificial 3rd byte for 2-byte VEX") |
| Link: http://lkml.kernel.org/r/20160811154521.20469-1-dvlasenk@redhat.com |
| Signed-off-by: Ingo Molnar <mingo@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kernel/uprobes.c | 22 +++++++++++----------- |
| 1 file changed, 11 insertions(+), 11 deletions(-) |
| |
| --- a/arch/x86/kernel/uprobes.c |
| +++ b/arch/x86/kernel/uprobes.c |
| @@ -357,20 +357,22 @@ static void riprel_analyze(struct arch_u |
| *cursor &= 0xfe; |
| } |
| /* |
| - * Similar treatment for VEX3 prefix. |
| - * TODO: add XOP/EVEX treatment when insn decoder supports them |
| + * Similar treatment for VEX3/EVEX prefix. |
| + * TODO: add XOP treatment when insn decoder supports them |
| */ |
| - if (insn->vex_prefix.nbytes == 3) { |
| + if (insn->vex_prefix.nbytes >= 3) { |
| /* |
| * vex2: c5 rvvvvLpp (has no b bit) |
| * vex3/xop: c4/8f rxbmmmmm wvvvvLpp |
| * evex: 62 rxbR00mm wvvvv1pp zllBVaaa |
| - * (evex will need setting of both b and x since |
| - * in non-sib encoding evex.x is 4th bit of MODRM.rm) |
| - * Setting VEX3.b (setting because it has inverted meaning): |
| + * Setting VEX3.b (setting because it has inverted meaning). |
| + * Setting EVEX.x since (in non-SIB encoding) EVEX.x |
| + * is the 4th bit of MODRM.rm, and needs the same treatment. |
| + * For VEX3-encoded insns, VEX3.x value has no effect in |
| + * non-SIB encoding, the change is superfluous but harmless. |
| */ |
| cursor = auprobe->insn + insn_offset_vex_prefix(insn) + 1; |
| - *cursor |= 0x20; |
| + *cursor |= 0x60; |
| } |
| |
| /* |
| @@ -415,12 +417,10 @@ static void riprel_analyze(struct arch_u |
| |
| reg = MODRM_REG(insn); /* Fetch modrm.reg */ |
| reg2 = 0xff; /* Fetch vex.vvvv */ |
| - if (insn->vex_prefix.nbytes == 2) |
| - reg2 = insn->vex_prefix.bytes[1]; |
| - else if (insn->vex_prefix.nbytes == 3) |
| + if (insn->vex_prefix.nbytes) |
| reg2 = insn->vex_prefix.bytes[2]; |
| /* |
| - * TODO: add XOP, EXEV vvvv reading. |
| + * TODO: add XOP vvvv reading. |
| * |
| * vex.vvvv field is in bits 6-3, bits are inverted. |
| * But in 32-bit mode, high-order bit may be ignored. |