On 31/01/2019 14:25, Jan Beulich wrote:
> --- a/xen/arch/x86/x86_emulate/x86_emulate.c
> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c
> @@ -2207,10 +2207,7 @@ static void *_decode_gpr(
>  
>      ASSERT(modrm_reg < ARRAY_SIZE(byte_reg_offsets));
>  
> -    /* For safety in release builds.  Debug builds will hit the ASSERT() */
> -    modrm_reg &= ARRAY_SIZE(byte_reg_offsets) - 1;
> -
> -    return (void *)regs + byte_reg_offsets[modrm_reg];
> +    return (void *)regs + array_access_nospec(byte_reg_offsets, modrm_reg);
>  }

Actually, the &= here wasn't by accident.  When the array size is an
power of two and known to the compiler, it is a rather lower overhead
alternative to array_access_nospec(), as it avoids the cmp/sbb dance in
the asm volatile statement.

I wonder if there is a sensible way cope with this in
array_access_nospec().  Perhaps something like:

#define array_access_nospec(array, index)
({
    size_t _s = ARRAY_SIZE(array);

    if ( !(_s & (_s - 1)) )
    {
        typeof(index) _i = index & (_s - 1);
        OPTIMIZER_HIDE_VAR(_i);
        (array)[_i];
    }
    else
        (array)[array_index_nospec(index, ARRAY_SIZE(array))];
})

As _s is known at compile time, only one half of the if condition will
be emitted by the compiler.

~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Reply via email to