- Timestamp:
- May 27, 2019 5:22:48 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r78720 r78772 413 413 * @{ 414 414 */ 415 static int hmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 416 static int hmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 417 static int hmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 418 static int hmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 419 static int hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 420 static int hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 421 static int hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 415 static VBOXSTRICTRC hmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 416 static VBOXSTRICTRC hmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 417 static VBOXSTRICTRC hmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 418 static VBOXSTRICTRC hmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 419 static VBOXSTRICTRC hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 420 static VBOXSTRICTRC hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 421 static VBOXSTRICTRC hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient); 422 static VBOXSTRICTRC hmR0VmxExitLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uMsw, RTGCPTR GCPtrEffDst); 422 423 /** @} */ 423 424 … … 12843 12844 case VMX_EXIT_QUAL_CRX_ACCESS_WRITE: 12844 12845 case VMX_EXIT_QUAL_CRX_ACCESS_READ: 12845 case VMX_EXIT_QUAL_CRX_ACCESS_CLTS:12846 12846 { 12847 12847 /** @todo NSTVMX: Implement me. */ … … 12849 12849 } 12850 12850 12851 case VMX_EXIT_QUAL_CRX_ACCESS_CLTS: 12852 { 12853 PCVMXVVMCS pVmcsNstGst = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs); 12854 Assert(pVmcsNstGst); 12855 12856 uint64_t const uGstHostMask = pVmcsNstGst->u64Cr0Mask.u; 12857 uint64_t const uReadShadow = pVmcsNstGst->u64Cr0ReadShadow.u; 12858 if ( (uGstHostMask & X86_CR0_TS) 12859 && (uReadShadow & X86_CR0_TS)) 12860 { 12861 /** @todo NSTVMX: continue with VM-exit. */ 12862 } 12863 break; 12864 } 12865 12851 12866 case VMX_EXIT_QUAL_CRX_ACCESS_LMSW: /* LMSW (Load Machine-Status Word into CR0) */ 12852 12867 { 12853 uint16_t const uNewMsw = VMX_EXIT_QUAL_CRX_LMSW_DATA(pVmxTransient->uExitQual); 12868 RTGCPTR GCPtrEffDst; 12869 uint16_t const uNewMsw = VMX_EXIT_QUAL_CRX_LMSW_DATA(pVmxTransient->uExitQual); 12870 bool const fMemOperand = VMX_EXIT_QUAL_CRX_LMSW_OP_MEM(pVmxTransient->uExitQual); 12871 12872 rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient); 12873 if (fMemOperand) 12874 { 12875 rc |= hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient); 12876 GCPtrEffDst = pVmxTransient->uGuestLinearAddr; 12877 } 12878 else 12879 GCPtrEffDst = NIL_RTGCPTR; 12880 AssertRCReturn(rc, rc); 12881 12854 12882 if (CPUMIsGuestVmxLmswInterceptSet(pVCpu, &pVCpu->cpum.GstCtx, uNewMsw)) 12855 12883 { 12856 rc = hmR0VmxReadExitInstrLenVmcs(pVmxTransient);12857 AssertRCReturn(rc, rc);12858 12859 RTGCPTR GCPtrEffDst;12860 bool const fMemOperand = VMX_EXIT_QUAL_CRX_LMSW_OP(pVmxTransient->uExitQual);12861 if (fMemOperand)12862 {12863 rc = hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient);12864 AssertRCReturn(rc, rc);12865 GCPtrEffDst = pVmxTransient->uGuestLinearAddr;12866 }12867 else12868 GCPtrEffDst = NIL_RTGCPTR;12869 12870 12884 VMXVEXITINFO ExitInfo; 12871 12885 RT_ZERO(ExitInfo); … … 12877 12891 } 12878 12892 else 12879 rcStrict = hmR0VmxExit MovCRx(pVCpu, pVmxTransient);12893 rcStrict = hmR0VmxExitLmsw(pVCpu, pVmxTransient->cbInstr, uNewMsw, GCPtrEffDst); 12880 12894 break; 12881 12895 } … … 13374 13388 13375 13389 /* If this VM-exit occurred while delivering an event through the guest IDT, handle it accordingly. */ 13376 VBOXSTRICTRC rcStrict Rc1= hmR0VmxCheckExitDueToEventDelivery(pVCpu, pVmxTransient);13377 if (RT_UNLIKELY(rcStrict Rc1== VINF_SUCCESS))13390 VBOXSTRICTRC rcStrict = hmR0VmxCheckExitDueToEventDelivery(pVCpu, pVmxTransient); 13391 if (RT_UNLIKELY(rcStrict == VINF_SUCCESS)) 13378 13392 { /* likely */ } 13379 13393 else 13380 13394 { 13381 if (rcStrict Rc1== VINF_HM_DOUBLE_FAULT)13382 rcStrict Rc1= VINF_SUCCESS;13395 if (rcStrict == VINF_HM_DOUBLE_FAULT) 13396 rcStrict = VINF_SUCCESS; 13383 13397 STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3); 13384 return rcStrict Rc1;13398 return rcStrict; 13385 13399 } 13386 13400 … … 13407 13421 else if (uVector != X86_XCPT_PF) 13408 13422 { 13409 rc = VINF_SUCCESS;13423 rcStrict = VINF_SUCCESS; 13410 13424 break; 13411 13425 } … … 13413 13427 switch (uVector) 13414 13428 { 13415 case X86_XCPT_PF: rc = hmR0VmxExitXcptPF(pVCpu, pVmxTransient); break;13416 case X86_XCPT_GP: rc = hmR0VmxExitXcptGP(pVCpu, pVmxTransient); break;13417 case X86_XCPT_MF: rc = hmR0VmxExitXcptMF(pVCpu, pVmxTransient); break;13418 case X86_XCPT_DB: rc = hmR0VmxExitXcptDB(pVCpu, pVmxTransient); break;13419 case X86_XCPT_BP: rc = hmR0VmxExitXcptBP(pVCpu, pVmxTransient); break;13420 case X86_XCPT_AC: rc = hmR0VmxExitXcptAC(pVCpu, pVmxTransient); break;13429 case X86_XCPT_PF: rcStrict = hmR0VmxExitXcptPF(pVCpu, pVmxTransient); break; 13430 case X86_XCPT_GP: rcStrict = hmR0VmxExitXcptGP(pVCpu, pVmxTransient); break; 13431 case X86_XCPT_MF: rcStrict = hmR0VmxExitXcptMF(pVCpu, pVmxTransient); break; 13432 case X86_XCPT_DB: rcStrict = hmR0VmxExitXcptDB(pVCpu, pVmxTransient); break; 13433 case X86_XCPT_BP: rcStrict = hmR0VmxExitXcptBP(pVCpu, pVmxTransient); break; 13434 case X86_XCPT_AC: rcStrict = hmR0VmxExitXcptAC(pVCpu, pVmxTransient); break; 13421 13435 13422 13436 case X86_XCPT_NM: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNM); 13423 rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;13437 rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break; 13424 13438 case X86_XCPT_XF: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestXF); 13425 rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;13439 rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break; 13426 13440 case X86_XCPT_DE: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestDE); 13427 rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;13441 rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break; 13428 13442 case X86_XCPT_UD: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestUD); 13429 rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;13443 rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break; 13430 13444 case X86_XCPT_SS: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestSS); 13431 rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;13445 rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break; 13432 13446 case X86_XCPT_NP: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNP); 13433 rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;13447 rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break; 13434 13448 case X86_XCPT_TS: STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestTS); 13435 rc = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break;13449 rcStrict = hmR0VmxExitXcptGeneric(pVCpu, pVmxTransient); break; 13436 13450 default: 13437 13451 { … … 13450 13464 pVmxTransient->cbInstr, pVmxTransient->uExitIntErrorCode, 13451 13465 0 /* GCPtrFaultAddress */); 13466 rcStrict = VINF_SUCCESS; 13452 13467 } 13453 13468 else … … 13455 13470 AssertMsgFailed(("Unexpected VM-exit caused by exception %#x\n", uVector)); 13456 13471 pVCpu->hm.s.u32HMError = uVector; 13457 rc = VERR_VMX_UNEXPECTED_EXCEPTION;13472 rcStrict = VERR_VMX_UNEXPECTED_EXCEPTION; 13458 13473 } 13459 13474 break; … … 13466 13481 { 13467 13482 pVCpu->hm.s.u32HMError = uExitIntInfo; 13468 rc = VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE;13483 rcStrict = VERR_VMX_UNEXPECTED_INTERRUPTION_EXIT_TYPE; 13469 13484 AssertMsgFailed(("Unexpected interruption info %#x\n", VMX_EXIT_INT_INFO_TYPE(uExitIntInfo))); 13470 13485 break; … … 13472 13487 } 13473 13488 STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitXcptNmi, y3); 13474 return rc ;13489 return rcStrict; 13475 13490 } 13476 13491 … … 14494 14509 case VMX_EXIT_QUAL_CRX_ACCESS_LMSW: /* LMSW (Load Machine-Status Word into CR0) */ 14495 14510 { 14496 /* Note! LMSW cannot clear CR0.PE, so no fRealOnV86Active kludge needed here. */ 14497 rc = hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient); 14498 AssertRCReturn(rc, rc); 14499 rcStrict = IEMExecDecodedLmsw(pVCpu, pVmxTransient->cbInstr, VMX_EXIT_QUAL_CRX_LMSW_DATA(uExitQual), 14500 pVmxTransient->uGuestLinearAddr); 14501 AssertMsg( rcStrict == VINF_SUCCESS 14502 || rcStrict == VINF_IEM_RAISED_XCPT 14503 , ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 14504 14505 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS | HM_CHANGED_GUEST_CR0); 14506 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitLmsw); 14507 Log4Func(("LMSW rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict))); 14511 /* 14512 * LMSW cannot clear CR0.PE, so no fRealOnV86Active kludge needed here. 14513 */ 14514 RTGCPTR GCPtrEffDst; 14515 uint8_t const cbInstr = pVmxTransient->cbInstr; 14516 uint16_t const uMsw = VMX_EXIT_QUAL_CRX_LMSW_DATA(uExitQual); 14517 bool const fMemOperand = VMX_EXIT_QUAL_CRX_LMSW_OP_MEM(uExitQual); 14518 if (fMemOperand) 14519 { 14520 rc = hmR0VmxReadGuestLinearAddrVmcs(pVCpu, pVmxTransient); 14521 AssertRCReturn(rc, rc); 14522 GCPtrEffDst = pVmxTransient->uGuestLinearAddr; 14523 } 14524 else 14525 GCPtrEffDst = NIL_RTGCPTR; 14526 14527 rcStrict = hmR0VmxExitLmsw(pVCpu, cbInstr, uMsw, GCPtrEffDst); 14508 14528 break; 14509 14529 } … … 15172 15192 * VM-exit exception handler for \#MF (Math Fault: floating point exception). 15173 15193 */ 15174 static inthmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)15194 static VBOXSTRICTRC hmR0VmxExitXcptMF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 15175 15195 { 15176 15196 HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient); … … 15202 15222 * VM-exit exception handler for \#BP (Breakpoint exception). 15203 15223 */ 15204 static inthmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)15224 static VBOXSTRICTRC hmR0VmxExitXcptBP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 15205 15225 { 15206 15226 HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient); … … 15231 15251 * VM-exit exception handler for \#AC (alignment check exception). 15232 15252 */ 15233 static inthmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)15253 static VBOXSTRICTRC hmR0VmxExitXcptAC(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 15234 15254 { 15235 15255 HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient); … … 15252 15272 * VM-exit exception handler for \#DB (Debug exception). 15253 15273 */ 15254 static inthmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)15274 static VBOXSTRICTRC hmR0VmxExitXcptDB(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 15255 15275 { 15256 15276 HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient); … … 15406 15426 * @remarks Requires pVmxTransient->uExitIntInfo to be up-to-date. 15407 15427 */ 15408 static inthmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)15428 static VBOXSTRICTRC hmR0VmxExitXcptGP(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 15409 15429 { 15410 15430 HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient); … … 15484 15504 * up-to-date. 15485 15505 */ 15486 static inthmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)15506 static VBOXSTRICTRC hmR0VmxExitXcptGeneric(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 15487 15507 { 15488 15508 HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient); … … 15517 15537 * VM-exit exception handler for \#PF (Page-fault exception). 15518 15538 */ 15519 static inthmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)15539 static VBOXSTRICTRC hmR0VmxExitXcptPF(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient) 15520 15540 { 15521 15541 HMVMX_VALIDATE_EXIT_XCPT_HANDLER_PARAMS(pVCpu, pVmxTransient); … … 15609 15629 } 15610 15630 15631 15632 /** 15633 * VM-exit exception handler for LMSW. 15634 */ 15635 static VBOXSTRICTRC hmR0VmxExitLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uMsw, RTGCPTR GCPtrEffDst) 15636 { 15637 VBOXSTRICTRC rcStrict = IEMExecDecodedLmsw(pVCpu, cbInstr, uMsw, GCPtrEffDst); 15638 AssertMsg( rcStrict == VINF_SUCCESS 15639 || rcStrict == VINF_IEM_RAISED_XCPT 15640 , ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 15641 Log4Func(("rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict))); 15642 15643 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS | HM_CHANGED_GUEST_CR0); 15644 if (rcStrict == VINF_IEM_RAISED_XCPT) 15645 { 15646 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_RAISED_XCPT_MASK); 15647 rcStrict = VINF_SUCCESS; 15648 } 15649 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitLmsw); 15650 return rcStrict; 15651 } 15652 15653 15611 15654 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX 15612 15655 /** @name VMX instruction handlers.
Note:
See TracChangeset
for help on using the changeset viewer.