Fixes for VMX emulation
This commit is contained in:
parent
3a470c9d11
commit
f6cb9e529f
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.cc,v 1.265 2009-02-01 20:47:06 sshwarts Exp $
|
||||
// $Id: cpu.cc,v 1.266 2009-02-02 18:59:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -505,15 +505,6 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
// Priority 4: Traps on Previous Instruction
|
||||
// Breakpoints
|
||||
// Debug Trap Exceptions (TF flag set or data/IO breakpoint)
|
||||
if (BX_CPU_THIS_PTR debug_trap &&
|
||||
!(BX_CPU_THIS_PTR inhibit_mask & BX_INHIBIT_DEBUG))
|
||||
{
|
||||
// A trap may be inhibited on this boundary due to an instruction
|
||||
// which loaded SS. If so we clear the inhibit_mask below
|
||||
// and don't execute this code until the next boundary.
|
||||
// Commit debug events to DR6
|
||||
exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
|
||||
}
|
||||
|
||||
// Priority 5: External Interrupts
|
||||
// NMI Interrupts
|
||||
@ -525,6 +516,20 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
// an opportunity to check interrupts on the next instruction
|
||||
// boundary.
|
||||
}
|
||||
#if BX_SUPPORT_VMX
|
||||
else if (BX_CPU_THIS_PTR intr_pending_vmx && BX_CPU_THIS_PTR get_IF())
|
||||
{
|
||||
// interrupt-window exiting
|
||||
BX_ERROR(("VMEXIT: Interrupt window exiting"));
|
||||
VMexit(0, VMX_VMEXIT_INTERRUPT_WINDOW, 0);
|
||||
}
|
||||
#endif
|
||||
else if (BX_CPU_THIS_PTR debug_trap) {
|
||||
// A trap may be inhibited on this boundary due to an instruction
|
||||
// which loaded SS. If so we clear the inhibit_mask below
|
||||
// and don't execute this code until the next boundary.
|
||||
exception(BX_DB_EXCEPTION, 0, 0); // no error, not interrupt
|
||||
}
|
||||
else if (BX_CPU_THIS_PTR pending_NMI) {
|
||||
BX_CPU_THIS_PTR pending_NMI = 0;
|
||||
BX_CPU_THIS_PTR disable_NMI = 1;
|
||||
@ -536,14 +541,6 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
BX_INSTR_HWINTERRUPT(BX_CPU_ID, 2, BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
interrupt(2, BX_NMI, 0, 0);
|
||||
}
|
||||
#if BX_SUPPORT_VMX
|
||||
else if (BX_CPU_THIS_PTR intr_pending_vmx && BX_CPU_THIS_PTR get_IF())
|
||||
{
|
||||
// interrupt-window exiting
|
||||
BX_ERROR(("VMEXIT: Interrupt window exiting"));
|
||||
VMexit(0, VMX_VMEXIT_INTERRUPT_WINDOW, 0);
|
||||
}
|
||||
#endif
|
||||
else if (BX_CPU_INTR && BX_CPU_THIS_PTR get_IF() && BX_DBG_ASYNC_INTR)
|
||||
{
|
||||
Bit8u vector;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: cpu.h,v 1.566 2009-02-01 20:47:06 sshwarts Exp $
|
||||
// $Id: cpu.h,v 1.567 2009-02-02 18:59:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -3415,7 +3415,7 @@ public: // for now...
|
||||
BX_SMF bx_bool VMexit_CLTS(bxInstruction_c *i) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void VMexit_MSR(bxInstruction_c *i, unsigned op, Bit32u msr) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void VMexit_IO(bxInstruction_c *i, unsigned port, unsigned len) BX_CPP_AttrRegparmN(3);
|
||||
BX_SMF void VMexit_LMSW(bxInstruction_c *i, Bit32u msw) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF Bit32u VMexit_LMSW(bxInstruction_c *i, Bit32u msw) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF bx_address VMexit_CR0_Write(bxInstruction_c *i, bx_address) BX_CPP_AttrRegparmN(2);
|
||||
BX_SMF void VMexit_CR3_Read(bxInstruction_c *i) BX_CPP_AttrRegparmN(1);
|
||||
BX_SMF void VMexit_CR3_Write(bxInstruction_c *i, bx_address) BX_CPP_AttrRegparmN(2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: proc_ctrl.cc,v 1.280 2009-02-01 20:47:06 sshwarts Exp $
|
||||
// $Id: proc_ctrl.cc,v 1.281 2009-02-02 18:59:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001 MandrakeSoft S.A.
|
||||
@ -870,7 +870,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::LMSW_Ew(bxInstruction_c *i)
|
||||
// LMSW does not affect PG,CD,NW,AM,WP,NE,ET bits, and cannot clear PE
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_LMSW(i, msw);
|
||||
msw = VMexit_LMSW(i, msw);
|
||||
#endif
|
||||
|
||||
// LMSW cannot clear PE
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vmexit.cc,v 1.2 2009-02-01 22:23:33 sshwarts Exp $
|
||||
// $Id: vmexit.cc,v 1.3 2009-02-02 18:59:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2009 Stanislav Shwartsman
|
||||
@ -515,21 +515,22 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_CLTS(bxInstruction_c *i)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_LMSW(bxInstruction_c *i, Bit32u msw)
|
||||
Bit32u BX_CPP_AttrRegparmN(2) BX_CPU_C::VMexit_LMSW(bxInstruction_c *i, Bit32u msw)
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR in_vmx_guest) return;
|
||||
if (! BX_CPU_THIS_PTR in_vmx_guest) return msw;
|
||||
|
||||
VMCS_CACHE *vm = &BX_CPU_THIS_PTR vmcs;
|
||||
Bit32u mask = vm->vm_cr0_mask & 0xF; /* LMSW affects only low 4 bits */
|
||||
bx_bool vmexit = 0;
|
||||
|
||||
if ((vm->vm_cr0_mask & msw & 0x1) != 0 && (vm->vm_cr0_read_shadow & 0x1) == 0)
|
||||
if ((mask & msw & 0x1) != 0 && (vm->vm_cr0_read_shadow & 0x1) == 0)
|
||||
vmexit = 1;
|
||||
|
||||
if ((vm->vm_cr0_mask & vm->vm_cr0_read_shadow & 0xE) != (vm->vm_cr0_mask & msw & 0xE))
|
||||
if ((mask & vm->vm_cr0_read_shadow & 0xE) != (mask & msw & 0xE))
|
||||
vmexit = 1;
|
||||
|
||||
if (vmexit) {
|
||||
BX_ERROR(("VMEXIT: CR0 write by LMSW"));
|
||||
BX_ERROR(("VMEXIT: CR0 write by LMSW of value 0x%04x", msw));
|
||||
|
||||
Bit64u qualification = VMX_VMEXIT_CR_ACCESS_LMSW << 4;
|
||||
qualification |= msw << 16;
|
||||
@ -540,6 +541,9 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::VMexit_LMSW(bxInstruction_c *i, Bit32u msw
|
||||
|
||||
VMexit(i, VMX_VMEXIT_CR_ACCESS, qualification);
|
||||
}
|
||||
|
||||
// keep untouched all the bits set in CR0 mask
|
||||
return (BX_CPU_THIS_PTR cr0.get32() & mask) | (msw & ~mask);
|
||||
}
|
||||
|
||||
bx_address BX_CPP_AttrRegparmN(2) BX_CPU_C::VMexit_CR0_Write(bxInstruction_c *i, bx_address val)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: vmx.cc,v 1.3 2009-02-01 22:23:33 sshwarts Exp $
|
||||
// $Id: vmx.cc,v 1.4 2009-02-02 18:59:44 sshwarts Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2009 Stanislav Shwartsman
|
||||
@ -1049,7 +1049,7 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
guest.tmpDR6 = VMread64(VMCS_GUEST_PENDING_DBG_EXCEPTIONS);
|
||||
|
||||
if (guest.tmpDR6 & BX_CONST64(0xFFFFFFFFFFFFAFF0)) {
|
||||
BX_ERROR(("VMENTER FAIL: VMCS guest tmpDR6 reserved bits %08x:%08x", GET32H(guest.tmpDR6), GET32L(guest.tmpDR6)));
|
||||
BX_ERROR(("VMENTER FAIL: VMCS guest tmpDR6 reserved bits"));
|
||||
return VMX_VMEXIT_VMENTRY_FAILURE_GUEST_STATE;
|
||||
}
|
||||
|
||||
@ -1180,7 +1180,10 @@ Bit32u BX_CPU_C::VMenterLoadCheckGuestState(Bit64u *qualification)
|
||||
BX_CPU_THIS_PTR debug_trap = 0;
|
||||
}
|
||||
else {
|
||||
BX_CPU_THIS_PTR debug_trap = guest.tmpDR6 & 0x0000400f;
|
||||
if (guest.tmpDR6 & (1 << 12))
|
||||
BX_CPU_THIS_PTR debug_trap = guest.tmpDR6 & 0x0000400F;
|
||||
else
|
||||
BX_CPU_THIS_PTR debug_trap = guest.tmpDR6 & 0x00004000;
|
||||
if (BX_CPU_THIS_PTR debug_trap)
|
||||
BX_CPU_THIS_PTR async_event = 1;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user