- Timestamp:
- Oct 11, 2018 5:01:25 AM (6 years ago)
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r74736 r74751 431 431 * Invokes the VMX VM-exit handler for a task switch. 432 432 */ 433 # define IEM_VMX_VMEXIT_TASK_SWITCH_RET(a_pVCpu, a_enmTaskSwitch, a_SelNewTss ) \434 do { return iemVmxVmexitTaskSwitch((a_pVCpu), (a_enmTaskSwitch), (a_SelNewTss) ); } while (0)433 # define IEM_VMX_VMEXIT_TASK_SWITCH_RET(a_pVCpu, a_enmTaskSwitch, a_SelNewTss, a_cbInstr) \ 434 do { return iemVmxVmexitTaskSwitch((a_pVCpu), (a_enmTaskSwitch), (a_SelNewTss), (a_cbInstr)); } while (0) 435 435 436 436 /** … … 440 440 do { return iemVmxVmexitInstrMwait((a_pVCpu), (a_fMonitorArmed), (a_cbInstr)); } while (0) 441 441 442 /** 443 * Invokes the VMX VM-exit handle for triple faults. 444 */ 445 # define IEM_VMX_VMEXIT_TRIPLE_FAULT_RET(a_pVCpu) \ 446 do { return iemVmxVmexitTripleFault(a_pVCpu); } while (0) 447 442 448 #else 443 # define IEM_VMX_IS_ROOT_MODE(a_pVCpu) (false)444 # define IEM_VMX_IS_NON_ROOT_MODE(a_pVCpu) (false)445 # define IEM_VMX_IS_PINCTLS_SET(a_pVCpu, a_cbInstr) (false)446 # define IEM_VMX_IS_PROCCTLS_SET(a_pVCpu, a_cbInstr) (false)447 # define IEM_VMX_IS_PROCCTLS2_SET(a_pVCpu, a_cbInstr) (false)449 # define IEM_VMX_IS_ROOT_MODE(a_pVCpu) (false) 450 # define IEM_VMX_IS_NON_ROOT_MODE(a_pVCpu) (false) 451 # define IEM_VMX_IS_PINCTLS_SET(a_pVCpu, a_cbInstr) (false) 452 # define IEM_VMX_IS_PROCCTLS_SET(a_pVCpu, a_cbInstr) (false) 453 # define IEM_VMX_IS_PROCCTLS2_SET(a_pVCpu, a_cbInstr) (false) 448 454 # define IEM_VMX_VMEXIT_INSTR_RET(a_pVCpu, a_uExitReason, a_cbInstr) do { return VERR_VMX_IPE_1; } while (0) 449 # define IEM_VMX_VMEXIT_INSTR_NEEDS_INFO_RET(a_pVCpu, a_uExitReason, a_uInstrId, a_cbInstr) 450 # define IEM_VMX_VMEXIT_TASK_SWITCH_RET(a_pVCpu, a_enmTaskSwitch, a_SelNewTss )do { return VERR_VMX_IPE_1; } while (0)455 # define IEM_VMX_VMEXIT_INSTR_NEEDS_INFO_RET(a_pVCpu, a_uExitReason, a_uInstrId, a_cbInstr) do { return VERR_VMX_IPE_1; } while (0) 456 # define IEM_VMX_VMEXIT_TASK_SWITCH_RET(a_pVCpu, a_enmTaskSwitch, a_SelNewTss, a_cbInstr) do { return VERR_VMX_IPE_1; } while (0) 451 457 # define IEM_VMX_VMEXIT_MWAIT_RET(a_pVCpu, a_fMonitorArmed, a_cbInstr) do { return VERR_VMX_IPE_1; } while (0) 458 # define IEM_VMX_VMEXIT_TRIPLE_FAULT_RET(a_pVCpu) do { return VERR_VMX_IPE_1; } while (0) 452 459 453 460 #endif … … 967 974 968 975 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 969 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss); 970 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEvent(PVMCPU pVCpu, uint8_t uVector, uint32_t fFlags, uint32_t uErrCode, uint64_t uCr2); 976 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss, uint8_t cbInstr); 977 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEvent(PVMCPU pVCpu, uint8_t uVector, uint32_t fFlags, uint32_t uErrCode, uint64_t uCr2, 978 uint8_t cbInstr); 979 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTripleFault(PVMCPU pVCpu); 971 980 #endif 972 981 973 982 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM 974 983 IEM_STATIC VBOXSTRICTRC iemSvmVmexit(PVMCPU pVCpu, uint64_t uExitCode, uint64_t uExitInfo1, uint64_t uExitInfo2); 975 IEM_STATIC VBOXSTRICTRC iemHandleSvmEventIntercept(PVMCPU pVCpu, uint8_t u8Vector, uint32_t fFlags, uint32_t uErr, uint64_t uCr2); 984 IEM_STATIC VBOXSTRICTRC iemHandleSvmEventIntercept(PVMCPU pVCpu, uint8_t u8Vector, uint32_t fFlags, uint32_t uErr, 985 uint64_t uCr2); 976 986 #endif 977 987 … … 3464 3474 IEM_STATIC VBOXSTRICTRC iemInitiateCpuShutdown(PVMCPU pVCpu) 3465 3475 { 3476 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 3477 IEM_VMX_VMEXIT_TRIPLE_FAULT_RET(pVCpu); 3478 3466 3479 if (IEM_SVM_IS_CTRL_INTERCEPT_SET(pVCpu, SVM_CTRL_INTERCEPT_SHUTDOWN)) 3467 3480 { … … 4043 4056 { 4044 4057 Log(("iemTaskSwitch: Guest intercept (source=%u, sel=%#x) -> VM-exit.\n", enmTaskSwitch, SelTSS)); 4045 IEM_VMX_VMEXIT_TASK_SWITCH_RET(pVCpu, enmTaskSwitch, SelTSS );4058 IEM_VMX_VMEXIT_TASK_SWITCH_RET(pVCpu, enmTaskSwitch, SelTSS, uNextEip - pVCpu->cpum.GstCtx.eip); 4046 4059 } 4047 4060 … … 5514 5527 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 5515 5528 { 5516 VBOXSTRICTRC rcStrict0 = iemVmxVmexitEvent(pVCpu, u8Vector, fFlags, uErr, uCr2 );5529 VBOXSTRICTRC rcStrict0 = iemVmxVmexitEvent(pVCpu, u8Vector, fFlags, uErr, uCr2, cbInstr); 5517 5530 if (rcStrict0 != VINF_VMX_INTERCEPT_NOT_ACTIVE) 5518 5531 return rcStrict0; … … 5579 5592 u8Vector = X86_XCPT_DF; 5580 5593 uErr = 0; 5594 /** @todo NSTVMX: Do we need to do something here for VMX? */ 5581 5595 /* SVM nested-guest #DF intercepts need to be checked now. See AMD spec. 15.12 "Exception Intercepts". */ 5582 5596 if (IEM_SVM_IS_XCPT_INTERCEPT_SET(pVCpu, X86_XCPT_DF)) -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74737 r74751 19 19 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 20 20 /** @todo NSTVMX: The following VM-exit intercepts are pending: 21 * VMX_EXIT_XCPT_OR_NMI 22 * VMX_EXIT_EXT_INT 23 * VMX_EXIT_TRIPLE_FAULT 21 * VMX_EXIT_EXT_INT ("acknowledge interrupt on exit" behavior pending) 24 22 * VMX_EXIT_INIT_SIGNAL 25 23 * VMX_EXIT_SIPI … … 3547 3545 * @param enmTaskSwitch The cause of the task switch. 3548 3546 * @param SelNewTss The selector of the new TSS. 3549 */ 3550 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss) 3551 { 3552 /* 3553 * Task-switch VM-exits are unconditional and only provide the 3554 * VM-exit qualification. 3547 * @param cbInstr The instruction length in bytes. 3548 */ 3549 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss, uint8_t cbInstr) 3550 { 3551 /* 3552 * Task-switch VM-exits are unconditional and provide the VM-exit qualification. 3553 * 3554 * If the the cause of the task switch is due to execution of CALL, IRET or the JMP 3555 * instruction or delivery of the exception generated by one of these instructions 3556 * lead to a task switch through a task gate in the IDT, we need to provide the 3557 * VM-exit instruction length. Any other means of invoking a task switch VM-exit 3558 * leaves the VM-exit instruction length field undefined. 3555 3559 * 3556 3560 * See Intel spec. 25.2 "Other Causes Of VM Exits". 3557 */ 3558 uint32_t uTaskSwitchSrc; 3561 * See Intel spec. 27.2.4 "Information for VM Exits Due to Instruction Execution". 3562 */ 3563 Assert(cbInstr <= 15); 3564 3565 uint8_t uType; 3559 3566 switch (enmTaskSwitch) 3560 3567 { 3561 case IEMTASKSWITCH_CALL: uTaskSwitchSrc = 0; break;3562 case IEMTASKSWITCH_IRET: uTaskSwitchSrc = 1; break;3563 case IEMTASKSWITCH_JUMP: uTaskSwitchSrc = 2;break;3564 case IEMTASKSWITCH_INT_XCPT: uTaskSwitchSrc = 3;break;3568 case IEMTASKSWITCH_CALL: uType = VMX_EXIT_QUAL_TASK_SWITCH_TYPE_CALL; break; 3569 case IEMTASKSWITCH_IRET: uType = VMX_EXIT_QUAL_TASK_SWITCH_TYPE_IRET; break; 3570 case IEMTASKSWITCH_JUMP: uType = VMX_EXIT_QUAL_TASK_SWITCH_TYPE_JMP; break; 3571 case IEMTASKSWITCH_INT_XCPT: uType = VMX_EXIT_QUAL_TASK_SWITCH_TYPE_IDT; break; 3565 3572 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 3566 3573 } 3567 3574 3568 3575 uint64_t const uExitQual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_TASK_SWITCH_NEW_TSS, SelNewTss) 3569 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_TASK_SWITCH_SOURCE, uT askSwitchSrc);3576 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_TASK_SWITCH_SOURCE, uType); 3570 3577 iemVmxVmcsSetExitQual(pVCpu, uExitQual); 3578 iemVmxVmcsSetExitInstrLen(pVCpu, cbInstr); 3571 3579 return iemVmxVmexit(pVCpu, VMX_EXIT_TASK_SWITCH); 3572 3580 } … … 3582 3590 * @param uErrCode The error code associated with the event. 3583 3591 * @param uCr2 The CR2 value in case of a \#PF exception. 3584 */ 3585 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEvent(PVMCPU pVCpu, uint8_t uVector, uint32_t fFlags, uint32_t uErrCode, uint64_t uCr2) 3592 * @param cbInstr The instruction length in bytes. 3593 */ 3594 IEM_STATIC VBOXSTRICTRC iemVmxVmexitEvent(PVMCPU pVCpu, uint8_t uVector, uint32_t fFlags, uint32_t uErrCode, uint64_t uCr2, 3595 uint8_t cbInstr) 3586 3596 { 3587 3597 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); … … 3689 3699 iemVmxVmcsSetExitIntErrCode(pVCpu, uErrCode); 3690 3700 iemVmxVmcsSetExitQual(pVCpu, uExitQual); 3701 3702 /* 3703 * For VM exits due to software exceptions (those generated by INT3 or INTO) or privileged 3704 * software exceptions (those generated by INT1/ICEBP) we need to supply the VM-exit instruction 3705 * length. 3706 */ 3707 if ( (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT) 3708 && (fFlags & (IEM_XCPT_FLAGS_BP_INSTR | IEM_XCPT_FLAGS_OF_INSTR | IEM_XCPT_FLAGS_ICEBP_INSTR))) 3709 iemVmxVmcsSetExitInstrLen(pVCpu, cbInstr); 3710 else 3711 iemVmxVmcsSetExitInstrLen(pVCpu, 0); 3712 3691 3713 return iemVmxVmexit(pVCpu, uExitReason); 3692 3714 } … … 3712 3734 ExitInfo.u64Qual = fMonitorHwArmed; 3713 3735 return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo); 3736 } 3737 3738 3739 /** 3740 * VMX VM-exit handler for VM-exits due to a triple fault. 3741 * 3742 * @returns VBox strict status code. 3743 * @param pVCpu The cross context virtual CPU structure. 3744 */ 3745 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTripleFault(PVMCPU pVCpu) 3746 { 3747 PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 3748 Assert(pVmcs); 3749 iemVmxVmcsSetExitQual(pVCpu, 0); 3750 return iemVmxVmexit(pVCpu, VMX_EXIT_TRIPLE_FAULT); 3714 3751 } 3715 3752
Note:
See TracChangeset
for help on using the changeset viewer.