[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] vmx realmode: Support privileged EFLAGS updates in emulated realmode.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1195991102 0 # Node ID a194083696d5dbd9b7509d35924e48aa05678607 # Parent 368bcf480772fb32b22fa9cb0bffcd10f0ed2c25 vmx realmode: Support privileged EFLAGS updates in emulated realmode. Also tweak debug tracing to be much less noisy. We can emulates tens of thousands of instructions in rombios now. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/x86/hvm/vmx/realmode.c | 47 ++++++++++++++++++++++++++++++---------- xen/arch/x86/x86_emulate.c | 11 +++------ 2 files changed, 40 insertions(+), 18 deletions(-) diff -r 368bcf480772 -r a194083696d5 xen/arch/x86/hvm/vmx/realmode.c --- a/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 11:43:53 2007 +0000 +++ b/xen/arch/x86/hvm/vmx/realmode.c Sun Nov 25 11:45:02 2007 +0000 @@ -168,6 +168,14 @@ realmode_write_segment( struct realmode_emulate_ctxt *rm_ctxt = container_of(ctxt, struct realmode_emulate_ctxt, ctxt); memcpy(&rm_ctxt->seg_reg[seg], reg, sizeof(struct segment_register)); + + if ( seg == x86_seg_ss ) + { + u32 intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); + intr_shadow ^= VMX_INTR_SHADOW_MOV_SS; + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); + } + return X86EMUL_OKAY; } @@ -231,6 +239,20 @@ realmode_read_cr( break; default: return X86EMUL_UNHANDLEABLE; + } + + return X86EMUL_OKAY; +} + +static int realmode_write_rflags( + unsigned long val, + struct x86_emulate_ctxt *ctxt) +{ + if ( (val & X86_EFLAGS_IF) && !(ctxt->regs->eflags & X86_EFLAGS_IF) ) + { + u32 intr_shadow = __vmread(GUEST_INTERRUPTIBILITY_INFO); + intr_shadow ^= VMX_INTR_SHADOW_STI; + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, intr_shadow); } return X86EMUL_OKAY; @@ -245,7 +267,8 @@ static struct x86_emulate_ops realmode_e .write_segment = realmode_write_segment, .read_io = realmode_read_io, .write_io = realmode_write_io, - .read_cr = realmode_read_cr + .read_cr = realmode_read_cr, + .write_rflags = realmode_write_rflags }; int vmx_realmode(struct cpu_user_regs *regs) @@ -277,26 +300,22 @@ int vmx_realmode(struct cpu_user_regs *r rm_ctxt.insn_buf, addr, sizeof(rm_ctxt.insn_buf))) ? sizeof(rm_ctxt.insn_buf) : 0; - gdprintk(XENLOG_DEBUG, - "RM %04x:%08lx: %02x %02x %02x %02x %02x %02x\n", - rm_ctxt.seg_reg[x86_seg_cs].sel, regs->eip, - rm_ctxt.insn_buf[0], rm_ctxt.insn_buf[1], - rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3], - rm_ctxt.insn_buf[4], rm_ctxt.insn_buf[5]); - rc = x86_emulate(&rm_ctxt.ctxt, &realmode_emulator_ops); if ( curr->arch.hvm_vmx.real_mode_io_in_progress ) { - ioreq_t *p = &get_ioreq(curr)->vp_ioreq; - gdprintk(XENLOG_DEBUG, "RM I/O %d %c addr=%lx data=%lx\n", - p->type, p->dir ? 'R' : 'W', p->addr, p->data); rc = 0; break; } if ( rc ) { + gdprintk(XENLOG_DEBUG, + "RM %04x:%08lx: %02x %02x %02x %02x %02x %02x\n", + rm_ctxt.seg_reg[x86_seg_cs].sel, rm_ctxt.insn_buf_eip, + rm_ctxt.insn_buf[0], rm_ctxt.insn_buf[1], + rm_ctxt.insn_buf[2], rm_ctxt.insn_buf[3], + rm_ctxt.insn_buf[4], rm_ctxt.insn_buf[5]); gdprintk(XENLOG_ERR, "Emulation failed\n"); rc = -EINVAL; break; @@ -317,6 +336,12 @@ int vmx_realmode_io_complete(void) if ( !curr->arch.hvm_vmx.real_mode_io_in_progress ) return 0; +#if 0 + gdprintk(XENLOG_DEBUG, "RM I/O %d %c bytes=%d addr=%lx data=%lx\n", + p->type, p->dir ? 'R' : 'W', + (int)p->size, (long)p->addr, (long)p->data); +#endif + curr->arch.hvm_vmx.real_mode_io_in_progress = 0; if ( p->dir == IOREQ_READ ) { diff -r 368bcf480772 -r a194083696d5 xen/arch/x86/x86_emulate.c --- a/xen/arch/x86/x86_emulate.c Sun Nov 25 11:43:53 2007 +0000 +++ b/xen/arch/x86/x86_emulate.c Sun Nov 25 11:45:02 2007 +0000 @@ -2253,16 +2253,13 @@ x86_emulate( break; case 0xfa: /* cli */ - generate_exception_if(!mode_iopl(), EXC_GP); - fail_if(ops->write_rflags == NULL); - if ( (rc = ops->write_rflags(_regs.eflags & ~EFLG_IF, ctxt)) != 0 ) - goto done; - break; - case 0xfb: /* sti */ generate_exception_if(!mode_iopl(), EXC_GP); fail_if(ops->write_rflags == NULL); - if ( (rc = ops->write_rflags(_regs.eflags | EFLG_IF, ctxt)) != 0 ) + _regs.eflags &= ~EFLG_IF; + if ( b == 0xfb ) /* sti */ + _regs.eflags |= EFLG_IF; + if ( (rc = ops->write_rflags(_regs.eflags, ctxt)) != 0 ) goto done; break; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |