Skip to content

Commit 6818787

Browse files
dvlasenkIngo Molnar
authored andcommitted
uprobes/x86: Fix RIP-relative handling of EVEX-encoded instructions
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 Cc: <stable@vger.kernel.org> # v4.1+ Fixes: 8a764a8 ("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>
1 parent db4a835 commit 6818787

File tree

1 file changed

+11
-11
lines changed

1 file changed

+11
-11
lines changed

arch/x86/kernel/uprobes.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -357,20 +357,22 @@ static void riprel_analyze(struct arch_uprobe *auprobe, struct insn *insn)
357357
*cursor &= 0xfe;
358358
}
359359
/*
360-
* Similar treatment for VEX3 prefix.
361-
* TODO: add XOP/EVEX treatment when insn decoder supports them
360+
* Similar treatment for VEX3/EVEX prefix.
361+
* TODO: add XOP treatment when insn decoder supports them
362362
*/
363-
if (insn->vex_prefix.nbytes == 3) {
363+
if (insn->vex_prefix.nbytes >= 3) {
364364
/*
365365
* vex2: c5 rvvvvLpp (has no b bit)
366366
* vex3/xop: c4/8f rxbmmmmm wvvvvLpp
367367
* evex: 62 rxbR00mm wvvvv1pp zllBVaaa
368-
* (evex will need setting of both b and x since
369-
* in non-sib encoding evex.x is 4th bit of MODRM.rm)
370-
* Setting VEX3.b (setting because it has inverted meaning):
368+
* Setting VEX3.b (setting because it has inverted meaning).
369+
* Setting EVEX.x since (in non-SIB encoding) EVEX.x
370+
* is the 4th bit of MODRM.rm, and needs the same treatment.
371+
* For VEX3-encoded insns, VEX3.x value has no effect in
372+
* non-SIB encoding, the change is superfluous but harmless.
371373
*/
372374
cursor = auprobe->insn + insn_offset_vex_prefix(insn) + 1;
373-
*cursor |= 0x20;
375+
*cursor |= 0x60;
374376
}
375377

376378
/*
@@ -415,12 +417,10 @@ static void riprel_analyze(struct arch_uprobe *auprobe, struct insn *insn)
415417

416418
reg = MODRM_REG(insn); /* Fetch modrm.reg */
417419
reg2 = 0xff; /* Fetch vex.vvvv */
418-
if (insn->vex_prefix.nbytes == 2)
419-
reg2 = insn->vex_prefix.bytes[1];
420-
else if (insn->vex_prefix.nbytes == 3)
420+
if (insn->vex_prefix.nbytes)
421421
reg2 = insn->vex_prefix.bytes[2];
422422
/*
423-
* TODO: add XOP, EXEV vvvv reading.
423+
* TODO: add XOP vvvv reading.
424424
*
425425
* vex.vvvv field is in bits 6-3, bits are inverted.
426426
* But in 32-bit mode, high-order bit may be ignored.

0 commit comments

Comments
 (0)