[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.2-testing] x86_emulate: Fix the segment-load function
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1213613667 -3600 # Node ID d1d066a0fc01c52c2fa5baaf4328ee4f72100348 # Parent b39b6ab402ee28b71d0b78e92f897f38e1583e89 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-unstable changeset: 17861:049a42108c65d9e56d18539454d49bc83f66eca2 xen-unstable date: Mon Jun 16 11:24:17 2008 +0100 --- xen/arch/x86/x86_emulate.c | 28 ++++++++++++++++++---------- 1 files changed, 18 insertions(+), 10 deletions(-) diff -r b39b6ab402ee -r d1d066a0fc01 xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Fri Jun 13 13:59:22 2008 +0100 +++ b/xen/arch/x86/x86_emulate.c Mon Jun 16 11:54:27 2008 +0100 @@ -817,6 +817,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, @@ -842,7 +850,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; @@ -861,7 +869,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; @@ -893,7 +901,7 @@ protmode_load_seg( dpl = (desc.b >> 13) & 3; rpl = sel & 3; - cpl = cs.sel & 3; + cpl = ss.attr.fields.dpl; switch ( seg ) { @@ -902,7 +910,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: @@ -922,7 +930,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; } @@ -971,10 +979,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 * @@ -1530,7 +1538,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); + generate_exception_if(!in_protmode(ctxt, ops), EXC_UD); } break; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |