- Timestamp:
- Oct 8, 2018 3:13:52 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/hm_vmx.h
r74667 r74683 2687 2687 /** Task switch caused by an interrupt gate. */ 2688 2688 #define VMX_EXIT_QUAL_TASK_SWITCH_TYPE_IDT 3 2689 2690 /** Bit fields for Exit qualification for task switches. */ 2691 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_NEW_TSS_SHIFT 0 2692 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_NEW_TSS_MASK UINT64_C(0x000000000000ffff) 2693 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_16_29_SHIFT 16 2694 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_16_29_MASK UINT64_C(0x000000003fff0000) 2695 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_SOURCE_SHIFT 30 2696 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_SOURCE_MASK UINT64_C(0x00000000c0000000) 2697 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_32_63_SHIFT 32 2698 #define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_32_63_MASK UINT64_C(0xffffffff00000000) 2699 RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_TASK_SWITCH_, UINT64_C(0), UINT64_MAX, 2700 (NEW_TSS, RSVD_16_29, SOURCE, RSVD_32_63)); 2689 2701 /** @} */ 2690 2702 -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r74661 r74683 397 397 398 398 /** 399 * Check if the nested-guest has the given Pin-based VM-execution control set. 400 */ 401 # define IEM_VMX_IS_PINCTLS_SET(a_pVCpu, a_PinCtl) \ 402 (CPUMIsGuestVmxPinCtlsSet((a_pVCpu), IEM_GET_CTX(a_pVCpu), (a_PinCtl))) 403 404 /** 405 * Check if the nested-guest has the given Processor-based VM-execution control set. 406 */ 407 #define IEM_VMX_IS_PROCCTLS_SET(a_pVCpu, a_ProcCtl) \ 408 (CPUMIsGuestVmxProcCtlsSet((a_pVCpu), IEM_GET_CTX(a_pVCpu), (a_ProcCtl))) 409 410 /** 411 * Check if the nested-guest has the given Secondary Processor-based VM-execution 412 * control set. 413 */ 414 #define IEM_VMX_IS_PROCCTLS2_SET(a_pVCpu, a_ProcCtl2) \ 415 (CPUMIsGuestVmxProcCtls2Set((a_pVCpu), IEM_GET_CTX(a_pVCpu), (a_ProcCtl2))) 416 417 /** 399 418 * Invokes the VMX VM-exit handler for an instruction intercept. 400 419 */ … … 410 429 411 430 /** 412 * Check if the nested-guest has the given Pin-based VM-execution control set. 413 */ 414 # define IEM_VMX_IS_PINCTLS_SET(a_pVCpu, a_PinCtl) \ 415 (CPUMIsGuestVmxPinCtlsSet((a_pVCpu), IEM_GET_CTX(a_pVCpu), (a_PinCtl))) 416 417 /** 418 * Check if the nested-guest has the given Processor-based VM-execution control set. 419 */ 420 #define IEM_VMX_IS_PROCCTLS_SET(a_pVCpu, a_ProcCtl) \ 421 (CPUMIsGuestVmxProcCtlsSet((a_pVCpu), IEM_GET_CTX(a_pVCpu), (a_ProcCtl))) 422 423 /** 424 * Check if the nested-guest has the given Secondary Processor-based VM-execution 425 * control set. 426 */ 427 #define IEM_VMX_IS_PROCCTLS2_SET(a_pVCpu, a_ProcCtl2) \ 428 (CPUMIsGuestVmxProcCtls2Set((a_pVCpu), IEM_GET_CTX(a_pVCpu), (a_ProcCtl2))) 431 * Invokes the VMX VM-exit handler for a task switch. 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) 429 435 430 436 #else … … 434 440 # define IEM_VMX_IS_PROCCTLS_SET(a_pVCpu, a_cbInstr) (false) 435 441 # define IEM_VMX_IS_PROCCTLS2_SET(a_pVCpu, a_cbInstr) (false) 436 # define IEM_VMX_VMEXIT_INSTR_RET(a_pVCpu, a_uExitReason, a_cbInstr) do { return VERR_VMX_IPE_1; } while (0) 442 # define IEM_VMX_VMEXIT_TASK_SWITCH_RET(a_pVCpu, a_enmTaskSwitch, a_SelNewTss) do { return VERR_VMX_IPE_1; } while (0) 443 # define IEM_VMX_VMEXIT_INSTR_RET(a_pVCpu, a_uExitReason, a_cbInstr) do { return VERR_VMX_IPE_1; } while (0) 437 444 # define IEM_VMX_VMEXIT_INSTR_NEEDS_INFO_RET(a_pVCpu, a_uExitReason, a_uInstrId, a_cbInstr) do { return VERR_VMX_IPE_1; } while (0) 438 445 … … 951 958 IEM_STATIC uint16_t iemSRegFetchU16(PVMCPU pVCpu, uint8_t iSegReg); 952 959 IEM_STATIC uint64_t iemSRegBaseFetchU64(PVMCPU pVCpu, uint8_t iSegReg); 960 961 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 962 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss); 963 #endif 953 964 954 965 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM … … 3961 3972 * @returns VBox strict status code. 3962 3973 * @param pVCpu The cross context virtual CPU structure of the calling thread. 3963 * @param enmTaskSwitch What caused thistask switch.3974 * @param enmTaskSwitch The cause of the task switch. 3964 3975 * @param uNextEip The EIP effective after the task switch. 3965 3976 * @param fFlags The flags, see IEM_XCPT_FLAGS_XXX. … … 4012 4023 enmTaskSwitch, uNewTSSLimit, uNewTSSLimitMin)); 4013 4024 return iemRaiseTaskSwitchFaultWithErr(pVCpu, SelTSS & X86_SEL_MASK_OFF_RPL); 4025 } 4026 4027 /* 4028 * Task switches in VMX non-root mode always cause task switches. 4029 * The new TSS must have been read and validated (DPL, limits etc.) before a 4030 * task-switch VM-exit commences. 4031 * 4032 * See Intel spec. 25.4.2 ".Treatment of Task Switches" 4033 */ 4034 if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu)) 4035 { 4036 Log(("iemTaskSwitch: Guest intercept (source=%u, sel=%#x) -> VM-exit.\n", enmTaskSwitch, SelTSS)); 4037 IEM_VMX_VMEXIT_TASK_SWITCH_RET(pVCpu, enmTaskSwitch, SelTSS); 4014 4038 } 4015 4039 … … 4037 4061 RT_NOREF2(uExitInfo1, uExitInfo2); 4038 4062 } 4039 /** @todo Nested-VMX task-switch intercept. */4040 4063 4041 4064 /* … … 4118 4141 Log(("iemTaskSwitch: Switching to the same TSS! enmTaskSwitch=%u GCPtr[Cur|New]TSS=%#RGv\n", enmTaskSwitch, GCPtrCurTSS)); 4119 4142 Log(("uCurCr3=%#x uCurEip=%#x uCurEflags=%#x uCurEax=%#x uCurEsp=%#x uCurEbp=%#x uCurCS=%#04x uCurSS=%#04x uCurLdt=%#x\n", 4120 pVCpu->cpum.GstCtx.cr3, pVCpu->cpum.GstCtx.eip, pVCpu->cpum.GstCtx.eflags.u32, pVCpu->cpum.GstCtx.eax, pVCpu->cpum.GstCtx.esp, pVCpu->cpum.GstCtx.ebp, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.ss.Sel, pVCpu->cpum.GstCtx.ldtr.Sel)); 4143 pVCpu->cpum.GstCtx.cr3, pVCpu->cpum.GstCtx.eip, pVCpu->cpum.GstCtx.eflags.u32, pVCpu->cpum.GstCtx.eax, 4144 pVCpu->cpum.GstCtx.esp, pVCpu->cpum.GstCtx.ebp, pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.ss.Sel, 4145 pVCpu->cpum.GstCtx.ldtr.Sel)); 4121 4146 } 4122 4147 if (fIsNewTSS386) … … 4420 4445 else 4421 4446 { 4422 Assert(!pVCpu->cpum.GstCtx.ldtr.Attr.n.u1Present); 4447 Assert(!pVCpu->cpum.GstCtx.ldtr.Attr.n.u1Present); /* Ensures that LDT.TI check passes in iemMemFetchSelDesc() below. */ 4423 4448 4424 4449 IEMSELDESC DescNewLdt; … … 4705 4730 } 4706 4731 4707 Log(("iemTaskSwitch: Success! New CS:EIP=%#04x:%#x SS=%#04x\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.eip, pVCpu->cpum.GstCtx.ss.Sel)); 4732 Log(("iemTaskSwitch: Success! New CS:EIP=%#04x:%#x SS=%#04x\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.eip, 4733 pVCpu->cpum.GstCtx.ss.Sel)); 4708 4734 return fFlags & IEM_XCPT_FLAGS_T_CPU_XCPT ? VINF_IEM_RAISED_XCPT : VINF_SUCCESS; 4709 4735 } … … 4864 4890 4865 4891 /* Do the actual task switch. */ 4866 return iemTaskSwitch(pVCpu, IEMTASKSWITCH_INT_XCPT, (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT) ? pVCpu->cpum.GstCtx.eip + cbInstr : pVCpu->cpum.GstCtx.eip, fFlags, uErr, uCr2, SelTSS, &DescTSS); 4892 return iemTaskSwitch(pVCpu, IEMTASKSWITCH_INT_XCPT, 4893 (fFlags & IEM_XCPT_FLAGS_T_SOFT_INT) ? pVCpu->cpum.GstCtx.eip + cbInstr : pVCpu->cpum.GstCtx.eip, 4894 fFlags, uErr, uCr2, SelTSS, &DescTSS); 4867 4895 } 4868 4896 -
trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h
r74678 r74683 28 28 * VMX_EXIT_INT_WINDOW 29 29 * VMX_EXIT_NMI_WINDOW 30 * VMX_EXIT_TASK_SWITCH31 30 * VMX_EXIT_GETSEC 32 31 * VMX_EXIT_INVD 33 32 * VMX_EXIT_RSM 34 33 * VMX_EXIT_MOV_DRX 35 * VMX_EXIT_IO_INSTR36 34 * VMX_EXIT_MWAIT 37 35 * VMX_EXIT_MTF … … 2727 2725 * 2728 2726 * The VM-exit instruction length is mandatory for all VM-exits that are caused by 2729 * instruction execution. 2727 * instruction execution. For VM-exits that are not due to instruction execution this 2728 * field is undefined. 2730 2729 * 2731 2730 * In our implementation in IEM, all undefined fields are generally cleared. However, … … 3373 3372 3374 3373 return VINF_VMX_INTERCEPT_NOT_ACTIVE; 3374 } 3375 3376 3377 /** 3378 * VMX VM-exit handler for VM-exits due to task switches. 3379 * 3380 * @returns VBox strict status code. 3381 * @param pVCpu The cross context virtual CPU structure. 3382 * @param enmTaskSwitch The cause of the task switch. 3383 * @param SelNewTss The selector of the new TSS. 3384 */ 3385 IEM_STATIC VBOXSTRICTRC iemVmxVmexitTaskSwitch(PVMCPU pVCpu, IEMTASKSWITCH enmTaskSwitch, RTSEL SelNewTss) 3386 { 3387 /* 3388 * Task-switch VM-exits are unconditional and only provide the 3389 * VM-exit qualification. 3390 * 3391 * See Intel spec. 25.2 "Other Causes Of VM Exits". 3392 */ 3393 uint8_t uTaskSwitchSrc; 3394 switch (enmTaskSwitch) 3395 { 3396 case IEMTASKSWITCH_CALL: uTaskSwitchSrc = 0; break; 3397 case IEMTASKSWITCH_IRET: uTaskSwitchSrc = 1; break; 3398 case IEMTASKSWITCH_JUMP: uTaskSwitchSrc = 2; break; 3399 case IEMTASKSWITCH_INT_XCPT: uTaskSwitchSrc = 3; break; 3400 IEM_NOT_REACHED_DEFAULT_CASE_RET(); 3401 } 3402 3403 uint64_t const uExitQual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_TASK_SWITCH_NEW_TSS, SelNewTss) 3404 | RT_BF_MAKE(VMX_BF_EXIT_QUAL_TASK_SWITCH_SOURCE, uTaskSwitchSrc); 3405 iemVmxVmcsSetExitQual(pVCpu, uExitQual); 3406 return iemVmxVmexit(pVCpu, VMX_EXIT_TASK_SWITCH); 3375 3407 } 3376 3408
Note:
See TracChangeset
for help on using the changeset viewer.