[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86emul: vendor specific direct branch behavior in 64-bit mode
commit 6329109cf352e164e0c227fe119b64bf7d38de38 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Thu Mar 26 12:32:07 2020 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Mar 26 12:32:07 2020 +0100 x86emul: vendor specific direct branch behavior in 64-bit mode Intel CPUs ignore operand size overrides here, while AMD ones don't. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- tools/tests/x86_emulator/test_x86_emulator.c | 68 ++++++++++++++++++++++++++++ xen/arch/x86/x86_emulate/x86_emulate.c | 8 +++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/tools/tests/x86_emulator/test_x86_emulator.c b/tools/tests/x86_emulator/test_x86_emulator.c index f28dae14e3..2d39bd05db 100644 --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -757,6 +757,62 @@ static const struct { .opc_len = { 4, 4 }, .stkoff = { 2 + 16, 8 + 16 }, .disp = { STKVAL_DISP - MMAP_ADDR, STKVAL_DISP }, + }, { + .descr = "jmpw .+16", + .opcode = { 0x66, 0xeb, 0x10 }, + .opc_len = { 3, 3 }, + .disp = { 3 + 16 - MMAP_ADDR, 3 + 16 }, + }, { + .descr = "jmpw .+128", + .opcode = { 0x66, 0xe9, 0x80, 0x00, 0x00, 0x00 }, + .opc_len = { 4, 6 }, + .disp = { 4 + 128 - MMAP_ADDR, 6 + 128 }, + }, { + .descr = "callw .+16", + .opcode = { 0x66, 0xe8, 0x10, 0x00, 0x00, 0x00 }, + .opc_len = { 4, 6 }, + .stkoff = { -2, -8 }, + .disp = { 4 + 16 - MMAP_ADDR, 6 + 16 }, + }, { + .descr = "jzw .+16", + .opcode = { 0x66, 0x74, 0x10 }, + .opc_len = { 3, 3 }, + .disp = { 3, 3 }, + }, { + .descr = "jzw .+128", + .opcode = { 0x66, 0x0f, 0x84, 0x80, 0x00, 0x00, 0x00 }, + .opc_len = { 5, 7 }, + .disp = { 5, 7 }, + }, { + .descr = "jnzw .+16", + .opcode = { 0x66, 0x75, 0x10 }, + .opc_len = { 3, 3 }, + .disp = { 3 + 16 - MMAP_ADDR, 3 + 16 }, + }, { + .descr = "jnzw .+128", + .opcode = { 0x66, 0x0f, 0x85, 0x80, 0x00, 0x00, 0x00 }, + .opc_len = { 5, 7 }, + .disp = { 5 + 128 - MMAP_ADDR, 7 + 128 }, + }, { + .descr = "loopqw .+16 (RCX>1)", + .opcode = { 0x66, 0xe0, 0x10 }, + .opc_len = { 3, 3 }, + .disp = { 3 + 16 - MMAP_ADDR, 3 + 16 }, + }, { + .descr = "looplw .+16 (ECX=1)", + .opcode = { 0x66, 0x67, 0xe0, 0x10 }, + .opc_len = { 4, 4 }, + .disp = { 4, 4 }, + }, { + .descr = "jrcxzw .+16 (RCX>0)", + .opcode = { 0x66, 0xe3, 0x10 }, + .opc_len = { 3, 3 }, + .disp = { 3, 3 }, + }, { + .descr = "jecxzw .+16 (ECX=0)", + .opcode = { 0x66, 0x67, 0xe3, 0x10 }, + .opc_len = { 4, 4 }, + .disp = { 4 + 16 - MMAP_ADDR, 4 + 16 }, }, }; #endif @@ -1361,6 +1417,7 @@ int main(int argc, char **argv) const char *vendor = cp.x86_vendor == X86_VENDOR_INTEL ? "Intel" : "AMD"; uint64_t *stk = (void *)res + MMAP_SZ - 16; + regs.rcx = 2; for ( i = 0; i < ARRAY_SIZE(vendor_tests); ++i ) { printf("%-*s", @@ -1370,6 +1427,7 @@ int main(int argc, char **argv) regs.eflags = EFLAGS_ALWAYS_SET; regs.rip = (unsigned long)instr; regs.rsp = (unsigned long)stk; + regs.rcx |= 0x8765432100000000UL; stk[0] = regs.rip + STKVAL_DISP; rc = x86_emulate(&ctxt, &emulops); if ( (rc != X86EMUL_OKAY) || @@ -1379,6 +1437,16 @@ int main(int argc, char **argv) ?: vendor_tests[i].opc_len[v])) || (regs.rsp != (unsigned long)stk + vendor_tests[i].stkoff[v]) ) goto fail; + /* For now only call insns push something onto the stack. */ + if ( regs.rsp < (unsigned long)stk ) + { + unsigned long opc_end = (unsigned long)instr + + vendor_tests[i].opc_len[v]; + + if ( memcmp(&opc_end, (void *)regs.rsp, + min((unsigned long)stk - regs.rsp, 8UL)) ) + goto fail; + } printf("okay\n"); } diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index c00f56a32a..49c21585c2 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1273,7 +1273,7 @@ do { \ #define jmp_rel(rel) \ do { \ unsigned long ip = _regs.r(ip) + (int)(rel); \ - if ( op_bytes == 2 ) \ + if ( op_bytes == 2 && (amd_like(ctxt) || !mode_64bit()) ) \ ip = (uint16_t)ip; \ else if ( !mode_64bit() ) \ ip = (uint32_t)ip; \ @@ -3391,7 +3391,13 @@ x86_decode( case SrcImm: if ( !(d & ByteOp) ) + { + if ( mode_64bit() && !amd_like(ctxt) && + ((ext == ext_none && (b | 1) == 0xe9) /* call / jmp */ || + (ext == ext_0f && (b | 0xf) == 0x8f) /* jcc */ ) ) + op_bytes = 4; bytes = op_bytes != 8 ? op_bytes : 4; + } else { case SrcImmByte: -- generated by git-patchbot for /home/xen/git/xen.git#staging _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |