]> xenbits.xensource.com Git - xen.git/commitdiff
x86emul: correct segment override decode for 64-bit mode
authorJan Beulich <jbeulich@suse.com>
Mon, 16 Dec 2019 16:34:46 +0000 (17:34 +0100)
committerJan Beulich <jbeulich@suse.com>
Mon, 16 Dec 2019 16:34:46 +0000 (17:34 +0100)
The legacy / compatibility mode ES, CS, SS, and DS overrides are fully
ignored prefixes in 64-bit mode, i.e. they in particular don't cancel an
earlier FS or GS one. (They don't violate the REX-prefix-must-be-last
rule though.)

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

index 777cac2b29c66781d3f8daa6ce6f8ca9a9eb1baf..d793bffa04921a060d0a6ac7af69ddf00e2994b8 100644 (file)
@@ -2830,14 +2830,17 @@ x86_decode(
         case 0x67: /* address-size override */
             ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6);
             break;
-        case 0x2e: /* CS override */
-            override_seg = x86_seg_cs;
+        case 0x2e: /* CS override / ignored in 64-bit mode */
+            if ( !mode_64bit() )
+                override_seg = x86_seg_cs;
             break;
-        case 0x3e: /* DS override */
-            override_seg = x86_seg_ds;
+        case 0x3e: /* DS override / ignored in 64-bit mode */
+            if ( !mode_64bit() )
+                override_seg = x86_seg_ds;
             break;
-        case 0x26: /* ES override */
-            override_seg = x86_seg_es;
+        case 0x26: /* ES override / ignored in 64-bit mode */
+            if ( !mode_64bit() )
+                override_seg = x86_seg_es;
             break;
         case 0x64: /* FS override */
             override_seg = x86_seg_fs;
@@ -2845,8 +2848,9 @@ x86_decode(
         case 0x65: /* GS override */
             override_seg = x86_seg_gs;
             break;
-        case 0x36: /* SS override */
-            override_seg = x86_seg_ss;
+        case 0x36: /* SS override / ignored in 64-bit mode */
+            if ( !mode_64bit() )
+                override_seg = x86_seg_ss;
             break;
         case 0xf0: /* LOCK */
             lock_prefix = 1;
@@ -2871,10 +2875,6 @@ x86_decode(
     }
  done_prefixes:
 
-    /* %{e,c,s,d}s overrides are ignored in 64bit mode. */
-    if ( mode_64bit() && override_seg < x86_seg_fs )
-        override_seg = x86_seg_none;
-
     if ( rex_prefix & REX_W )
         op_bytes = 8;