[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86_emulate: Fix the segment-load function
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1213611857 -3600 # Node ID 049a42108c65d9e56d18539454d49bc83f66eca2 # Parent ac745ad5f018356b4cf4b1ba127e6c2cc42c4723 x86_emulate: Fix the segment-load function Fix the non-conforming type check and uses the consistent method to fetch the cpl value as function get_cpl(). Also make sure vm86 mode is properly handled when determining whether in real mode or protected mode -- in various respects vm86 mode can act like both. Signed-off-by: Dongxiao Xu <dongxiao.xu@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/x86_emulate/x86_emulate.c | 30 +++++++++++++++++++----------- 1 files changed, 19 insertions(+), 11 deletions(-) diff -r ac745ad5f018 -r 049a42108c65 xen/arch/x86/x86_emulate/x86_emulate.c --- a/xen/arch/x86/x86_emulate/x86_emulate.c Fri Jun 13 16:10:50 2008 +0100 +++ b/xen/arch/x86/x86_emulate/x86_emulate.c Mon Jun 16 11:24:17 2008 +0100 @@ -878,6 +878,14 @@ in_realmode( } static int +in_protmode( + struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops) +{ + return !(in_realmode(ctxt, ops) || (ctxt->regs->eflags & EFLG_VM)); +} + +static int realmode_load_seg( enum x86_segment seg, uint16_t sel, @@ -903,7 +911,7 @@ protmode_load_seg( struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { - struct segment_register desctab, cs, segr; + struct segment_register desctab, ss, segr; struct { uint32_t a, b; } desc; unsigned long val; uint8_t dpl, rpl, cpl; @@ -923,7 +931,7 @@ protmode_load_seg( if ( (seg == x86_seg_ldtr) && (sel & 4) ) goto raise_exn; - if ( (rc = ops->read_segment(x86_seg_cs, &cs, ctxt)) || + if ( (rc = ops->read_segment(x86_seg_ss, &ss, ctxt)) || (rc = ops->read_segment((sel & 4) ? x86_seg_ldtr : x86_seg_gdtr, &desctab, ctxt)) ) return rc; @@ -955,7 +963,7 @@ protmode_load_seg( dpl = (desc.b >> 13) & 3; rpl = sel & 3; - cpl = cs.sel & 3; + cpl = ss.attr.fields.dpl; switch ( seg ) { @@ -964,7 +972,7 @@ protmode_load_seg( if ( !(desc.b & (1u<<11)) ) goto raise_exn; /* Non-conforming segment: check DPL against RPL. */ - if ( ((desc.b & (6u<<9)) != 6) && (dpl != rpl) ) + if ( ((desc.b & (6u<<9)) != (6u<<9)) && (dpl != rpl) ) goto raise_exn; break; case x86_seg_ss: @@ -984,7 +992,7 @@ protmode_load_seg( if ( (desc.b & (5u<<9)) == (4u<<9) ) goto raise_exn; /* Non-conforming segment: check DPL against RPL and CPL. */ - if ( ((desc.b & (6u<<9)) != 6) && ((dpl < cpl) || (dpl < rpl)) ) + if ( ((desc.b & (6u<<9)) != (6u<<9)) && ((dpl < cpl) || (dpl < rpl)) ) goto raise_exn; break; } @@ -1034,10 +1042,10 @@ load_seg( (ops->write_segment == NULL) ) return X86EMUL_UNHANDLEABLE; - if ( in_realmode(ctxt, ops) ) - return realmode_load_seg(seg, sel, ctxt, ops); - - return protmode_load_seg(seg, sel, ctxt, ops); + if ( in_protmode(ctxt, ops) ) + return protmode_load_seg(seg, sel, ctxt, ops); + + return realmode_load_seg(seg, sel, ctxt, ops); } void * @@ -1596,7 +1604,7 @@ x86_emulate( dst.val = (dst.val & ~3) | (src_val & 3); else dst.type = OP_NONE; - generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1); + generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1); } break; @@ -3212,7 +3220,7 @@ x86_emulate( if ( modrm == 0xdf ) /* invlpga */ { - generate_exception_if(in_realmode(ctxt, ops), EXC_UD, -1); + generate_exception_if(!in_protmode(ctxt, ops), EXC_UD, -1); generate_exception_if(!mode_ring0(), EXC_GP, 0); fail_if(ops->invlpg == NULL); if ( (rc = ops->invlpg(x86_seg_none, truncate_ea(_regs.eax), _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |