]> xenbits.xensource.com Git - people/dariof/xen.git/commitdiff
x86emul: correct EVEX decoding
authorJan Beulich <jbeulich@suse.com>
Fri, 26 Oct 2018 15:50:01 +0000 (17:50 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 26 Oct 2018 15:50:01 +0000 (17:50 +0200)
Fix an inverted pair of checks, drop an incorrect instance of #UD
raising for non-64-bit mode, and add further generic checks.

Note: Despite what SDM Vol 2 rev 067 states, EVEX.V' is _not_ ignored
      outside of 64-bit mode when the field does not encode a register.
      Just like EVEX.VVVV is required to be 0b1111 in that case, EVEX.V'
      is required to be 1 there.

Also rename the bcst field to br, as #UD generation for individual insns
will need to consider both of its possible meanings.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/x86_emulate/x86_emulate.c

index 90132f4c7cf23d69e5313339171c90d7f8773429..d8ebecd49d1a18b6bd46d513bf5bc6b6fe1ab13d 100644 (file)
@@ -650,7 +650,7 @@ union evex {
         uint8_t w:1;
         uint8_t opmsk:3;
         uint8_t RX:1;
-        uint8_t bcst:1;
+        uint8_t br:1;
         uint8_t lr:2;
         uint8_t z:1;
     };
@@ -2760,13 +2760,11 @@ x86_decode(
                         evex.raw[1] = vex.raw[1];
                         evex.raw[2] = insn_fetch_type(uint8_t);
 
-                        generate_exception_if(evex.mbs || !evex.mbz, EXC_UD);
+                        generate_exception_if(!evex.mbs || evex.mbz, EXC_UD);
+                        generate_exception_if(!evex.opmsk && evex.z, EXC_UD);
 
                         if ( !mode_64bit() )
-                        {
-                            generate_exception_if(!evex.RX, EXC_UD);
                             evex.R = 1;
-                        }
 
                         vex.opcx = evex.opcx;
                         break;
@@ -3404,6 +3402,7 @@ x86_emulate(
         d = (d & ~DstMask) | DstMem;
         /* Becomes a normal DstMem operation from here on. */
     case DstMem:
+        generate_exception_if(ea.type == OP_MEM && evex.z, EXC_UD);
         if ( state->simd_size )
         {
             generate_exception_if(lock_prefix, EXC_UD);