correctly signal bit 12 (nmi unblocking by iret) in vmx interruption info. todo: find how to implement it clean way
This commit is contained in:
parent
1a770dd260
commit
53d14c01b5
@ -1092,6 +1092,10 @@ public: // for now...
|
||||
bx_bool in_event;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
bx_bool nmi_unblocking_iret;
|
||||
#endif
|
||||
|
||||
bx_bool EXT; /* 1 if processing external interrupt or exception
|
||||
* or if not related to current instruction,
|
||||
* 0 if current CS:IP caused exception */
|
||||
|
@ -551,6 +551,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET16(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (is_masked_event(PIN_VMEXIT(VMX_VM_EXEC_CTRL1_VIRTUAL_NMI) ? BX_EVENT_VMX_VIRTUAL_NMI : BX_EVENT_NMI))
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 1;
|
||||
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && PIN_VMEXIT(VMX_VM_EXEC_CTRL1_NMI_EXITING)) {
|
||||
if (PIN_VMEXIT(VMX_VM_EXEC_CTRL1_VIRTUAL_NMI)) unmask_event(BX_EVENT_VMX_VIRTUAL_NMI);
|
||||
}
|
||||
@ -593,6 +597,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET16(bxInstruction_c *i)
|
||||
|
||||
done:
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 0;
|
||||
#endif
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
|
||||
|
@ -594,6 +594,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET32(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (is_masked_event(PIN_VMEXIT(VMX_VM_EXEC_CTRL1_VIRTUAL_NMI) ? BX_EVENT_VMX_VIRTUAL_NMI : BX_EVENT_NMI))
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 1;
|
||||
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && PIN_VMEXIT(VMX_VM_EXEC_CTRL1_NMI_EXITING)) {
|
||||
if (PIN_VMEXIT(VMX_VM_EXEC_CTRL1_VIRTUAL_NMI)) unmask_event(BX_EVENT_VMX_VIRTUAL_NMI);
|
||||
}
|
||||
@ -636,6 +640,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET32(bxInstruction_c *i)
|
||||
|
||||
done:
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 0;
|
||||
#endif
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, EIP);
|
||||
|
||||
|
@ -433,6 +433,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET64(bxInstruction_c *i)
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest)
|
||||
if (is_masked_event(PIN_VMEXIT(VMX_VM_EXEC_CTRL1_VIRTUAL_NMI) ? BX_EVENT_VMX_VIRTUAL_NMI : BX_EVENT_NMI))
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 1;
|
||||
|
||||
if (BX_CPU_THIS_PTR in_vmx_guest && PIN_VMEXIT(VMX_VM_EXEC_CTRL1_NMI_EXITING)) {
|
||||
if (PIN_VMEXIT(VMX_VM_EXEC_CTRL1_VIRTUAL_NMI)) unmask_event(BX_EVENT_VMX_VIRTUAL_NMI);
|
||||
}
|
||||
@ -448,6 +452,10 @@ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::IRET64(bxInstruction_c *i)
|
||||
|
||||
long_iret(i);
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 0;
|
||||
#endif
|
||||
|
||||
BX_INSTR_FAR_BRANCH(BX_CPU_ID, BX_INSTR_IS_IRET,
|
||||
BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector.value, RIP);
|
||||
|
||||
|
@ -381,7 +381,6 @@ void BX_CPU_C::deliver_SIPI(unsigned vector)
|
||||
BX_CPU_THIS_PTR activity_state = BX_ACTIVITY_STATE_ACTIVE;
|
||||
RIP = 0;
|
||||
load_seg_reg(&BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS], vector*0x100);
|
||||
unmask_event(BX_EVENT_INIT); // enable INIT pin back
|
||||
BX_INFO(("CPU %d started up at %04X:%08X by APIC",
|
||||
BX_CPU_THIS_PTR bx_cpuid, vector*0x100, EIP));
|
||||
} else {
|
||||
|
@ -899,6 +899,10 @@ void BX_CPU_C::reset(unsigned source)
|
||||
BX_CPU_THIS_PTR in_event = 0;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_VMX
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 0;
|
||||
#endif
|
||||
|
||||
#if BX_SUPPORT_SMP
|
||||
// notice if I'm the bootstrap processor. If not, do the equivalent of
|
||||
// a HALT instruction.
|
||||
@ -912,7 +916,6 @@ void BX_CPU_C::reset(unsigned source)
|
||||
BX_CPU_THIS_PTR msr.apicbase &= ~0x0100; /* clear bit 8 BSP */
|
||||
BX_INFO(("CPU[%d] is an application processor. Halting until IPI.", apic_id));
|
||||
activity_state = BX_ACTIVITY_STATE_WAIT_FOR_SIPI;
|
||||
mask_event(BX_EVENT_INIT); // INIT is disabled when CPU is waiting for SIPI
|
||||
async_event = 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -1620,9 +1620,11 @@ bx_phy_address BX_CPU_C::translate_guest_physical(bx_phy_address guest_paddr, bx
|
||||
// no VMExit qualification for EPT Misconfiguration VMExit
|
||||
vmexit_qualification = access_mask | (combined_access << 3);
|
||||
if (guest_laddr_valid) {
|
||||
vmexit_qualification |= 0x80;
|
||||
if (! is_page_walk) vmexit_qualification |= 0x100;
|
||||
vmexit_qualification |= (1<<7);
|
||||
if (! is_page_walk) vmexit_qualification |= (1<<8);
|
||||
}
|
||||
if (BX_CPU_THIS_PTR nmi_unblocking_iret)
|
||||
vmexit_qualification |= (1 << 12);
|
||||
|
||||
if (SECONDARY_VMEXEC_CONTROL(VMX_VM_EXEC_CTRL3_EPT_VIOLATION_EXCEPTION)) {
|
||||
if ((entry[leaf] & BX_SUPPRESS_EPT_VIOLATION_EXCEPTION) == 0)
|
||||
|
@ -236,6 +236,8 @@ void BX_CPU_C::VMexit_Event(unsigned type, unsigned vector, Bit16u errcode, bx_b
|
||||
vm->idt_vector_info = vector | (type << 8);
|
||||
if (errcode_valid)
|
||||
vm->idt_vector_info |= (1 << 11); // error code delivered
|
||||
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -260,6 +262,9 @@ void BX_CPU_C::VMexit_Event(unsigned type, unsigned vector, Bit16u errcode, bx_b
|
||||
interruption_info |= (1 << 11); // error code delivered
|
||||
interruption_info |= (1 << 31); // valid
|
||||
|
||||
if (BX_CPU_THIS_PTR nmi_unblocking_iret)
|
||||
interruption_info |= (1 << 12);
|
||||
|
||||
VMwrite32(VMCS_32BIT_VMEXIT_INTERRUPTION_INFO, interruption_info);
|
||||
VMwrite32(VMCS_32BIT_VMEXIT_INTERRUPTION_ERR_CODE, errcode);
|
||||
|
||||
|
@ -2414,6 +2414,8 @@ void BX_CPU_C::VMexit(Bit32u reason, Bit64u qualification)
|
||||
VMwrite32(VMCS_32BIT_IDT_VECTORING_INFO, 0);
|
||||
}
|
||||
|
||||
BX_CPU_THIS_PTR nmi_unblocking_iret = 0;
|
||||
|
||||
// VMEXITs are FAULT-like: restore RIP/RSP to value before VMEXIT occurred
|
||||
if (! IS_TRAP_LIKE_VMEXIT(reason)) {
|
||||
RIP = BX_CPU_THIS_PTR prev_rip;
|
||||
|
Loading…
x
Reference in New Issue
Block a user