[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] x86/emul: Simplfy L{ES,DS,SS,FS,GS} handling
%ss, %fs and %gs can be calculated by directly masking the opcode. %es and %ds cant, but the calculation isn't hard. Use seg rather than dst.val for storing the calculated segment, which is appropriately typed. The mode_64() check can be repositioned and simplified to drop the ext check. Replace opencoding of X86EMUL_OKAY. Finally, introduce assertions each time we calculate a user segment to load (rather than using constants) which don't have other validity checks. This includes the POP %sreg case. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> --- xen/arch/x86/x86_emulate/x86_emulate.c | 40 +++++++++++++++------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 1b5becf..2fb99e9 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -2765,6 +2765,7 @@ x86_emulate( if ( mode_64bit() && (op_bytes == 4) ) op_bytes = 8; seg = (b >> 3) & 7; + ASSERT(is_x86_user_segment(seg)); if ( (rc = read_ulong(x86_seg_ss, sp_post_inc(op_bytes), &dst.val, op_bytes, ctxt, ops)) != X86EMUL_OKAY || (rc = load_seg(seg, dst.val, 0, NULL, ctxt, ops)) != X86EMUL_OKAY ) @@ -3393,25 +3394,32 @@ x86_emulate( _regs.eip = dst.val; break; - case 0xc4: /* les */ { + case 0xc4: /* les */ + case 0xc5: /* lds */ + { unsigned long sel; - dst.val = x86_seg_es; - les: /* dst.val identifies the segment */ - generate_exception_if(mode_64bit() && !ext, EXC_UD); + + generate_exception_if(mode_64bit(), EXC_UD); + seg = (b & 1) * 3; /* es = 0, ds = 3 */ + goto les; + + case X86EMUL_OPC(0x0f, 0xb2): /* lss */ + case X86EMUL_OPC(0x0f, 0xb4): /* lfs */ + case X86EMUL_OPC(0x0f, 0xb5): /* lgs */ + seg = b & 7; + + les: generate_exception_if(src.type != OP_MEM, EXC_UD); if ( (rc = read_ulong(src.mem.seg, src.mem.off + src.bytes, - &sel, 2, ctxt, ops)) != 0 ) + &sel, 2, ctxt, ops)) != X86EMUL_OKAY ) goto done; - if ( (rc = load_seg(dst.val, sel, 0, NULL, ctxt, ops)) != 0 ) + ASSERT(is_x86_user_segment(seg)); + if ( (rc = load_seg(seg, sel, 0, NULL, ctxt, ops)) != X86EMUL_OKAY ) goto done; dst.val = src.val; break; } - case 0xc5: /* lds */ - dst.val = x86_seg_ds; - goto les; - case 0xc8: /* enter imm16,imm8 */ { uint8_t depth = imm2 & 31; int i; @@ -5228,22 +5236,10 @@ x86_emulate( } break; - case X86EMUL_OPC(0x0f, 0xb2): /* lss */ - dst.val = x86_seg_ss; - goto les; - case X86EMUL_OPC(0x0f, 0xb3): btr: /* btr */ emulate_2op_SrcV_nobyte("btr", src, dst, _regs.eflags); break; - case X86EMUL_OPC(0x0f, 0xb4): /* lfs */ - dst.val = x86_seg_fs; - goto les; - - case X86EMUL_OPC(0x0f, 0xb5): /* lgs */ - dst.val = x86_seg_gs; - goto les; - case X86EMUL_OPC(0x0f, 0xb6): /* movzx rm8,r{16,32,64} */ /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */ dst.reg = decode_register(modrm_reg, &_regs, 0); -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |