[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86emul: fix pushing of selector registers
commit 373923ed9c2ed36925f574387db2be2ebe5ce45a Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Fri Oct 14 14:09:16 2016 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Fri Oct 14 14:09:16 2016 +0200 x86emul: fix pushing of selector registers Both explicit PUSH and far CALL currently push unrelated data (the segment attributes word) in the high half (attributes and limit in the 64-bit case in the high 48 bits) instead of zero. To avoid having to apply this and further changes in multiple places, also fold the two (respectively) far call/jmp instances into one. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/x86_emulate/x86_emulate.c | 46 +++++++++------------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 7f53f94..38147c5 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -2643,13 +2643,8 @@ x86_emulate( fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(src.val, &sreg, ctxt)) != 0 ) goto done; - /* 64-bit mode: PUSH defaults to a 64-bit operand. */ - if ( mode_64bit() && (op_bytes == 4) ) - op_bytes = 8; - if ( (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) != 0 ) - goto done; - break; + src.val = sreg.sel; + goto push; case 0x07: /* pop %%es */ src.val = x86_seg_es; @@ -3064,13 +3059,15 @@ x86_emulate( case 0x9a: /* call (far, absolute) */ ASSERT(!mode_64bit()); + far_call: fail_if(ops->read_segment == NULL); if ( (rc = ops->read_segment(x86_seg_cs, &sreg, ctxt)) || (rc = load_seg(x86_seg_cs, imm2, 0, &cs, ctxt, ops)) || (validate_far_branch(&cs, imm1), + src.val = sreg.sel, rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) || + &src.val, op_bytes, ctxt)) || (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), &_regs.eip, op_bytes, ctxt)) || (rc = ops->write_segment(x86_seg_cs, &cs, ctxt)) ) @@ -4025,6 +4022,7 @@ x86_emulate( case 0xea: /* jmp (far, absolute) */ ASSERT(!mode_64bit()); + far_jmp: if ( (rc = load_seg(x86_seg_cs, imm2, 0, &cs, ctxt, ops)) || (rc = commit_far_branch(&cs, imm1)) ) goto done; @@ -4288,36 +4286,16 @@ x86_emulate( dst.type = OP_NONE; break; case 3: /* call (far, absolute indirect) */ - case 5: /* jmp (far, absolute indirect) */ { - unsigned long sel; - + case 5: /* jmp (far, absolute indirect) */ generate_exception_if(src.type != OP_MEM, EXC_UD, -1); if ( (rc = read_ulong(src.mem.seg, src.mem.off + op_bytes, - &sel, 2, ctxt, ops)) ) + &imm2, 2, ctxt, ops)) ) goto done; - - if ( (modrm_reg & 7) == 3 ) /* call */ - { - fail_if(ops->read_segment == NULL); - if ( (rc = ops->read_segment(x86_seg_cs, &sreg, ctxt)) || - (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || - (validate_far_branch(&cs, src.val), - rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &sreg.sel, op_bytes, ctxt)) || - (rc = ops->write(x86_seg_ss, sp_pre_dec(op_bytes), - &_regs.eip, op_bytes, ctxt)) || - (rc = ops->write_segment(x86_seg_cs, &cs, ctxt)) ) - goto done; - _regs.eip = src.val; - } - else if ( (rc = load_seg(x86_seg_cs, sel, 0, &cs, ctxt, ops)) || - (rc = commit_far_branch(&cs, src.val)) ) - goto done; - - dst.type = OP_NONE; - break; - } + imm1 = src.val; + if ( !(modrm_reg & 4) ) + goto far_call; + goto far_jmp; case 6: /* push */ goto push; case 7: -- 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 |