|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 10/30] x86emul: support JMPABS
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/tools/tests/x86_emulator/test_x86_emulator.c
+++ b/tools/tests/x86_emulator/test_x86_emulator.c
@@ -1979,6 +1979,22 @@ int main(int argc, char **argv)
cpu_policy.feat.movrs = movrs;
}
+
+ printf("%-40s", "Testing jmpabs $0x123456789abc...");
+ if ( cpu_has_apx_f )
+ {
+ instr[0] = 0xd5; instr[1] = 0x00; instr[2] = 0xa1;
+ instr[3] = 0xbc; instr[4] = 0x9a; instr[5] = 0x78; instr[6] = 0x56;
+ instr[7] = 0x34; instr[8] = 0x12; instr[9] = 0; instr[10] = 0;
+ regs.rip = (unsigned long)&instr[0];
+ rc = x86_emulate(&ctxt, &emulops);
+ if ( (rc != X86EMUL_OKAY) ||
+ (regs.rip != 0x123456789abcUL) )
+ goto fail;
+ printf("okay\n");
+ }
+ else
+ printf("skipped\n");
#endif /* x86-64 */
printf("%-40s", "Testing shld $1,%ecx,(%edx)...");
--- a/xen/arch/x86/x86_emulate/decode.c
+++ b/xen/arch/x86/x86_emulate/decode.c
@@ -689,6 +689,13 @@ decode_onebyte(struct x86_emulate_state
s->ea.mem.off = insn_fetch_bytes(s->ad_bytes);
break;
+ case X86EMUL_OPC_REX2 | 0xa1: /* jmpabs */
+ if ( s->ad_bytes == 8 ) /* Fetch more bytes to obtain imm64. */
+ s->imm1 = ((uint32_t)s->imm1 |
+ ((uint64_t)insn_fetch_type(uint32_t) << 32));
+ ctxt->opcode |= MASK_INSR(s->vex.pfx, X86EMUL_OPC_PFX_MASK);
+ break;
+
case 0xb8 ... 0xbf: /* mov imm{16,32,64},r{16,32,64} */
if ( s->op_bytes == 8 ) /* Fetch more bytes to obtain imm64. */
s->imm1 = ((uint32_t)s->imm1 |
@@ -1948,6 +1955,16 @@ int x86emul_decode(struct x86_emulate_st
{
s->modrm_mod = 0xff;
s->modrm_reg = s->modrm_rm = s->modrm = 0;
+
+ switch ( opcode )
+ {
+ case X86EMUL_OPC_REX2 | 0xa1:
+ d = DstImplicit | SrcImm;
+ break;
+
+ default:
+ break;
+ }
}
if ( override_seg != x86_seg_none )
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -2237,6 +2237,13 @@ x86_emulate(
_regs.ah = (_regs.eflags & EFLAGS_MASK) | X86_EFLAGS_MBS;
break;
+ case X86EMUL_OPC_REX2 | 0xa1: /* jmpabs */
+ generate_exception_if(ad_bytes != 8 || op_bytes != 4, X86_EXC_UD);
+ generate_exception_if(!is_canonical_address(imm1), X86_EXC_GP, 0);
+ _regs.r(ip) = imm1;
+ singlestep = _regs.eflags & X86_EFLAGS_TF;
+ break;
+
case 0xa4 ... 0xa5: /* movs */ {
unsigned long nr_reps = get_rep_prefix(true, true);
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |