more SVM implementation
This commit is contained in:
parent
3e65692e40
commit
7f5f917a34
137
bochs/cpu/cpu.cc
137
bochs/cpu/cpu.cc
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2001-2011 The Bochs Project
|
||||
// Copyright (C) 2001-2012 The Bochs Project
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
@ -476,12 +476,8 @@ void BX_CPP_AttrRegparmN(2) BX_CPU_C::repeat_ZF(bxInstruction_c *i, BxRepIterati
|
||||
BX_CPU_THIS_PTR async_event |= BX_ASYNC_EVENT_STOP_TRACE;
|
||||
}
|
||||
|
||||
unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
bx_bool BX_CPU_C::handleWaitForEvent(void)
|
||||
{
|
||||
//
|
||||
// This area is where we process special conditions and events.
|
||||
//
|
||||
if (BX_CPU_THIS_PTR activity_state != BX_ACTIVITY_STATE_ACTIVE) {
|
||||
// For one processor, pass the time as quickly as possible until
|
||||
// an interrupt wakes up the CPU.
|
||||
while (1)
|
||||
@ -503,7 +499,7 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR activity_state == BX_ACTIVITY_STATE_ACTIVE) {
|
||||
BX_INFO(("handleAsyncEvent: reset detected in HLT state"));
|
||||
BX_INFO(("handleWaitForEvent: reset detected in HLT state"));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -531,8 +527,88 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
return 1; // Return to caller of cpu_loop.
|
||||
#endif
|
||||
|
||||
if (bx_pc_system.kill_bochs_request) {
|
||||
// setting kill_bochs_request causes the cpu loop to return ASAP.
|
||||
return 1; // Return to caller of cpu_loop.
|
||||
}
|
||||
|
||||
BX_TICKN(10); // when in HLT run time faster for single CPU
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BX_CPP_INLINE bx_bool BX_CPU_C::interrupts_enabled(void)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest && SVM_V_INTR_MASKING) return SVM_HOST_IF;
|
||||
#endif
|
||||
return BX_CPU_THIS_PTR get_IF();
|
||||
}
|
||||
|
||||
void BX_CPU_C::InterruptAcknowledge(void)
|
||||
{
|
||||
Bit8u vector;
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_INTR)) Svm_Vmexit(SVM_VMEXIT_INTR);
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_ExtInterrupt();
|
||||
#endif
|
||||
|
||||
// NOTE: similar code in ::take_irq()
|
||||
#if BX_SUPPORT_APIC
|
||||
if (BX_CPU_THIS_PTR lapic.INTR)
|
||||
vector = BX_CPU_THIS_PTR lapic.acknowledge_int();
|
||||
else
|
||||
#endif
|
||||
// if no local APIC, always acknowledge the PIC.
|
||||
vector = DEV_pic_iac(); // may set INTR with next interrupt
|
||||
|
||||
BX_CPU_THIS_PTR EXT = 1; /* external event */
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_Event(0, BX_EXTERNAL_INTERRUPT, vector, 0, 0);
|
||||
#endif
|
||||
|
||||
BX_INSTR_HWINTERRUPT(BX_CPU_ID, vector,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
interrupt(vector, BX_EXTERNAL_INTERRUPT, 0, 0);
|
||||
|
||||
BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP
|
||||
BX_CPU_THIS_PTR EXT = 0;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
void BX_CPU_C::VirtualInterruptAcknowledge(void)
|
||||
{
|
||||
Bit8u vector = SVM_V_INTR_VECTOR;
|
||||
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_VINTR)) Svm_Vmexit(SVM_VMEXIT_VINTR);
|
||||
|
||||
SVM_V_IRQ = 0;
|
||||
|
||||
BX_CPU_THIS_PTR EXT = 1; /* external event */
|
||||
|
||||
BX_INSTR_HWINTERRUPT(BX_CPU_ID, vector,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
interrupt(vector, BX_EXTERNAL_INTERRUPT, 0, 0);
|
||||
|
||||
BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP
|
||||
BX_CPU_THIS_PTR EXT = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
bx_bool BX_CPU_C::handleAsyncEvent(void)
|
||||
{
|
||||
//
|
||||
// This area is where we process special conditions and events.
|
||||
//
|
||||
if (BX_CPU_THIS_PTR activity_state != BX_ACTIVITY_STATE_ACTIVE) {
|
||||
// For one processor, pass the time as quickly as possible until
|
||||
// an interrupt wakes up the CPU.
|
||||
if (handleWaitForEvent()) return 1;
|
||||
}
|
||||
|
||||
if (bx_pc_system.kill_bochs_request) {
|
||||
@ -575,7 +651,7 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
#if BX_SUPPORT_SMP
|
||||
if (BX_SMP_PROCESSORS > 1) {
|
||||
// if HALT condition remains, return so other CPUs have a chance
|
||||
if (BX_CPU_THIS_PTR activity_state) {
|
||||
if (BX_CPU_THIS_PTR activity_state != BX_ACTIVITY_STATE_ACTIVE) {
|
||||
#if BX_DEBUGGER
|
||||
BX_CPU_THIS_PTR stop_reason = STOP_CPU_HALTED;
|
||||
#endif
|
||||
@ -641,39 +717,22 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
}
|
||||
#endif
|
||||
else if (BX_CPU_INTR && BX_DBG_ASYNC_INTR &&
|
||||
(BX_CPU_THIS_PTR get_IF()
|
||||
(interrupts_enabled()
|
||||
#if BX_SUPPORT_VMX
|
||||
|| (BX_CPU_THIS_PTR in_vmx_guest && PIN_VMEXIT(VMX_VM_EXEC_CTRL1_EXTERNAL_INTERRUPT_VMEXIT))
|
||||
#endif
|
||||
))
|
||||
{
|
||||
Bit8u vector;
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_ExtInterrupt();
|
||||
#endif
|
||||
// NOTE: similar code in ::take_irq()
|
||||
#if BX_SUPPORT_APIC
|
||||
if (BX_CPU_THIS_PTR lapic.INTR)
|
||||
vector = BX_CPU_THIS_PTR lapic.acknowledge_int();
|
||||
else
|
||||
#endif
|
||||
// if no local APIC, always acknowledge the PIC.
|
||||
vector = DEV_pic_iac(); // may set INTR with next interrupt
|
||||
BX_CPU_THIS_PTR EXT = 1; /* external event */
|
||||
#if BX_SUPPORT_VMX
|
||||
VMexit_Event(0, BX_EXTERNAL_INTERRUPT, vector, 0, 0);
|
||||
#endif
|
||||
BX_INSTR_HWINTERRUPT(BX_CPU_ID, vector,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
interrupt(vector, BX_EXTERNAL_INTERRUPT, 0, 0);
|
||||
// Set up environment, as would be when this main cpu loop gets
|
||||
// invoked. At the end of normal instructions, we always commmit
|
||||
// the new EIP. But here, we call interrupt() much like
|
||||
// it was a sofware interrupt instruction, and need to effect the
|
||||
// commit here. This code mirrors similar code above.
|
||||
BX_CPU_THIS_PTR prev_rip = RIP; // commit new RIP
|
||||
BX_CPU_THIS_PTR EXT = 0;
|
||||
InterruptAcknowledge();
|
||||
}
|
||||
#if BX_SUPPORT_SVM
|
||||
else if (BX_CPU_THIS_PTR in_svm_guest && SVM_V_IRQ && BX_CPU_THIS_PTR get_IF() &&
|
||||
(SVM_V_INTR_PRIO > SVM_V_TPR || SVM_V_IGNORE_TPR))
|
||||
{
|
||||
// virtual interrupt acknowledge
|
||||
VirtualInterruptAcknowledge();
|
||||
}
|
||||
#endif
|
||||
else if (BX_HRQ && BX_DBG_ASYNC_DMA) {
|
||||
// NOTE: similar code in ::take_dma()
|
||||
// assert Hold Acknowledge (HLDA) and go into a bus hold state
|
||||
@ -712,18 +771,22 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
// Alignment check
|
||||
// (handled by rest of the code)
|
||||
|
||||
if (!((BX_CPU_INTR && BX_CPU_THIS_PTR get_IF()) ||
|
||||
if (!((BX_CPU_INTR && interrupts_enabled()) ||
|
||||
BX_CPU_THIS_PTR debug_trap ||
|
||||
// BX_CPU_THIS_PTR get_TF() // implies debug_trap is set
|
||||
BX_HRQ
|
||||
#if BX_SUPPORT_VMX
|
||||
|| BX_CPU_THIS_PTR vmx_interrupt_window
|
||||
|| (! BX_CPU_THIS_PTR disable_NMI && BX_CPU_THIS_PTR in_vmx_guest &&
|
||||
|| (BX_CPU_THIS_PTR in_vmx_guest && ! BX_CPU_THIS_PTR disable_NMI &&
|
||||
VMEXIT(VMX_VM_EXEC_CTRL2_NMI_WINDOW_VMEXIT))
|
||||
#endif
|
||||
#if BX_SUPPORT_VMX >= 2
|
||||
|| BX_CPU_THIS_PTR pending_vmx_timer_expired
|
||||
#endif
|
||||
#if BX_SUPPORT_SVM
|
||||
|| (BX_CPU_THIS_PTR in_svm_guest && SVM_V_IRQ && BX_CPU_THIS_PTR get_IF() &&
|
||||
(SVM_V_INTR_PRIO > SVM_V_TPR || SVM_V_IGNORE_TPR))
|
||||
#endif
|
||||
#if BX_X86_DEBUGGER
|
||||
// a debug code breakpoint is set in current page
|
||||
|| BX_CPU_THIS_PTR codebp
|
||||
|
@ -1020,6 +1020,7 @@ public: // for now...
|
||||
bx_bool in_svm_guest;
|
||||
bx_bool svm_gif; /* global interrupt enable flag, when zero all external interrupt disabled */
|
||||
bx_phy_address vmcbptr;
|
||||
bx_hostpageaddr_t vmcbhostptr;
|
||||
VMCB_CACHE vmcb;
|
||||
#endif
|
||||
|
||||
@ -3536,7 +3537,10 @@ public: // for now...
|
||||
#if BX_SUPPORT_SMP
|
||||
BX_SMF void cpu_run_trace(void);
|
||||
#endif
|
||||
BX_SMF unsigned handleAsyncEvent(void);
|
||||
BX_SMF bx_bool handleAsyncEvent(void);
|
||||
BX_SMF bx_bool handleWaitForEvent(void);
|
||||
BX_SMF bx_bool interrupts_enabled(void);
|
||||
BX_SMF void InterruptAcknowledge(void);
|
||||
|
||||
BX_SMF int fetchDecode32(const Bit8u *fetchPtr, bxInstruction_c *i, unsigned remainingInPage) BX_CPP_AttrRegparmN(3);
|
||||
#if BX_SUPPORT_X86_64
|
||||
@ -4252,6 +4256,7 @@ public: // for now...
|
||||
BX_SMF bx_bool SvmEnterLoadCheckControls(SVM_CONTROLS *ctrls);
|
||||
BX_SMF bx_bool SvmEnterLoadCheckGuestState(void);
|
||||
BX_SMF void Svm_Vmexit(int reason);
|
||||
BX_SMF void SvmExitSaveGuestState(void);
|
||||
BX_SMF void SvmExitLoadHostState(SVM_HOST_STATE *host);
|
||||
BX_SMF Bit8u vmcb_read8(unsigned offset);
|
||||
BX_SMF Bit16u vmcb_read16(unsigned offset);
|
||||
@ -4268,6 +4273,7 @@ public: // for now...
|
||||
Bit16u errcode, bx_bool errcode_valid, Bit64u qualification = 0);
|
||||
BX_SMF void SvmInterceptIO(bxInstruction_c *i, unsigned port, unsigned len);
|
||||
BX_SMF void SvmInterceptMSR(unsigned op, Bit32u msr);
|
||||
BX_SMF void VirtualInterruptAcknowledge(void);
|
||||
BX_SMF void register_svm_state(bx_param_c *parent);
|
||||
#endif
|
||||
|
||||
|
@ -1017,7 +1017,7 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetCR0(bx_address val)
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if(SVM_CR_WRITE_INTERCEPTED(0)) Svm_Vmexit(SVM_VMEXIT_CR0_WRITE);
|
||||
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_CR0_WRITE_NO_TS_MP)) {
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_CR0_WRITE_NO_TS_MP)) {
|
||||
if ((oldCR0 & 0xfffffff5) != (val_32 & 0xfffffff5)) {
|
||||
// any other bit except TS or MP had changed
|
||||
Svm_Vmexit(SVM_VMEXIT_CR0_SEL_WRITE);
|
||||
@ -1302,6 +1302,12 @@ bx_bool BX_CPP_AttrRegparmN(1) BX_CPU_C::SetEFER(bx_address val_64)
|
||||
#if BX_CPU_LEVEL >= 6
|
||||
void BX_CPU_C::WriteCR8(bxInstruction_c *i, bx_address val)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_CR_WRITE_INTERCEPTED(8)) Svm_Vmexit(SVM_VMEXIT_CR8_READ);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
VMexit_CR8_Write(i);
|
||||
@ -1312,47 +1318,55 @@ void BX_CPU_C::WriteCR8(bxInstruction_c *i, bx_address val)
|
||||
// APIC.TPR[3:0] = 0
|
||||
// Reads of CR8 return zero extended APIC.TPR[7:4]
|
||||
// Write to CR8 update APIC.TPR[7:4]
|
||||
#if BX_SUPPORT_APIC
|
||||
if (val & BX_CONST64(0xfffffffffffffff0)) {
|
||||
BX_ERROR(("WriteCR8: Attempt to set reserved bits of CR8"));
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
unsigned tpr = (val & 0xf) << 4;
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
SVM_V_TPR = tpr;
|
||||
if (SVM_V_INTR_MASKING) return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX && BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW)) {
|
||||
VMX_Write_VTPR((val & 0xf) << 4);
|
||||
VMX_Write_VTPR(tpr);
|
||||
return;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
BX_CPU_THIS_PTR lapic.set_tpr((val & 0xf) << 4);
|
||||
}
|
||||
#endif // BX_SUPPORT_APIC
|
||||
|
||||
BX_CPU_THIS_PTR lapic.set_tpr(tpr);
|
||||
}
|
||||
|
||||
Bit32u BX_CPU_C::ReadCR8(bxInstruction_c *i)
|
||||
{
|
||||
Bit32u tpr = 0;
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_CR_WRITE_INTERCEPTED(8)) Svm_Vmexit(SVM_VMEXIT_CR8_READ);
|
||||
|
||||
if (SVM_V_INTR_MASKING) return SVM_V_TPR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX && BX_SUPPORT_X86_64
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
VMexit_CR8_Read(i);
|
||||
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && VMEXIT(VMX_VM_EXEC_CTRL2_TPR_SHADOW)) {
|
||||
tpr = (VMX_Read_VTPR() >> 4) & 0xf;
|
||||
Bit32u tpr = (VMX_Read_VTPR() >> 4) & 0xf;
|
||||
return tpr;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
// CR8 is aliased to APIC->TASK PRIORITY register
|
||||
// APIC.TPR[7:4] = CR8[3:0]
|
||||
// APIC.TPR[3:0] = 0
|
||||
// Reads of CR8 return zero extended APIC.TPR[7:4]
|
||||
// Write to CR8 update APIC.TPR[7:4]
|
||||
#if BX_SUPPORT_APIC
|
||||
tpr = (BX_CPU_THIS_PTR lapic.get_tpr() >> 4) & 0xf;
|
||||
#endif
|
||||
}
|
||||
|
||||
Bit32u tpr = (BX_CPU_THIS_PTR lapic.get_tpr() >> 4) & 0xf;
|
||||
return tpr;
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHF_Fw(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_PUSHF)) Svm_Vmexit(SVM_VMEXIT_PUSHF);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_PUSHF)) Svm_Vmexit(SVM_VMEXIT_PUSHF);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -207,7 +207,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPF_Fw(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_POPF)) Svm_Vmexit(SVM_VMEXIT_POPF);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_POPF)) Svm_Vmexit(SVM_VMEXIT_POPF);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -271,7 +271,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHF_Fd(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_PUSHF)) Svm_Vmexit(SVM_VMEXIT_PUSHF);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_PUSHF)) Svm_Vmexit(SVM_VMEXIT_PUSHF);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -290,7 +290,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPF_Fd(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_POPF)) Svm_Vmexit(SVM_VMEXIT_POPF);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_POPF)) Svm_Vmexit(SVM_VMEXIT_POPF);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -340,7 +340,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PUSHF_Fq(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_PUSHF)) Svm_Vmexit(SVM_VMEXIT_PUSHF);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_PUSHF)) Svm_Vmexit(SVM_VMEXIT_PUSHF);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -354,7 +354,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::POPF_Fq(bxInstruction_c *i)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_POPF)) Svm_Vmexit(SVM_VMEXIT_POPF);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_POPF)) Svm_Vmexit(SVM_VMEXIT_POPF);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -947,8 +947,16 @@ void bx_generic_cpuid_t::init_cpu_extensions_bitmask(void)
|
||||
if (xlarge_pages)
|
||||
features_bitmask |= BX_CPU_1G_PAGES;
|
||||
}
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
static unsigned svm_enabled = SIM->get_param_num(BXPN_CPUID_SVM)->get();
|
||||
if (svm_enabled) {
|
||||
features_bitmask |= BX_CPU_ALT_MOV_CR8; // auto-enable together with SVM
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BX_SUPPORT_X86_64
|
||||
|
||||
#endif // CPU_LEVEL >= 6
|
||||
|
||||
#endif // CPU_LEVEL >= 5
|
||||
|
@ -1114,6 +1114,8 @@ void BX_CPU_C::reset(unsigned source)
|
||||
#if BX_SUPPORT_SVM
|
||||
BX_CPU_THIS_PTR in_svm_guest = 0;
|
||||
BX_CPU_THIS_PTR svm_gif = 1;
|
||||
BX_CPU_THIS_PTR vmcbptr = 0;
|
||||
BX_CPU_THIS_PTR vmcbhostptr = 0;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX || BX_SUPPORT_SVM
|
||||
|
@ -886,8 +886,7 @@ bx_bool BX_CPP_AttrRegparmN(3) BX_CPU_C::allow_io(bxInstruction_c *i, Bit16u por
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_IO))
|
||||
SvmInterceptIO(i, port, len);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_IO)) SvmInterceptIO(i, port, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -351,7 +351,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDMSR(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_MSR)) SvmInterceptMSR(BX_READ, index);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_MSR)) SvmInterceptMSR(BX_READ, index);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -843,7 +843,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::WRMSR(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_MSR)) SvmInterceptMSR(BX_WRITE, index);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_MSR)) SvmInterceptMSR(BX_WRITE, index);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -480,7 +480,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INVLPG(bxInstruction_c* i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_INVLPG)) Svm_Vmexit(SVM_VMEXIT_INVLPG);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_INVLPG)) Svm_Vmexit(SVM_VMEXIT_INVLPG);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -50,7 +50,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PAUSE(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_PAUSE)) Svm_Vmexit(SVM_VMEXIT_PAUSE);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_PAUSE)) Svm_Vmexit(SVM_VMEXIT_PAUSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -80,7 +80,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CPUID(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_CPUID)) Svm_Vmexit(SVM_VMEXIT_CPUID);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_CPUID)) Svm_Vmexit(SVM_VMEXIT_CPUID);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -105,6 +105,12 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CPUID(bxInstruction_c *i)
|
||||
//
|
||||
void BX_CPU_C::shutdown(void)
|
||||
{
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_SHUTDOWN)) Svm_Vmexit(SVM_VMEXIT_SHUTDOWN);
|
||||
}
|
||||
#endif
|
||||
|
||||
BX_PANIC(("Entering to shutdown state still not implemented"));
|
||||
|
||||
BX_CPU_THIS_PTR clear_IF();
|
||||
@ -149,7 +155,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::HLT(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_HLT)) Svm_Vmexit(SVM_VMEXIT_HLT);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_HLT)) Svm_Vmexit(SVM_VMEXIT_HLT);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -197,7 +203,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INVD(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_INVD)) Svm_Vmexit(SVM_VMEXIT_INVD);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_INVD)) Svm_Vmexit(SVM_VMEXIT_INVD);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -227,7 +233,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::WBINVD(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_WBINVD)) Svm_Vmexit(SVM_VMEXIT_WBINVD);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_WBINVD)) Svm_Vmexit(SVM_VMEXIT_WBINVD);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -442,7 +448,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDPMC(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_RDPMC)) Svm_Vmexit(SVM_VMEXIT_RDPMC);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_RDPMC)) Svm_Vmexit(SVM_VMEXIT_RDPMC);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -513,7 +519,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSC(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest)
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_RDTSC)) Svm_Vmexit(SVM_VMEXIT_RDTSC);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_RDTSC)) Svm_Vmexit(SVM_VMEXIT_RDTSC);
|
||||
#endif
|
||||
|
||||
// return ticks
|
||||
@ -554,7 +560,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::RDTSCP(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest)
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_RDTSCP)) Svm_Vmexit(SVM_VMEXIT_RDTSCP);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_RDTSCP)) Svm_Vmexit(SVM_VMEXIT_RDTSCP);
|
||||
#endif
|
||||
|
||||
// return ticks
|
||||
@ -708,8 +714,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::MWAIT(bxInstruction_c *i)
|
||||
// When "interrupt window exiting" VMX control is set MWAIT instruction
|
||||
// won't cause the processor to enter BX_ACTIVITY_STATE_MWAIT_IF sleep
|
||||
// state with EFLAGS.IF = 0
|
||||
if (BX_CPU_THIS_PTR vmx_interrupt_window && ! BX_CPU_THIS_PTR get_IF())
|
||||
{
|
||||
if (BX_CPU_THIS_PTR vmx_interrupt_window && ! BX_CPU_THIS_PTR get_IF()) {
|
||||
BX_NEXT_TRACE(i);
|
||||
}
|
||||
#endif
|
||||
|
@ -730,7 +730,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SGDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_GDTR_READ)) Svm_Vmexit(SVM_VMEXIT_GDTR_READ);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_GDTR_READ)) Svm_Vmexit(SVM_VMEXIT_GDTR_READ);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -757,7 +757,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SIDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_IDTR_READ)) Svm_Vmexit(SVM_VMEXIT_IDTR_READ);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_IDTR_READ)) Svm_Vmexit(SVM_VMEXIT_IDTR_READ);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -790,7 +790,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LGDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_GDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_GDTR_WRITE);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_GDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_GDTR_WRITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -825,7 +825,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_IDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_IDTR_WRITE);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_IDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_IDTR_WRITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -856,7 +856,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SGDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_GDTR_READ)) Svm_Vmexit(SVM_VMEXIT_GDTR_READ);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_GDTR_READ)) Svm_Vmexit(SVM_VMEXIT_GDTR_READ);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -883,7 +883,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SIDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_IDTR_READ)) Svm_Vmexit(SVM_VMEXIT_IDTR_READ);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_IDTR_READ)) Svm_Vmexit(SVM_VMEXIT_IDTR_READ);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -915,7 +915,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LGDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_GDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_GDTR_WRITE);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_GDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_GDTR_WRITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -951,7 +951,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LIDT64_Ms(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_IDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_IDTR_WRITE);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_IDTR_WRITE)) Svm_Vmexit(SVM_VMEXIT_IDTR_WRITE);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -68,7 +68,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT1(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_ICEBP)) Svm_Vmexit(SVM_VMEXIT_ICEBP);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_ICEBP)) Svm_Vmexit(SVM_VMEXIT_ICEBP);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -127,7 +127,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INT_Ib(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_SOFTINT)) Svm_Vmexit(SVM_VMEXIT_SOFTWARE_INTERRUPT);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_SOFTINT)) Svm_Vmexit(SVM_VMEXIT_SOFTWARE_INTERRUPT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
196
bochs/cpu/svm.cc
196
bochs/cpu/svm.cc
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2012 Stanislav Shwartsman
|
||||
// Copyright (c) 2011-2012 Stanislav Shwartsman
|
||||
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
@ -43,18 +43,34 @@ BX_CPP_INLINE Bit64u CanonicalizeAddress(Bit64u laddr)
|
||||
|
||||
BX_CPP_INLINE Bit8u BX_CPU_C::vmcb_read8(unsigned offset)
|
||||
{
|
||||
Bit32u val_8;
|
||||
Bit8u val_8;
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit8u *hostAddr = (Bit8u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
val_8 = *hostAddr;
|
||||
}
|
||||
else {
|
||||
access_read_physical(pAddr, 1, (Bit8u*)(&val_8));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 1, BX_VMCS_ACCESS | BX_READ, (Bit8u*)(&val_8));
|
||||
return val_8;
|
||||
}
|
||||
|
||||
BX_CPP_INLINE Bit16u BX_CPU_C::vmcb_read16(unsigned offset)
|
||||
{
|
||||
Bit32u val_16;
|
||||
Bit16u val_16;
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit16u *hostAddr = (Bit16u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
ReadHostWordFromLittleEndian(hostAddr, val_16);
|
||||
}
|
||||
else {
|
||||
access_read_physical(pAddr, 2, (Bit8u*)(&val_16));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 2, BX_VMCS_ACCESS | BX_READ, (Bit8u*)(&val_16));
|
||||
return val_16;
|
||||
}
|
||||
@ -63,7 +79,15 @@ BX_CPP_INLINE Bit32u BX_CPU_C::vmcb_read32(unsigned offset)
|
||||
{
|
||||
Bit32u val_32;
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit32u *hostAddr = (Bit32u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
ReadHostDWordFromLittleEndian(hostAddr, val_32);
|
||||
}
|
||||
else {
|
||||
access_read_physical(pAddr, 4, (Bit8u*)(&val_32));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 4, BX_VMCS_ACCESS | BX_READ, (Bit8u*)(&val_32));
|
||||
return val_32;
|
||||
}
|
||||
@ -72,7 +96,15 @@ BX_CPP_INLINE Bit64u BX_CPU_C::vmcb_read64(unsigned offset)
|
||||
{
|
||||
Bit64u val_64;
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit64u *hostAddr = (Bit64u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
ReadHostQWordFromLittleEndian(hostAddr, val_64);
|
||||
}
|
||||
else {
|
||||
access_read_physical(pAddr, 8, (Bit8u*)(&val_64));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 8, BX_VMCS_ACCESS | BX_READ, (Bit8u*)(&val_64));
|
||||
return val_64;
|
||||
}
|
||||
@ -80,28 +112,64 @@ BX_CPP_INLINE Bit64u BX_CPU_C::vmcb_read64(unsigned offset)
|
||||
BX_CPP_INLINE void BX_CPU_C::vmcb_write8(unsigned offset, Bit8u val_8)
|
||||
{
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit8u *hostAddr = (Bit8u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 1);
|
||||
*hostAddr = val_8;
|
||||
}
|
||||
else {
|
||||
access_write_physical(pAddr, 1, (Bit8u*)(&val_8));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 1, BX_VMCS_ACCESS | BX_WRITE, (Bit8u*)(&val_8));
|
||||
}
|
||||
|
||||
BX_CPP_INLINE void BX_CPU_C::vmcb_write16(unsigned offset, Bit16u val_16)
|
||||
{
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit16u *hostAddr = (Bit16u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 2);
|
||||
WriteHostWordToLittleEndian(hostAddr, val_16);
|
||||
}
|
||||
else {
|
||||
access_write_physical(pAddr, 2, (Bit8u*)(&val_16));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 2, BX_VMCS_ACCESS | BX_WRITE, (Bit8u*)(&val_16));
|
||||
}
|
||||
|
||||
BX_CPP_INLINE void BX_CPU_C::vmcb_write32(unsigned offset, Bit32u val_32)
|
||||
{
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit32u *hostAddr = (Bit32u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 4);
|
||||
WriteHostDWordToLittleEndian(hostAddr, val_32);
|
||||
}
|
||||
else {
|
||||
access_write_physical(pAddr, 4, (Bit8u*)(&val_32));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 4, BX_VMCS_ACCESS | BX_WRITE, (Bit8u*)(&val_32));
|
||||
}
|
||||
|
||||
BX_CPP_INLINE void BX_CPU_C::vmcb_write64(unsigned offset, Bit64u val_64)
|
||||
{
|
||||
bx_phy_address pAddr = BX_CPU_THIS_PTR vmcbptr + offset;
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcbhostptr) {
|
||||
Bit64u *hostAddr = (Bit64u*) (BX_CPU_THIS_PTR vmcbhostptr | offset);
|
||||
pageWriteStampTable.decWriteStamp(pAddr, 8);
|
||||
WriteHostQWordToLittleEndian(hostAddr, val_64);
|
||||
}
|
||||
else {
|
||||
access_write_physical(pAddr, 8, (Bit8u*)(&val_64));
|
||||
}
|
||||
|
||||
BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, pAddr, 8, BX_VMCS_ACCESS | BX_WRITE, (Bit8u*)(&val_64));
|
||||
}
|
||||
|
||||
@ -197,6 +265,41 @@ void BX_CPU_C::SvmExitLoadHostState(SVM_HOST_STATE *host)
|
||||
BX_INSTR_TLB_CNTRL(BX_CPU_ID, BX_INSTR_CONTEXT_SWITCH, 0);
|
||||
}
|
||||
|
||||
void BX_CPU_C::SvmExitSaveGuestState(void)
|
||||
{
|
||||
for (unsigned n=0;n < 4; n++) {
|
||||
svm_segment_write(&BX_CPU_THIS_PTR sregs[n], SVM_GUEST_ES_SELECTOR + n * 0x10);
|
||||
}
|
||||
|
||||
vmcb_write64(SVM_GUEST_GDTR_BASE, BX_CPU_THIS_PTR gdtr.base);
|
||||
vmcb_write16(SVM_GUEST_GDTR_LIMIT, BX_CPU_THIS_PTR gdtr.limit);
|
||||
|
||||
vmcb_write64(SVM_GUEST_IDTR_BASE, BX_CPU_THIS_PTR idtr.base);
|
||||
vmcb_write16(SVM_GUEST_IDTR_LIMIT, BX_CPU_THIS_PTR idtr.limit);
|
||||
|
||||
vmcb_write64(SVM_GUEST_EFER_MSR, BX_CPU_THIS_PTR efer.get32());
|
||||
vmcb_write64(SVM_GUEST_CR0, BX_CPU_THIS_PTR cr0.get32());
|
||||
vmcb_write64(SVM_GUEST_CR2, BX_CPU_THIS_PTR cr2);
|
||||
vmcb_write64(SVM_GUEST_CR3, BX_CPU_THIS_PTR cr3);
|
||||
vmcb_write64(SVM_GUEST_CR4, BX_CPU_THIS_PTR cr4.get32());
|
||||
|
||||
vmcb_write64(SVM_GUEST_DR6, BX_CPU_THIS_PTR dr6.get32());
|
||||
vmcb_write64(SVM_GUEST_DR7, BX_CPU_THIS_PTR dr7.get32());
|
||||
|
||||
vmcb_write64(SVM_GUEST_RAX, RAX);
|
||||
vmcb_write64(SVM_GUEST_RSP, RSP);
|
||||
vmcb_write64(SVM_GUEST_RIP, RIP);
|
||||
|
||||
vmcb_write8(SVM_GUEST_CPL, CPL);
|
||||
|
||||
vmcb_write8(SVM_CONTROL_INTERRUPT_SHADOW, interrupts_inhibited(BX_INHIBIT_INTERRUPTS));
|
||||
|
||||
SVM_CONTROLS *ctrls = &BX_CPU_THIS_PTR vmcb.ctrls;
|
||||
|
||||
vmcb_write8(SVM_CONTROL_VTPR, ctrls->v_tpr);
|
||||
vmcb_write8(SVM_CONTROL_VIRQ, ctrls->v_irq);
|
||||
}
|
||||
|
||||
bx_bool BX_CPU_C::SvmEnterLoadCheckControls(SVM_CONTROLS *ctrls)
|
||||
{
|
||||
ctrls->cr_rd_ctrl = vmcb_read16(SVM_CONTROL_INTERCEPT_CR_READ);
|
||||
@ -208,7 +311,7 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckControls(SVM_CONTROLS *ctrls)
|
||||
ctrls->intercept_vector[0] = vmcb_read32(SVM_CONTROL_INTERCEPT1);
|
||||
ctrls->intercept_vector[1] = vmcb_read32(SVM_CONTROL_INTERCEPT2);
|
||||
|
||||
if (! SVM_INTERCEPT(1, SVM_INTERCEPT1_VMRUN)) {
|
||||
if (! SVM_INTERCEPT(SVM_INTERCEPT1_VMRUN)) {
|
||||
BX_ERROR(("VMRUN: VMRUN intercept bit is not set!"));
|
||||
return 0;
|
||||
}
|
||||
@ -229,14 +332,14 @@ bx_bool BX_CPU_C::SvmEnterLoadCheckControls(SVM_CONTROLS *ctrls)
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bit64u interrupt_control = vmcb_read32(SVM_CONTROL_VINTERRUPT_CONTROL);
|
||||
ctrls->v_tpr = vmcb_read8(SVM_CONTROL_VTPR);
|
||||
ctrls->v_irq = vmcb_read8(SVM_CONTROL_VIRQ) & 0x1;
|
||||
ctrls->v_intr_masking = vmcb_read8(SVM_CONTROL_VINTR_MASKING) & 0x1;
|
||||
ctrls->v_intr_vector = vmcb_read8(SVM_CONTROL_VINTR_VECTOR);
|
||||
|
||||
ctrls->v_tpr = (interrupt_control & 0xff);
|
||||
ctrls->v_irq = (interrupt_control >> 8) & 0x1;
|
||||
ctrls->v_intr_prio = (interrupt_control >> 16) & 0xf;
|
||||
ctrls->v_ignore_tpr = (interrupt_control >> 20) & 0x1;
|
||||
ctrls->v_intr_masking = (interrupt_control >> 24) & 0x1;
|
||||
ctrls->v_intr_vector = vmcb_read8(SVM_CONTROL_VINTERRUPT_VECTOR);
|
||||
Bit8u vintr_control = vmcb_read8(SVM_CONTROL_VINTR_PRIO_IGN_TPR);
|
||||
ctrls->v_intr_prio = vintr_control & 0xf;
|
||||
ctrls->v_ignore_tpr = (vintr_control >> 4) & 0x1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -436,11 +539,13 @@ void BX_CPU_C::Svm_Vmexit(int reason)
|
||||
// STEP 0: Update exit reason
|
||||
//
|
||||
|
||||
SVM_CONTROLS *ctrls = &BX_CPU_THIS_PTR vmcb.ctrls;
|
||||
|
||||
vmcb_write64(SVM_CONTROL_EXITCODE, (Bit64u) ((Bit64s) reason));
|
||||
|
||||
if (BX_CPU_THIS_PTR in_event) {
|
||||
vmcb_write32(SVM_CONTROL_EXITINTINFO, BX_CPU_THIS_PTR vmcb.ctrls.exitintinfo | 0x80000000);
|
||||
vmcb_write32(SVM_CONTROL_EXITINTINFO_ERROR_CODE, BX_CPU_THIS_PTR vmcb.ctrls.exitintinfo_error_code);
|
||||
vmcb_write32(SVM_CONTROL_EXITINTINFO, ctrls->exitintinfo | 0x80000000);
|
||||
vmcb_write32(SVM_CONTROL_EXITINTINFO_ERROR_CODE, ctrls->exitintinfo_error_code);
|
||||
BX_CPU_THIS_PTR in_event = 0;
|
||||
}
|
||||
else {
|
||||
@ -450,34 +555,7 @@ void BX_CPU_C::Svm_Vmexit(int reason)
|
||||
//
|
||||
// Step 1: Save guest state in the VMCB
|
||||
//
|
||||
for (unsigned n=0;n < 4; n++) {
|
||||
svm_segment_write(&BX_CPU_THIS_PTR sregs[n], SVM_GUEST_ES_SELECTOR + n * 0x10);
|
||||
}
|
||||
|
||||
vmcb_write64(SVM_GUEST_GDTR_BASE, BX_CPU_THIS_PTR gdtr.base);
|
||||
vmcb_write16(SVM_GUEST_GDTR_LIMIT, BX_CPU_THIS_PTR gdtr.limit);
|
||||
|
||||
vmcb_write64(SVM_GUEST_IDTR_BASE, BX_CPU_THIS_PTR idtr.base);
|
||||
vmcb_write16(SVM_GUEST_IDTR_LIMIT, BX_CPU_THIS_PTR idtr.limit);
|
||||
|
||||
vmcb_write64(SVM_GUEST_EFER_MSR, BX_CPU_THIS_PTR efer.get32());
|
||||
vmcb_write64(SVM_GUEST_CR0, BX_CPU_THIS_PTR cr0.get32());
|
||||
vmcb_write64(SVM_GUEST_CR2, BX_CPU_THIS_PTR cr2);
|
||||
vmcb_write64(SVM_GUEST_CR3, BX_CPU_THIS_PTR cr3);
|
||||
vmcb_write64(SVM_GUEST_CR4, BX_CPU_THIS_PTR cr4.get32());
|
||||
|
||||
vmcb_write64(SVM_GUEST_DR6, BX_CPU_THIS_PTR dr6.get32());
|
||||
vmcb_write64(SVM_GUEST_DR7, BX_CPU_THIS_PTR dr7.get32());
|
||||
|
||||
vmcb_write64(SVM_GUEST_RAX, RAX);
|
||||
vmcb_write64(SVM_GUEST_RSP, RSP);
|
||||
vmcb_write64(SVM_GUEST_RIP, RIP);
|
||||
|
||||
vmcb_write8(SVM_GUEST_CPL, CPL);
|
||||
|
||||
if (interrupts_inhibited(BX_INHIBIT_INTERRUPTS)) {
|
||||
vmcb_write8(SVM_CONTROL_INTERRUPT_SHADOW, 0x01);
|
||||
}
|
||||
SvmExitSaveGuestState();
|
||||
|
||||
//
|
||||
// Step 2:
|
||||
@ -540,8 +618,10 @@ void BX_CPU_C::SvmInjectEvents(void)
|
||||
BX_CPU_THIS_PTR errorno = 1;
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR vmcb.ctrls.exitintinfo = injecting_event & ~0x80000000;
|
||||
BX_CPU_THIS_PTR vmcb.ctrls.exitintinfo_error_code = error_code;
|
||||
SVM_CONTROLS *ctrls = &BX_CPU_THIS_PTR vmcb.ctrls;
|
||||
|
||||
ctrls->exitintinfo = injecting_event & ~0x80000000;
|
||||
ctrls->exitintinfo_error_code = error_code;
|
||||
|
||||
RSP_SPECULATIVE;
|
||||
|
||||
@ -568,6 +648,8 @@ void BX_CPU_C::SvmInterceptException(unsigned type, unsigned vector, Bit16u errc
|
||||
|
||||
BX_ASSERT(vector < 32);
|
||||
|
||||
SVM_CONTROLS *ctrls = &BX_CPU_THIS_PTR vmcb.ctrls;
|
||||
|
||||
if (! SVM_EXCEPTION_INTERCEPTED(vector)) {
|
||||
|
||||
// -----------------------------------------
|
||||
@ -581,8 +663,8 @@ void BX_CPU_C::SvmInterceptException(unsigned type, unsigned vector, Bit16u errc
|
||||
//
|
||||
|
||||
// record IDT vectoring information
|
||||
BX_CPU_THIS_PTR vmcb.ctrls.exitintinfo_error_code = errcode;
|
||||
BX_CPU_THIS_PTR vmcb.ctrls.exitintinfo = vector | (type << 8);
|
||||
ctrls->exitintinfo_error_code = errcode;
|
||||
ctrls->exitintinfo = vector | (type << 8);
|
||||
if (errcode_valid)
|
||||
BX_CPU_THIS_PTR vmcb.ctrls.exitintinfo |= (1 << 11); // error code delivered
|
||||
return;
|
||||
@ -621,7 +703,7 @@ void BX_CPU_C::SvmInterceptIO(bxInstruction_c *i, unsigned port, unsigned len)
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR in_svm_guest) return;
|
||||
|
||||
if (! SVM_INTERCEPT(0, SVM_INTERCEPT0_IO)) return;
|
||||
if (! SVM_INTERCEPT(SVM_INTERCEPT0_IO)) return;
|
||||
|
||||
Bit8u bitmap[2];
|
||||
bx_phy_address pAddr;
|
||||
@ -701,7 +783,7 @@ void BX_CPU_C::SvmInterceptMSR(unsigned op, Bit32u msr)
|
||||
{
|
||||
if (! BX_CPU_THIS_PTR in_svm_guest) return;
|
||||
|
||||
if (! SVM_INTERCEPT(0, SVM_INTERCEPT0_MSR)) return;
|
||||
if (! SVM_INTERCEPT(SVM_INTERCEPT0_MSR)) return;
|
||||
|
||||
BX_ASSERT(op == BX_READ || op == BX_WRITE);
|
||||
|
||||
@ -728,6 +810,7 @@ void BX_CPU_C::SvmInterceptMSR(unsigned op, Bit32u msr)
|
||||
Svm_Vmexit(SVM_VMEXIT_MSR);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMRUN(bxInstruction_c *i)
|
||||
@ -741,7 +824,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMRUN(bxInstruction_c *i)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_VMRUN))
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_VMRUN))
|
||||
Svm_Vmexit(SVM_VMEXIT_VMRUN);
|
||||
|
||||
bx_address pAddr = RAX & i->asize_mask();
|
||||
@ -750,6 +833,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMRUN(bxInstruction_c *i)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
BX_CPU_THIS_PTR vmcbptr = pAddr;
|
||||
BX_CPU_THIS_PTR vmcbhostptr = BX_CPU_THIS_PTR getHostMemAddr(pAddr, BX_WRITE);
|
||||
|
||||
//
|
||||
// Step 1: Save host state to physical memory indicated in SVM_HSAVE_PHY_ADDR_MSR
|
||||
@ -782,7 +866,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMMCALL(bxInstruction_c *i)
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR efer.get_SVME()) {
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_VMMCALL)) Svm_Vmexit(SVM_VMEXIT_VMMCALL);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_VMMCALL)) Svm_Vmexit(SVM_VMEXIT_VMMCALL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -804,7 +888,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMLOAD(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_VMLOAD)) Svm_Vmexit(SVM_VMEXIT_VMLOAD);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_VMLOAD)) Svm_Vmexit(SVM_VMEXIT_VMLOAD);
|
||||
}
|
||||
|
||||
bx_address pAddr = RAX & i->asize_mask();
|
||||
@ -813,6 +897,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMLOAD(bxInstruction_c *i)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
BX_CPU_THIS_PTR vmcbptr = pAddr;
|
||||
BX_CPU_THIS_PTR vmcbhostptr = BX_CPU_THIS_PTR getHostMemAddr(pAddr, BX_WRITE);
|
||||
|
||||
bx_segment_reg_t fs, gs, guest_tr, guest_ldtr;
|
||||
|
||||
@ -852,7 +937,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMSAVE(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_VMSAVE)) Svm_Vmexit(SVM_VMEXIT_VMSAVE);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_VMSAVE)) Svm_Vmexit(SVM_VMEXIT_VMSAVE);
|
||||
}
|
||||
|
||||
bx_address pAddr = RAX & i->asize_mask();
|
||||
@ -861,6 +946,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMSAVE(bxInstruction_c *i)
|
||||
exception(BX_GP_EXCEPTION, 0);
|
||||
}
|
||||
BX_CPU_THIS_PTR vmcbptr = pAddr;
|
||||
BX_CPU_THIS_PTR vmcbhostptr = BX_CPU_THIS_PTR getHostMemAddr(pAddr, BX_WRITE);
|
||||
|
||||
svm_segment_write(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS], SVM_GUEST_FS_SELECTOR);
|
||||
svm_segment_write(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS], SVM_GUEST_GS_SELECTOR);
|
||||
@ -893,7 +979,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::SKINIT(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_SKINIT)) Svm_Vmexit(SVM_VMEXIT_SKINIT);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_SKINIT)) Svm_Vmexit(SVM_VMEXIT_SKINIT);
|
||||
}
|
||||
|
||||
BX_PANIC(("SVM: SKINIT is not implemented yet"));
|
||||
@ -914,7 +1000,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::CLGI(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_CLGI)) Svm_Vmexit(SVM_VMEXIT_CLGI);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_CLGI)) Svm_Vmexit(SVM_VMEXIT_CLGI);
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR svm_gif = 0;
|
||||
@ -936,7 +1022,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::STGI(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_STGI)) Svm_Vmexit(SVM_VMEXIT_STGI);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_STGI)) Svm_Vmexit(SVM_VMEXIT_STGI);
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR svm_gif = 1;
|
||||
@ -958,7 +1044,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::INVLPGA(bxInstruction_c *i)
|
||||
}
|
||||
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(0, SVM_INTERCEPT0_INVLPGA)) Svm_Vmexit(SVM_VMEXIT_INVLPGA);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT0_INVLPGA)) Svm_Vmexit(SVM_VMEXIT_INVLPGA);
|
||||
}
|
||||
|
||||
TLB_flush();
|
||||
|
122
bochs/cpu/svm.h
122
bochs/cpu/svm.h
@ -2,7 +2,7 @@
|
||||
// $Id$
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (c) 2012 Stanislav Shwartsman
|
||||
// Copyright (c) 2011-2012 Stanislav Shwartsman
|
||||
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
@ -24,6 +24,8 @@
|
||||
#ifndef _BX_SVM_AMD_H_
|
||||
#define _BX_SVM_AMD_H_
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
|
||||
enum SVM_intercept_codes {
|
||||
SVM_VMEXIT_CR0_READ = 0,
|
||||
SVM_VMEXIT_CR2_READ = 2,
|
||||
@ -106,8 +108,11 @@ enum SVM_intercept_codes {
|
||||
#define SVM_CONTROL_TSC_OFFSET (0x050)
|
||||
#define SVM_CONTROL_GUEST_ASID (0x058)
|
||||
#define SVM_CONTROL_TLB_CONTROL (0x05c)
|
||||
#define SVM_CONTROL_VINTERRUPT_CONTROL (0x060) /* VTPR, VIRQ, V_INTR_PRIO, VINTR_MASKING and etc */
|
||||
#define SVM_CONTROL_VINTERRUPT_VECTOR (0x064)
|
||||
#define SVM_CONTROL_VTPR (0x060)
|
||||
#define SVM_CONTROL_VIRQ (0x061)
|
||||
#define SVM_CONTROL_VINTR_PRIO_IGN_TPR (0x062)
|
||||
#define SVM_CONTROL_VINTR_MASKING (0x063)
|
||||
#define SVM_CONTROL_VINTR_VECTOR (0x064)
|
||||
#define SVM_CONTROL_INTERRUPT_SHADOW (0x068)
|
||||
#define SVM_CONTROL_EXITCODE (0x070)
|
||||
#define SVM_CONTROL_EXITINFO1 (0x078)
|
||||
@ -277,6 +282,19 @@ typedef struct bx_SVM_CONTROLS
|
||||
|
||||
} SVM_CONTROLS;
|
||||
|
||||
#if defined(NEED_CPU_REG_SHORTCUTS)
|
||||
|
||||
#define SVM_V_TPR (BX_CPU_THIS_PTR vmcb.ctrls.v_tpr)
|
||||
#define SVM_V_IRQ (BX_CPU_THIS_PTR vmcb.ctrls.v_irq)
|
||||
#define SVM_V_INTR_PRIO (BX_CPU_THIS_PTR vmcb.ctrls.v_intr_prio)
|
||||
#define SVM_V_IGNORE_TPR (BX_CPU_THIS_PTR vmcb.ctrls.v_ignore_tpr)
|
||||
#define SVM_V_INTR_MASKING (BX_CPU_THIS_PTR vmcb.ctrls.v_intr_masking)
|
||||
#define SVM_V_INTR_VECTOR (BX_CPU_THIS_PTR vmcb.ctrls.v_intr_vector)
|
||||
|
||||
#define SVM_HOST_IF (BX_CPU_THIS_PTR vmcb.host_state.eflags & EFlagsIFMask)
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct bx_VMCB_CACHE
|
||||
{
|
||||
SVM_HOST_STATE host_state;
|
||||
@ -287,56 +305,56 @@ typedef struct bx_VMCB_CACHE
|
||||
// SVM intercept controls
|
||||
// ========================
|
||||
|
||||
#define SVM_INTERCEPT0_INTR (1 << 0)
|
||||
#define SVM_INTERCEPT0_NMI (1 << 1)
|
||||
#define SVM_INTERCEPT0_SMI (1 << 2)
|
||||
#define SVM_INTERCEPT0_INIT (1 << 3)
|
||||
#define SVM_INTERCEPT0_VINTR (1 << 4)
|
||||
#define SVM_INTERCEPT0_CR0_WRITE_NO_TS_MP (1 << 5)
|
||||
#define SVM_INTERCEPT0_IDTR_READ (1 << 6)
|
||||
#define SVM_INTERCEPT0_GDTR_READ (1 << 7)
|
||||
#define SVM_INTERCEPT0_LDTR_READ (1 << 8)
|
||||
#define SVM_INTERCEPT0_TR_READ (1 << 9)
|
||||
#define SVM_INTERCEPT0_IDTR_WRITE (1 << 10)
|
||||
#define SVM_INTERCEPT0_GDTR_WRITE (1 << 11)
|
||||
#define SVM_INTERCEPT0_LDTR_WRITE (1 << 12)
|
||||
#define SVM_INTERCEPT0_TR_WRITE (1 << 13)
|
||||
#define SVM_INTERCEPT0_RDTSC (1 << 14)
|
||||
#define SVM_INTERCEPT0_RDPMC (1 << 15)
|
||||
#define SVM_INTERCEPT0_PUSHF (1 << 16)
|
||||
#define SVM_INTERCEPT0_POPF (1 << 17)
|
||||
#define SVM_INTERCEPT0_CPUID (1 << 18)
|
||||
#define SVM_INTERCEPT0_RSM (1 << 19)
|
||||
#define SVM_INTERCEPT0_IRET (1 << 20)
|
||||
#define SVM_INTERCEPT0_SOFTINT (1 << 21)
|
||||
#define SVM_INTERCEPT0_INVD (1 << 22)
|
||||
#define SVM_INTERCEPT0_PAUSE (1 << 23)
|
||||
#define SVM_INTERCEPT0_HLT (1 << 24)
|
||||
#define SVM_INTERCEPT0_INVLPG (1 << 25)
|
||||
#define SVM_INTERCEPT0_INVLPGA (1 << 26)
|
||||
#define SVM_INTERCEPT0_IO (1 << 27)
|
||||
#define SVM_INTERCEPT0_MSR (1 << 28)
|
||||
#define SVM_INTERCEPT0_TASK_SWITCH (1 << 29)
|
||||
#define SVM_INTERCEPT0_FERR_FREEZE (1 << 30)
|
||||
#define SVM_INTERCEPT0_SHUTDOWN (1 << 31)
|
||||
#define SVM_INTERCEPT0_INTR (0)
|
||||
#define SVM_INTERCEPT0_NMI (1)
|
||||
#define SVM_INTERCEPT0_SMI (2)
|
||||
#define SVM_INTERCEPT0_INIT (3)
|
||||
#define SVM_INTERCEPT0_VINTR (4)
|
||||
#define SVM_INTERCEPT0_CR0_WRITE_NO_TS_MP (5)
|
||||
#define SVM_INTERCEPT0_IDTR_READ (6)
|
||||
#define SVM_INTERCEPT0_GDTR_READ (7)
|
||||
#define SVM_INTERCEPT0_LDTR_READ (8)
|
||||
#define SVM_INTERCEPT0_TR_READ (9)
|
||||
#define SVM_INTERCEPT0_IDTR_WRITE (10)
|
||||
#define SVM_INTERCEPT0_GDTR_WRITE (11)
|
||||
#define SVM_INTERCEPT0_LDTR_WRITE (12)
|
||||
#define SVM_INTERCEPT0_TR_WRITE (13)
|
||||
#define SVM_INTERCEPT0_RDTSC (14)
|
||||
#define SVM_INTERCEPT0_RDPMC (15)
|
||||
#define SVM_INTERCEPT0_PUSHF (16)
|
||||
#define SVM_INTERCEPT0_POPF (17)
|
||||
#define SVM_INTERCEPT0_CPUID (18)
|
||||
#define SVM_INTERCEPT0_RSM (19)
|
||||
#define SVM_INTERCEPT0_IRET (20)
|
||||
#define SVM_INTERCEPT0_SOFTINT (21)
|
||||
#define SVM_INTERCEPT0_INVD (22)
|
||||
#define SVM_INTERCEPT0_PAUSE (23)
|
||||
#define SVM_INTERCEPT0_HLT (24)
|
||||
#define SVM_INTERCEPT0_INVLPG (25)
|
||||
#define SVM_INTERCEPT0_INVLPGA (26)
|
||||
#define SVM_INTERCEPT0_IO (27)
|
||||
#define SVM_INTERCEPT0_MSR (28)
|
||||
#define SVM_INTERCEPT0_TASK_SWITCH (29)
|
||||
#define SVM_INTERCEPT0_FERR_FREEZE (30)
|
||||
#define SVM_INTERCEPT0_SHUTDOWN (31)
|
||||
|
||||
#define SVM_INTERCEPT1_VMRUN (1 << 0)
|
||||
#define SVM_INTERCEPT1_VMMCALL (1 << 1)
|
||||
#define SVM_INTERCEPT1_VMLOAD (1 << 2)
|
||||
#define SVM_INTERCEPT1_VMSAVE (1 << 3)
|
||||
#define SVM_INTERCEPT1_STGI (1 << 4)
|
||||
#define SVM_INTERCEPT1_CLGI (1 << 5)
|
||||
#define SVM_INTERCEPT1_SKINIT (1 << 6)
|
||||
#define SVM_INTERCEPT1_RDTSCP (1 << 7)
|
||||
#define SVM_INTERCEPT1_ICEBP (1 << 8)
|
||||
#define SVM_INTERCEPT1_WBINVD (1 << 9)
|
||||
#define SVM_INTERCEPT1_MONITOR (1 << 10)
|
||||
#define SVM_INTERCEPT1_MWAIT (1 << 11)
|
||||
#define SVM_INTERCEPT1_MWAIT_ARMED (1 << 12)
|
||||
#define SVM_INTERCEPT1_XSETBV (1 << 13)
|
||||
#define SVM_INTERCEPT1_VMRUN (32)
|
||||
#define SVM_INTERCEPT1_VMMCALL (33)
|
||||
#define SVM_INTERCEPT1_VMLOAD (34)
|
||||
#define SVM_INTERCEPT1_VMSAVE (35)
|
||||
#define SVM_INTERCEPT1_STGI (36)
|
||||
#define SVM_INTERCEPT1_CLGI (37)
|
||||
#define SVM_INTERCEPT1_SKINIT (38)
|
||||
#define SVM_INTERCEPT1_RDTSCP (39)
|
||||
#define SVM_INTERCEPT1_ICEBP (40)
|
||||
#define SVM_INTERCEPT1_WBINVD (41)
|
||||
#define SVM_INTERCEPT1_MONITOR (42)
|
||||
#define SVM_INTERCEPT1_MWAIT (43)
|
||||
#define SVM_INTERCEPT1_MWAIT_ARMED (44)
|
||||
#define SVM_INTERCEPT1_XSETBV (45)
|
||||
|
||||
#define SVM_INTERCEPT(vector, intercept_bit) \
|
||||
(BX_CPU_THIS_PTR vmcb.ctrls.intercept_vector[vector] & (intercept_bit))
|
||||
#define SVM_INTERCEPT(intercept_bitnum) \
|
||||
(BX_CPU_THIS_PTR vmcb.ctrls.intercept_vector[intercept_bitnum / 32] & (1 << (intercept_bitnum & 31)))
|
||||
|
||||
#define SVM_EXCEPTION_INTERCEPTED(vector) \
|
||||
(BX_CPU_THIS_PTR vmcb.ctrls.exceptions_intercept & (1<<(vector)))
|
||||
@ -353,4 +371,6 @@ typedef struct bx_VMCB_CACHE
|
||||
#define SVM_DR_WRITE_INTERCEPTED(reg_num) \
|
||||
(BX_CPU_THIS_PTR vmcb.ctrls.dr_wr_ctrl & (1<<(reg_num)))
|
||||
|
||||
#endif // BX_SUPPORT_SVM
|
||||
|
||||
#endif // _BX_SVM_AMD_H_
|
||||
|
@ -65,7 +65,7 @@ Bit16u BX_CPP_AttrRegparmN(1) BX_CPU_C::VMread16(unsigned encoding)
|
||||
|
||||
if (BX_CPU_THIS_PTR vmcshostptr) {
|
||||
Bit16u *hostAddr = (Bit16u*) (BX_CPU_THIS_PTR vmcshostptr | offset);
|
||||
ReadHostDWordFromLittleEndian(hostAddr, field);
|
||||
ReadHostWordFromLittleEndian(hostAddr, field);
|
||||
}
|
||||
else {
|
||||
access_read_physical(pAddr, 2, (Bit8u*)(&field));
|
||||
|
@ -409,7 +409,7 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::XSETBV(bxInstruction_c *i)
|
||||
|
||||
#if BX_SUPPORT_SVM
|
||||
if (BX_CPU_THIS_PTR in_svm_guest) {
|
||||
if (SVM_INTERCEPT(1, SVM_INTERCEPT1_XSETBV)) Svm_Vmexit(SVM_VMEXIT_XSETBV);
|
||||
if (SVM_INTERCEPT(SVM_INTERCEPT1_XSETBV)) Svm_Vmexit(SVM_VMEXIT_XSETBV);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user