ia64/xen-unstable
changeset 16483:f9a43c6b5be1
vmx realmode: When returning to protected mode we have to massage the
segment state to pass VMENTER's stringent 'sanity checks'.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
segment state to pass VMENTER's stringent 'sanity checks'.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Mon Nov 26 22:20:21 2007 +0000 (2007-11-26) |
parents | 4d6f92fa1014 |
children | 26e766e0c628 |
files | xen/arch/x86/hvm/vmx/realmode.c |
line diff
1.1 --- a/xen/arch/x86/hvm/vmx/realmode.c Mon Nov 26 17:55:23 2007 +0000 1.2 +++ b/xen/arch/x86/hvm/vmx/realmode.c Mon Nov 26 22:20:21 2007 +0000 1.3 @@ -524,7 +524,8 @@ void vmx_realmode(struct cpu_user_regs * 1.4 if ( rc == X86EMUL_UNHANDLEABLE ) 1.5 { 1.6 gdprintk(XENLOG_DEBUG, 1.7 - "RM %04x:%08lx: %02x %02x %02x %02x %02x %02x\n", 1.8 + "Real-mode emulation failed @ %04x:%08lx: " 1.9 + "%02x %02x %02x %02x %02x %02x\n", 1.10 rm_ctxt.seg_reg[x86_seg_cs].sel, rm_ctxt.insn_buf_eip, 1.11 rm_ctxt.insn_buf[0], rm_ctxt.insn_buf[1], 1.12 rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3], 1.13 @@ -534,6 +535,26 @@ void vmx_realmode(struct cpu_user_regs * 1.14 } 1.15 } 1.16 1.17 + /* 1.18 + * Cannot enter protected mode with bogus selector RPLs and DPLs. Hence we 1.19 + * fix up as best we can, even though this deviates from native execution 1.20 + */ 1.21 + if ( curr->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PE ) 1.22 + { 1.23 + /* CS.RPL == SS.RPL == SS.DPL == 0. */ 1.24 + rm_ctxt.seg_reg[x86_seg_cs].sel &= ~3; 1.25 + rm_ctxt.seg_reg[x86_seg_ss].sel &= ~3; 1.26 + /* DS,ES,FS,GS: The most uninvasive trick is to set DPL == RPL. */ 1.27 + rm_ctxt.seg_reg[x86_seg_ds].attr.fields.dpl = 1.28 + rm_ctxt.seg_reg[x86_seg_ds].sel & 3; 1.29 + rm_ctxt.seg_reg[x86_seg_es].attr.fields.dpl = 1.30 + rm_ctxt.seg_reg[x86_seg_es].sel & 3; 1.31 + rm_ctxt.seg_reg[x86_seg_fs].attr.fields.dpl = 1.32 + rm_ctxt.seg_reg[x86_seg_fs].sel & 3; 1.33 + rm_ctxt.seg_reg[x86_seg_gs].attr.fields.dpl = 1.34 + rm_ctxt.seg_reg[x86_seg_gs].sel & 3; 1.35 + } 1.36 + 1.37 for ( i = 0; i < 10; i++ ) 1.38 hvm_set_segment_register(curr, i, &rm_ctxt.seg_reg[i]); 1.39 } 1.40 @@ -546,12 +567,6 @@ int vmx_realmode_io_complete(void) 1.41 if ( !curr->arch.hvm_vmx.real_mode_io_in_progress ) 1.42 return 0; 1.43 1.44 -#if 0 1.45 - gdprintk(XENLOG_DEBUG, "RM I/O %d %c bytes=%d addr=%lx data=%lx\n", 1.46 - p->type, p->dir ? 'R' : 'W', 1.47 - (int)p->size, (long)p->addr, (long)p->data); 1.48 -#endif 1.49 - 1.50 curr->arch.hvm_vmx.real_mode_io_in_progress = 0; 1.51 if ( p->dir == IOREQ_READ ) 1.52 {