Changeset 72440 in vbox
- Timestamp:
- Jun 5, 2018 5:45:11 AM (6 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r72212 r72440 91 91 else if ( rc == VINF_HM_DOUBLE_FAULT) { return VINF_SUCCESS; } \ 92 92 else if ( rc == VINF_EM_RESET \ 93 && HMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, SVM_CTRL_INTERCEPT_SHUTDOWN)) \93 && CPUMIsGuestSvmCtrlInterceptSet(pVCpu, pCtx, SVM_CTRL_INTERCEPT_SHUTDOWN)) \ 94 94 return VBOXSTRICTRC_TODO(IEMExecSvmVmexit(pVCpu, SVM_EXIT_SHUTDOWN, 0, 0)); \ 95 95 else \ … … 374 374 #endif 375 375 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM 376 static FNSVMEXITHANDLER hmR0SvmExitXcptPFNested;377 376 static FNSVMEXITHANDLER hmR0SvmExitClgi; 378 377 static FNSVMEXITHANDLER hmR0SvmExitStgi; … … 5099 5098 return HM_SVM_VMEXIT_NESTED(pVCpu, uExitCode, u32ErrCode, uFaultAddress); 5100 5099 5101 /* If the nested-guest is not intercepting #PFs, forward the #PF to the nested-guest. */5100 /* If the nested-guest is not intercepting #PFs, forward the #PF to the guest. */ 5102 5101 hmR0SvmSetPendingXcptPF(pVCpu, pCtx, u32ErrCode, uFaultAddress); 5103 5102 return VINF_SUCCESS; 5104 5103 } 5105 return hmR0SvmExitXcptPF Nested(pVCpu, pCtx,pSvmTransient);5104 return hmR0SvmExitXcptPF(pVCpu, pCtx,pSvmTransient); 5106 5105 } 5107 5106 … … 5883 5882 /* Determine a vectoring #PF condition, see comment in hmR0SvmExitXcptPF(). */ 5884 5883 if (fRaiseInfo & (IEMXCPTRAISEINFO_EXT_INT_PF | IEMXCPTRAISEINFO_NMI_PF)) 5884 { 5885 5885 pSvmTransient->fVectoringPF = true; 5886 Log4(("IDT: Pending vectoring #PF due to delivery of Ext-Int/NMI. uCR2=%#RX64\n", pCtx->cr2)); 5887 } 5886 5888 else if ( pVmcb->ctrl.ExitIntInfo.n.u3Type == SVM_EVENT_EXCEPTION 5887 5889 && uIdtVector == X86_XCPT_PF) … … 5923 5925 if (fRaiseInfo & IEMXCPTRAISEINFO_PF_PF) 5924 5926 { 5927 Log4(("IDT: Pending vectoring double #PF uCR2=%#RX64\n", pCtx->cr2)); 5925 5928 pSvmTransient->fVectoringDoublePF = true; 5926 5929 Assert(rc == VINF_SUCCESS); … … 7252 7255 { 7253 7256 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS(); 7254 HMSVM_ASSERT_NOT_IN_NESTED_GUEST(pCtx);7255 7257 7256 7258 HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY(); 7257 7259 7258 7260 /* See AMD spec. 15.12.15 "#PF (Page Fault)". */ 7259 P SVMVMCB pVmcb = pVCpu->hm.s.svm.pVmcb;7260 uint32_t u32ErrCode = pVmcb->ctrl.u64ExitInfo1;7261 RTGCUINTPTR uFaultAddress = pVmcb->ctrl.u64ExitInfo2;7262 PVM pVM = pVCpu->CTX_SUFF(pVM);7261 PVM pVM = pVCpu->CTX_SUFF(pVM); 7262 PSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu, pCtx); 7263 uint32_t uErrCode = pVmcb->ctrl.u64ExitInfo1; 7264 uint64_t const uFaultAddress = pVmcb->ctrl.u64ExitInfo2; 7263 7265 7264 7266 #if defined(HMSVM_ALWAYS_TRAP_ALL_XCPTS) || defined(HMSVM_ALWAYS_TRAP_PF) … … 7266 7268 { 7267 7269 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory or vectoring #PF. */ 7268 if (!pSvmTransient->fVectoringDoublePF) 7270 if ( !pSvmTransient->fVectoringDoublePF 7271 || CPUMIsGuestInSvmNestedHwVirtMode(pCtx)) 7269 7272 { 7270 7273 /* A genuine guest #PF, reflect it to the guest. */ 7271 hmR0SvmSetPendingXcptPF(pVCpu, pCtx, u 32ErrCode, uFaultAddress);7272 Log4(("#PF: Guest page fault at %04X:%RGv FaultAddr=%R GvErrCode=%#x\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip,7273 uFaultAddress, u 32ErrCode));7274 hmR0SvmSetPendingXcptPF(pVCpu, pCtx, uErrCode, uFaultAddress); 7275 Log4(("#PF: Guest page fault at %04X:%RGv FaultAddr=%RX64 ErrCode=%#x\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip, 7276 uFaultAddress, uErrCode)); 7274 7277 } 7275 7278 else … … 7291 7294 if ( pVM->hm.s.fTprPatchingAllowed 7292 7295 && (uFaultAddress & 0xfff) == XAPIC_OFF_TPR 7293 && !(u32ErrCode & X86_TRAP_PF_P) /* Not present. */ 7296 && !(uErrCode & X86_TRAP_PF_P) /* Not present. */ 7297 && !CPUMIsGuestInSvmNestedHwVirtMode(pCtx) 7294 7298 && !CPUMIsGuestInLongModeEx(pCtx) 7295 7299 && !CPUMGetGuestCPL(pVCpu) … … 7313 7317 } 7314 7318 7315 Log4(("#PF: uFaultAddress=%#RX64 CS:RIP=%#04x:%#RX64 u 32ErrCode %#RX32 cr3=%#RX64\n", uFaultAddress, pCtx->cs.Sel,7316 pCtx->rip, u 32ErrCode, pCtx->cr3));7319 Log4(("#PF: uFaultAddress=%#RX64 CS:RIP=%#04x:%#RX64 uErrCode %#RX32 cr3=%#RX64\n", uFaultAddress, pCtx->cs.Sel, 7320 pCtx->rip, uErrCode, pCtx->cr3)); 7317 7321 7318 7322 /* If it's a vectoring #PF, emulate injecting the original event injection as PGMTrap0eHandler() is incapable … … 7324 7328 } 7325 7329 7326 TRPMAssertXcptPF(pVCpu, uFaultAddress, u 32ErrCode);7327 int rc = PGMTrap0eHandler(pVCpu, u 32ErrCode, CPUMCTX2CORE(pCtx), (RTGCPTR)uFaultAddress);7328 7329 Log4(("#PF rc=%Rrc\n", rc));7330 TRPMAssertXcptPF(pVCpu, uFaultAddress, uErrCode); 7331 int rc = PGMTrap0eHandler(pVCpu, uErrCode, CPUMCTX2CORE(pCtx), (RTGCPTR)uFaultAddress); 7332 7333 Log4(("#PF: rc=%Rrc\n", rc)); 7330 7334 7331 7335 if (rc == VINF_SUCCESS) … … 7337 7341 return rc; 7338 7342 } 7339 else if (rc == VINF_EM_RAW_GUEST_TRAP) 7343 7344 if (rc == VINF_EM_RAW_GUEST_TRAP) 7340 7345 { 7341 7346 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory or vectoring #PF. */ 7342 7347 7343 if (!pSvmTransient->fVectoringDoublePF) 7344 { 7345 /* It's a guest page fault and needs to be reflected to the guest. */ 7346 u32ErrCode = TRPMGetErrorCode(pVCpu); /* The error code might have been changed. */ 7348 /* 7349 * If a nested-guest delivers a #PF and that causes a #PF which is -not- a shadow #PF, 7350 * we should simply forward the #PF to the guest and is up to the nested-hypervisor to 7351 * determine whether it is a nested-shadow #PF or a #DF, see @bugref{7243#c121}. 7352 */ 7353 if ( !pSvmTransient->fVectoringDoublePF 7354 || CPUMIsGuestInSvmNestedHwVirtMode(pCtx)) 7355 { 7356 /* It's a guest (or nested-guest) page fault and needs to be reflected. */ 7357 uErrCode = TRPMGetErrorCode(pVCpu); /* The error code might have been changed. */ 7347 7358 TRPMResetTrap(pVCpu); 7348 hmR0SvmSetPendingXcptPF(pVCpu, pCtx, u32ErrCode, uFaultAddress); 7359 7360 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM 7361 /* If the nested-guest is intercepting #PFs, cause a #PF #VMEXIT. */ 7362 if ( CPUMIsGuestInSvmNestedHwVirtMode(pCtx) 7363 && HMIsGuestSvmXcptInterceptSet(pVCpu, pCtx, X86_XCPT_PF)) 7364 return VBOXSTRICTRC_TODO(IEMExecSvmVmexit(pVCpu, SVM_EXIT_XCPT_PF, uErrCode, uFaultAddress)); 7365 #endif 7366 7367 hmR0SvmSetPendingXcptPF(pVCpu, pCtx, uErrCode, uFaultAddress); 7349 7368 } 7350 7369 else … … 7594 7613 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM 7595 7614 /** 7596 * \#VMEXIT handler for #PF occuring while in nested-guest execution7597 * (SVM_EXIT_XCPT_14). Conditional \#VMEXIT.7598 */7599 HMSVM_EXIT_DECL hmR0SvmExitXcptPFNested(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)7600 {7601 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();7602 7603 HMSVM_CHECK_EXIT_DUE_TO_EVENT_DELIVERY();7604 7605 /* See AMD spec. 15.12.15 "#PF (Page Fault)". */7606 PSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu, pCtx);7607 uint32_t u32ErrCode = pVmcb->ctrl.u64ExitInfo1;7608 uint64_t const uFaultAddress = pVmcb->ctrl.u64ExitInfo2;7609 7610 Log4(("#PFNested: uFaultAddress=%#RX64 CS:RIP=%#04x:%#RX64 u32ErrCode=%#RX32 CR3=%#RX64\n", uFaultAddress, pCtx->cs.Sel,7611 pCtx->rip, u32ErrCode, pCtx->cr3));7612 7613 /* If it's a vectoring #PF, emulate injecting the original event injection as PGMTrap0eHandler() is incapable7614 of differentiating between instruction emulation and event injection that caused a #PF. See @bugref{6607}. */7615 if (pSvmTransient->fVectoringPF)7616 {7617 Assert(pVCpu->hm.s.Event.fPending);7618 return VINF_EM_RAW_INJECT_TRPM_EVENT;7619 }7620 7621 Assert(!pVCpu->CTX_SUFF(pVM)->hm.s.fNestedPaging);7622 7623 TRPMAssertXcptPF(pVCpu, uFaultAddress, u32ErrCode);7624 int rc = PGMTrap0eHandler(pVCpu, u32ErrCode, CPUMCTX2CORE(pCtx), (RTGCPTR)uFaultAddress);7625 7626 Log4(("#PFNested: rc=%Rrc\n", rc));7627 7628 if (rc == VINF_SUCCESS)7629 {7630 /* Successfully synced shadow pages tables or emulated an MMIO instruction. */7631 TRPMResetTrap(pVCpu);7632 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowPF);7633 HMCPU_CF_SET(pVCpu, HM_CHANGED_ALL_GUEST);7634 return rc;7635 }7636 7637 if (rc == VINF_EM_RAW_GUEST_TRAP)7638 {7639 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory or vectoring #PF. */7640 7641 if (!pSvmTransient->fVectoringDoublePF)7642 {7643 /* It's a nested-guest page fault and needs to be reflected to the nested-guest. */7644 u32ErrCode = TRPMGetErrorCode(pVCpu); /* The error code might have been changed. */7645 TRPMResetTrap(pVCpu);7646 hmR0SvmSetPendingXcptPF(pVCpu, pCtx, u32ErrCode, uFaultAddress);7647 }7648 else7649 {7650 /* A nested-guest page-fault occurred during delivery of a page-fault. Inject #DF. */7651 TRPMResetTrap(pVCpu);7652 hmR0SvmSetPendingXcptDF(pVCpu);7653 Log4(("#PF: Pending #DF due to vectoring #PF\n"));7654 }7655 7656 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF);7657 return VINF_SUCCESS;7658 }7659 7660 TRPMResetTrap(pVCpu);7661 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitShadowPFEM);7662 return rc;7663 }7664 7665 7666 /**7667 7615 * \#VMEXIT handler for CLGI (SVM_EXIT_CLGI). Conditional \#VMEXIT. 7668 7616 */ -
trunk/src/VBox/VMM/VMMR3/EM.cpp
r72327 r72440 1716 1716 * doesn't intercept HLT but intercepts INTR? */ 1717 1717 *pfResched = true; 1718 return VINF_EM_RESCHEDULE; 1718 if (rcStrict == VINF_SVM_VMEXIT) 1719 return VINF_SUCCESS; 1720 if (rcStrict == VINF_PGM_CHANGE_MODE) 1721 return PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER); 1722 return VBOXSTRICTRC_VAL(rcStrict); 1719 1723 } 1720 1724 … … 1726 1730 /** @todo this really isn't nice, should properly handle this */ 1727 1731 int rc = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT); 1732 if (rc == VINF_SVM_VMEXIT) 1733 rc = VINF_SUCCESS; 1734 else if (rc == VINF_PGM_CHANGE_MODE) 1735 rc = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER); 1728 1736 if (pVM->em.s.fIemExecutesAll && ( rc == VINF_EM_RESCHEDULE_REM 1729 1737 || rc == VINF_EM_RESCHEDULE_HM … … 1750 1758 * doesn't intercept HLT but intercepts VINTR? */ 1751 1759 *pfResched = true; 1752 return VINF_EM_RESCHEDULE; 1760 if (rcStrict == VINF_SVM_VMEXIT) 1761 return VINF_SUCCESS; 1762 if (rcStrict == VINF_PGM_CHANGE_MODE) 1763 return PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER); 1764 return VBOXSTRICTRC_VAL(rcStrict); 1753 1765 } 1754 1766 … … 2129 2141 /** @todo this really isn't nice, should properly handle this */ 2130 2142 rc2 = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT); 2131 Log(("EM: TRPMR3InjectEvent -> %d\n", rc2));2143 Log(("EM: TRPMR3InjectEvent -> %d\n", rc2)); 2132 2144 if (pVM->em.s.fIemExecutesAll && ( rc2 == VINF_EM_RESCHEDULE_REM 2133 2145 || rc2 == VINF_EM_RESCHEDULE_HM
Note:
See TracChangeset
for help on using the changeset viewer.