[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86/emul: Calculate not_64bit during instruction decode
commit 9b1f6622b68145931d6ff93ff4f37e6666bbcae1 Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> AuthorDate: Fri Jan 13 13:23:42 2017 +0000 Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> CommitDate: Mon Jan 16 17:37:26 2017 +0000 x86/emul: Calculate not_64bit during instruction decode ... rather than repeating "generate_exception_if(mode_64bit(), EXC_UD);" in the emulation switch statement. Bloat-o-meter shows: add/remove: 0/0 grow/shrink: 1/2 up/down: 8/-495 (-487) function old new delta per_cpu__state 98 106 +8 x86_decode 6782 6726 -56 x86_emulate 57160 56721 -439 The reason for x86_decode() getting smaller is that this change alters the x86_decode_onebyte() switch statement from a chain of if()/else's to a jump table. The jump table adds 250 bytes of data which bloat-o-meter clearly can't see. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx> --- xen/arch/x86/x86_emulate/x86_emulate.c | 47 +++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 445dcac..e9ac1fc 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1907,6 +1907,7 @@ struct x86_emulate_state { uint8_t modrm, modrm_mod, modrm_reg, modrm_rm; uint8_t rex_prefix; bool lock_prefix; + bool not_64bit; /* Instruction not available in 64bit. */ opcode_desc_t desc; union vex vex; union evex evex; @@ -1957,6 +1958,30 @@ x86_decode_onebyte( switch ( ctxt->opcode ) { + case 0x06: /* push %%es */ + case 0x07: /* pop %%es */ + case 0x0e: /* push %%cs */ + case 0x16: /* push %%ss */ + case 0x17: /* pop %%ss */ + case 0x1e: /* push %%ds */ + case 0x1f: /* pop %%ds */ + case 0x27: /* daa */ + case 0x2f: /* das */ + case 0x37: /* aaa */ + case 0x3f: /* aas */ + case 0x60: /* pusha */ + case 0x61: /* popa */ + case 0x62: /* bound */ + case 0x82: /* Grp1 (x86/32 only) */ + case 0xc4: /* les */ + case 0xc5: /* lds */ + case 0xce: /* into */ + case 0xd4: /* aam */ + case 0xd5: /* aad */ + case 0xd6: /* salc */ + state->not_64bit = true; + break; + case 0x90: /* nop / pause */ if ( repe_prefix() ) ctxt->opcode |= X86EMUL_OPC_F3(0, 0); @@ -2624,6 +2649,8 @@ x86_emulate( d = state.desc; #define state (&state) + generate_exception_if(state->not_64bit && mode_64bit(), EXC_UD); + if ( ea.type == OP_REG ) ea.reg = decode_register(modrm_rm, &_regs, (d & ByteOp) && !rex_prefix); @@ -2832,8 +2859,6 @@ x86_emulate( case 0x0e: /* push %%cs */ case 0x16: /* push %%ss */ case 0x1e: /* push %%ds */ - generate_exception_if(mode_64bit(), EXC_UD); - /* fall through */ case X86EMUL_OPC(0x0f, 0xa0): /* push %%fs */ case X86EMUL_OPC(0x0f, 0xa8): /* push %%gs */ fail_if(ops->read_segment == NULL); @@ -2846,8 +2871,6 @@ x86_emulate( case 0x07: /* pop %%es */ case 0x17: /* pop %%ss */ case 0x1f: /* pop %%ds */ - generate_exception_if(mode_64bit(), EXC_UD); - /* fall through */ case X86EMUL_OPC(0x0f, 0xa1): /* pop %%fs */ case X86EMUL_OPC(0x0f, 0xa9): /* pop %%gs */ fail_if(ops->write_segment == NULL); @@ -2868,7 +2891,6 @@ x86_emulate( uint8_t al = _regs.al; unsigned int eflags = _regs._eflags; - generate_exception_if(mode_64bit(), EXC_UD); _regs._eflags &= ~(EFLG_CF|EFLG_AF|EFLG_SF|EFLG_ZF|EFLG_PF); if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) ) { @@ -2890,7 +2912,6 @@ x86_emulate( case 0x37: /* aaa */ case 0x3f: /* aas */ - generate_exception_if(mode_64bit(), EXC_UD); _regs._eflags &= ~EFLG_CF; if ( (_regs.al > 9) || (_regs._eflags & EFLG_AF) ) { @@ -2935,7 +2956,6 @@ x86_emulate( _regs._eax, _regs._ecx, _regs._edx, _regs._ebx, _regs._esp, _regs._ebp, _regs._esi, _regs._edi }; - generate_exception_if(mode_64bit(), EXC_UD); fail_if(!ops->write); for ( i = 0; i < 8; i++ ) if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), @@ -2950,7 +2970,6 @@ x86_emulate( &_regs._edi, &_regs._esi, &_regs._ebp, &dummy_esp, &_regs._ebx, &_regs._edx, &_regs._ecx, &_regs._eax }; - generate_exception_if(mode_64bit(), EXC_UD); for ( i = 0; i < 8; i++ ) { if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes), @@ -2967,8 +2986,7 @@ x86_emulate( case 0x62: /* bound */ { unsigned long src_val2; int lb, ub, idx; - generate_exception_if(mode_64bit() || (src.type != OP_MEM), - EXC_UD); + generate_exception_if(src.type != OP_MEM, EXC_UD); if ( (rc = read_ulong(src.mem.seg, src.mem.off + op_bytes, &src_val2, op_bytes, ctxt, ops)) ) goto done; @@ -3127,10 +3145,7 @@ x86_emulate( adjust_bnd(ctxt, ops, vex.pfx); break; - case 0x82: /* Grp1 (x86/32 only) */ - generate_exception_if(mode_64bit(), EXC_UD); - /* Fallthrough. */ - case 0x80: case 0x81: case 0x83: /* Grp1 */ + case 0x80: case 0x81: case 0x82: case 0x83: /* Grp1 */ switch ( modrm_reg & 7 ) { case 0: goto add; @@ -3518,7 +3533,6 @@ x86_emulate( case 0xc4: /* les */ case 0xc5: /* lds */ - generate_exception_if(mode_64bit(), EXC_UD); seg = (b & 1) * 3; /* es = 0, ds = 3 */ les: generate_exception_if(src.type != OP_MEM, EXC_UD); @@ -3606,7 +3620,6 @@ x86_emulate( goto done; case 0xce: /* into */ - generate_exception_if(mode_64bit(), EXC_UD); if ( !(_regs._eflags & EFLG_OF) ) break; src.val = EXC_OF; @@ -3648,7 +3661,6 @@ x86_emulate( case 0xd5: /* aad */ { unsigned int base = (uint8_t)src.val; - generate_exception_if(mode_64bit(), EXC_UD); if ( b & 0x01 ) { uint16_t ax = _regs.ax; @@ -3670,7 +3682,6 @@ x86_emulate( } case 0xd6: /* salc */ - generate_exception_if(mode_64bit(), EXC_UD); _regs.al = (_regs._eflags & EFLG_CF) ? 0xff : 0x00; break; -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |