diff mbox series

[4/7] x86emul: vendor specific near indirect branch behavior in 64-bit mode

Message ID fbabdcdb-3123-75e7-896c-9c7dd844f409@suse.com (mailing list archive)
State Superseded
Headers show
Series x86emul: (mainly) vendor specific behavior adjustments | expand

Commit Message

Jan Beulich March 24, 2020, 4:27 p.m. UTC
Intel CPUs ignore operand size overrides here, while AMD ones don't.

Signed-off-by: Jan Beulich <jbeulich@suse.com>

Comments

Andrew Cooper March 25, 2020, 2:11 p.m. UTC | #1
On 24/03/2020 16:27, Jan Beulich wrote:
> Intel CPUs ignore operand size overrides here, while AMD ones don't.
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
diff mbox series

Patch

--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -813,6 +813,17 @@  static const struct {
         .opcode = { 0x66, 0x67, 0xe3, 0x10 },
         .opc_len = { 4, 4 },
         .disp = { 4 + 16 - MMAP_ADDR, 4 + 16 },
+    }, {
+        .descr = "jmpw *(%rsp)",
+        .opcode = { 0x66, 0xff, 0x24, 0x24 },
+        .opc_len = { 4, 4 },
+        .disp = { STKVAL_DISP - MMAP_ADDR, STKVAL_DISP },
+    }, {
+        .descr = "callw *(%rsp)",
+        .opcode = { 0x66, 0xff, 0x14, 0x24 },
+        .opc_len = { 4, 4 },
+        .stkoff = { -2, -8 },
+        .disp = { STKVAL_DISP - MMAP_ADDR, STKVAL_DISP },
     },
 };
 #endif
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -2524,8 +2524,7 @@  x86_decode_onebyte(
         {
         case 2: /* call (near) */
         case 4: /* jmp (near) */
-        case 6: /* push */
-            if ( mode_64bit() && op_bytes == 4 )
+            if ( mode_64bit() && (op_bytes == 4 || !amd_like(ctxt)) )
                 op_bytes = 8;
             state->desc = DstNone | SrcMem | Mov;
             break;
@@ -2537,6 +2536,12 @@  x86_decode_onebyte(
                 op_bytes = 4;
             state->desc = DstNone | SrcMem | Mov;
             break;
+
+        case 6: /* push */
+            if ( mode_64bit() && op_bytes == 4 )
+                op_bytes = 8;
+            state->desc = DstNone | SrcMem | Mov;
+            break;
         }
         break;
     }