On Fri, 2014-05-02 at 17:04 +0200, Denys Vlasenko wrote:
> Before this patch, instructions such as div, mul,
> shifts with count in CL, cmpxchg are mishandled.

I just noticed that this sounds rather worse than it is.  It would be
more precise to say, "Before this patch, the rip-relative addressing
mode in instructions such as ... is mishandled."

...
> 
> Signed-off-by: Denys Vlasenko <dvlas...@redhat.com>
> CC: Jim Keniston <jkeni...@us.ibm.com>
> CC: Masami Hiramatsu <masami.hiramatsu...@hitachi.com>
> CC: Srikar Dronamraju <sri...@linux.vnet.ibm.com>
> CC: Ingo Molnar <mi...@kernel.org>
> CC: Oleg Nesterov <o...@redhat.com>
> ---
>  arch/x86/kernel/uprobes.c | 179 
> +++++++++++++++++++++++++++++++++-------------
>  1 file changed, 128 insertions(+), 51 deletions(-)
> 
> diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
> index dbbf6cd..5b387b7 100644
> --- a/arch/x86/kernel/uprobes.c
> +++ b/arch/x86/kernel/uprobes.c
> @@ -41,8 +41,12 @@
>  /* Instruction will modify TF, don't change it */
>  #define UPROBE_FIX_SETF              0x04
> 
> -#define UPROBE_FIX_RIP_AX    0x08
> -#define UPROBE_FIX_RIP_CX    0x10
> +#define UPROBE_FIX_RIP_SI    0x08
> +#define UPROBE_FIX_RIP_DI    0x10
> +#define UPROBE_FIX_RIP_BX    0x20
> +#define UPROBE_FIX_RIP_MASK  (UPROBE_FIX_RIP_SI \
> +                             | UPROBE_FIX_RIP_DI \
> +                             | UPROBE_FIX_RIP_BX)

Yes.

...
> +     /* Fetch vex.vvvv */
> +     reg2 = 0xff;
> +     if (insn->vex_prefix.nbytes == 2) {
> +             reg2 = insn->vex_prefix.bytes[1];
> +     }
> +     if (insn->vex_prefix.nbytes == 3) {
> +             reg2 = insn->vex_prefix.bytes[2];
> +     }
> +     /* TODO: add XOP, EXEV vvvv reading */
> +     /*
> +      * vex.vvvv field is in bits 6-3, bits are inverted.
> +      * But in 32-bit mode, high-order bit may be ignored.
> +      * Therefore, let's consider only 3 low-order bits.
> +      */
> +     reg2 = ((reg2 >> 3) & 0x7) ^ 0x7;
> 
> +     /* Register numbering is ax,cx,dx,bx, sp,bp,si,di, r8..r15 */
> +     /*
> +      * Choose scratch reg. Order is important:
> +      * must not select bx if we can use si (cmpxchg8b case!)

It'd be good to add here:
         * For instructions without a VEX prefix, reg2 is 0 here.

Otherwise it kind of looks like you forgot to address that case, and the
reader shouldn't have to do the bit fiddling to figure it out.

> +      */
> +     if (reg != 6 && reg2 != 6) {
> +             reg2 = 6;
> +             auprobe->def.fixups |= UPROBE_FIX_RIP_SI;
> +     } else if (reg != 7 && reg2 != 7) {
> +             reg2 = 7;
> +             auprobe->def.fixups |= UPROBE_FIX_RIP_DI;
> +             /* TODO (paranoia): force maskmovq to not use di */
> +     } else {
> +             reg2 = 3; /* BX */
> +             auprobe->def.fixups |= UPROBE_FIX_RIP_BX;
> +     }

Yes.  Looks good from here down.

Reviewed-by: Jim Keniston <jkeni...@us.ibm.com>


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to