x86emul: VEX.B is ignored in compatibility mode While VEX.R and VEX.X are guaranteed to be 1 in compatibility mode, VEX.B can be encoded as zero, but would be ignored by the processor. Since we emulate instructions in 64-bit mode, we need to force the bit to 1 in order to not act on the wrong {X,Y,Z}MM register. We must not, however, fiddle with the high bit of VEX.VVVV in the decode phase, as that would undermine the checking of instructions requiring the field to be all ones independent of mode. This is being enforced in copy_REX_VEX() instead. Signed-off-by: Jan Beulich --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -331,7 +331,11 @@ union vex { #define copy_REX_VEX(ptr, rex, vex) do { \ if ( (vex).opcx != vex_none ) \ + { \ + if ( !mode_64bit() ) \ + vex.reg |= 8; \ ptr[0] = 0xc4, ptr[1] = (vex).raw[0], ptr[2] = (vex).raw[1]; \ + } \ else if ( mode_64bit() ) \ ptr[1] = rex | REX_PREFIX; \ } while (0) @@ -2217,6 +2221,8 @@ x86_decode( op_bytes = 8; } } + else + vex.b = 1; switch ( b ) { case 0x62: @@ -2235,7 +2241,7 @@ x86_decode( break; } } - if ( mode_64bit() && !vex.r ) + if ( !vex.r ) rex_prefix |= REX_R; ext = vex.opcx;