Changeset 80587 in vbox
- Timestamp:
- Sep 4, 2019 5:44:20 PM (5 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMR0.cpp
r80333 r80587 87 87 /** @name Ring-0 method table for AMD-V and VT-x specific operations. 88 88 * @{ */ 89 DECLR0CALLBACKMEMBER(int, pfnEnterSession, (PVMCPUCC pVCpu)); 90 DECLR0CALLBACKMEMBER(void, pfnThreadCtxCallback, (RTTHREADCTXEVENT enmEvent, PVMCPUCC pVCpu, bool fGlobalInit)); 91 DECLR0CALLBACKMEMBER(int, pfnExportHostState, (PVMCPUCC pVCpu)); 89 DECLR0CALLBACKMEMBER(int, pfnEnterSession, (PVMCPUCC pVCpu)); 90 DECLR0CALLBACKMEMBER(void, pfnThreadCtxCallback, (RTTHREADCTXEVENT enmEvent, PVMCPUCC pVCpu, bool fGlobalInit)); 91 DECLR0CALLBACKMEMBER(int, pfnCallRing3Callback, (PVMCPUCC pVCpu, VMMCALLRING3 enmOperation)); 92 DECLR0CALLBACKMEMBER(int, pfnExportHostState, (PVMCPUCC pVCpu)); 92 93 DECLR0CALLBACKMEMBER(VBOXSTRICTRC, pfnRunGuestCode, (PVMCPUCC pVCpu)); 93 DECLR0CALLBACKMEMBER(int, pfnEnableCpu, (PHMPHYSCPU pHostCpu, PVMCC pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage,94 bool fEnabledByHost, PCSUPHWVIRTMSRS pHwvirtMsrs));95 DECLR0CALLBACKMEMBER(int, pfnDisableCpu, (void *pvCpuPage, RTHCPHYS HCPhysCpuPage));96 DECLR0CALLBACKMEMBER(int, pfnInitVM, (PVMCC pVM));97 DECLR0CALLBACKMEMBER(int, pfnTermVM, (PVMCC pVM));98 DECLR0CALLBACKMEMBER(int, pfnSetupVM, (PVMCC pVM));94 DECLR0CALLBACKMEMBER(int, pfnEnableCpu, (PHMPHYSCPU pHostCpu, PVMCC pVM, void *pvCpuPage, RTHCPHYS HCPhysCpuPage, 95 bool fEnabledByHost, PCSUPHWVIRTMSRS pHwvirtMsrs)); 96 DECLR0CALLBACKMEMBER(int, pfnDisableCpu, (void *pvCpuPage, RTHCPHYS HCPhysCpuPage)); 97 DECLR0CALLBACKMEMBER(int, pfnInitVM, (PVMCC pVM)); 98 DECLR0CALLBACKMEMBER(int, pfnTermVM, (PVMCC pVM)); 99 DECLR0CALLBACKMEMBER(int, pfnSetupVM, (PVMCC pVM)); 99 100 /** @} */ 100 101 … … 269 270 } 270 271 272 static DECLCALLBACK(int) hmR0DummyCallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation) 273 { 274 RT_NOREF2(pVCpu, enmOperation); 275 return VINF_SUCCESS; 276 } 277 271 278 static DECLCALLBACK(VBOXSTRICTRC) hmR0DummyRunGuestCode(PVMCPUCC pVCpu) 272 279 { … … 466 473 g_HmR0.pfnEnterSession = VMXR0Enter; 467 474 g_HmR0.pfnThreadCtxCallback = VMXR0ThreadCtxCallback; 475 g_HmR0.pfnCallRing3Callback = VMXR0CallRing3Callback; 468 476 g_HmR0.pfnExportHostState = VMXR0ExportHostState; 469 477 g_HmR0.pfnRunGuestCode = VMXR0RunGuestCode; … … 518 526 g_HmR0.pfnEnterSession = SVMR0Enter; 519 527 g_HmR0.pfnThreadCtxCallback = SVMR0ThreadCtxCallback; 528 g_HmR0.pfnCallRing3Callback = SVMR0CallRing3Callback; 520 529 g_HmR0.pfnExportHostState = SVMR0ExportHostState; 521 530 g_HmR0.pfnRunGuestCode = SVMR0RunGuestCode; … … 588 597 g_HmR0.pfnEnterSession = hmR0DummyEnter; 589 598 g_HmR0.pfnThreadCtxCallback = hmR0DummyThreadCtxCallback; 599 g_HmR0.pfnCallRing3Callback = hmR0DummyCallRing3Callback; 590 600 g_HmR0.pfnExportHostState = hmR0DummyExportHostState; 591 601 g_HmR0.pfnRunGuestCode = hmR0DummyRunGuestCode; … … 1339 1349 1340 1350 /** 1351 * Notification callback before performing a longjump to ring-3. 1352 * 1353 * @returns VBox status code. 1354 * @param pVCpu The cross context virtual CPU structure. 1355 * @param enmOperation The operation causing the ring-3 longjump. 1356 * @param pvUser User argument, currently unused, NULL. 1357 */ 1358 static DECLCALLBACK(int) hmR0CallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation, void *pvUser) 1359 { 1360 RT_NOREF(pvUser); 1361 Assert(pVCpu); 1362 Assert(g_HmR0.pfnCallRing3Callback); 1363 return g_HmR0.pfnCallRing3Callback(pVCpu, enmOperation); 1364 } 1365 1366 1367 /** 1341 1368 * Turns on HM on the CPU if necessary and initializes the bare minimum state 1342 1369 * required for entering HM context. … … 1359 1386 if (!pHostCpu->fConfigured) 1360 1387 rc = hmR0EnableCpu(pVCpu->CTX_SUFF(pVM), idCpu); 1388 1389 /* Register a callback to fire prior to performing a longjmp to ring-3 so HM can disable VT-x/AMD-V if needed. */ 1390 VMMRZCallRing3SetNotification(pVCpu, hmR0CallRing3Callback, NULL /* pvUser */); 1361 1391 1362 1392 /* Reload host-state (back from ring-3/migrated CPUs) and shared guest/host bits. */ … … 1456 1486 pVCpu->hm.s.idEnteredCpu = NIL_RTCPUID; 1457 1487 1488 /* De-register the longjmp-to-ring 3 callback now that we have reliquished hardware resources. */ 1489 VMMRZCallRing3RemoveNotification(pVCpu); 1458 1490 return VINF_SUCCESS; 1459 1491 } -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r80454 r80587 2888 2888 * 2889 2889 * Consider this scenario: #VMEXIT -> VMMRZCallRing3Enable() -> do stuff that causes a longjmp 2890 * -> hmR0SvmCallRing3Callback() -> VMMRZCallRing3Disable() -> hmR0SvmImportGuestState()2890 * -> SVMR0CallRing3Callback() -> VMMRZCallRing3Disable() -> hmR0SvmImportGuestState() 2891 2891 * -> Sets VMCPU_FF_HM_UPDATE_CR3 pending -> return from the longjmp -> continue with #VMEXIT 2892 2892 * handling -> hmR0SvmImportGuestState() and here we are. … … 2945 2945 /* 2946 2946 * !!! IMPORTANT !!! 2947 * If you modify code here, make sure to check whether hmR0SvmCallRing3Callback() needs to be updated too.2947 * If you modify code here, make sure to check whether SVMR0CallRing3Callback() needs to be updated too. 2948 2948 */ 2949 2949 … … 3008 3008 /* 3009 3009 * !!! IMPORTANT !!! 3010 * If you modify code here, make sure to check whether hmR0SvmCallRing3Callback() needs to be updated too.3010 * If you modify code here, make sure to check whether SVMR0CallRing3Callback() needs to be updated too. 3011 3011 */ 3012 3012 … … 3044 3044 * @param pVCpu The cross context virtual CPU structure. 3045 3045 * @param enmOperation The operation causing the ring-3 longjump. 3046 * @param pvUser The user argument, NULL (currently unused). 3047 */ 3048 static DECLCALLBACK(int) hmR0SvmCallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation, void *pvUser) 3049 { 3050 RT_NOREF_PV(pvUser); 3051 3046 */ 3047 VMMR0DECL(int) SVMR0CallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation) 3048 { 3052 3049 if (enmOperation == VMMCALLRING3_VM_R0_ASSERTION) 3053 3050 { … … 3129 3126 hmR0SvmLeaveSession(pVCpu); 3130 3127 STAM_COUNTER_DEC(&pVCpu->hm.s.StatSwitchLongJmpToR3); 3128 3129 /* Thread-context hooks are unregistered at this point!!! */ 3130 /* Ring-3 callback notifications are unregistered at this point!!! */ 3131 3131 3132 3132 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3); … … 3155 3155 3156 3156 STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3); 3157 3158 /* We do -not- want any longjmp notifications after this! We must return to ring-3 ASAP. */3159 VMMRZCallRing3RemoveNotification(pVCpu);3160 3157 VMMRZCallRing3Enable(pVCpu); 3161 3158 … … 4789 4786 * better than a kernel panic. This also disables flushing of the R0-logger instance. 4790 4787 */ 4791 VMMRZCallRing3Disable(pVCpu);4792 VMMRZCallRing3RemoveNotification(pVCpu);4793 4788 hmR0SvmPreRunGuestCommitted(pVCpu, &SvmTransient); 4794 4789 … … 4954 4949 VMMR0DECL(VBOXSTRICTRC) SVMR0RunGuestCode(PVMCPUCC pVCpu) 4955 4950 { 4951 AssertPtr(pVCpu); 4952 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 4956 4953 Assert(VMMRZCallRing3IsEnabled(pVCpu)); 4954 Assert(!ASMAtomicUoReadU64(&pCtx->fExtrn)); 4957 4955 HMSVM_ASSERT_PREEMPT_SAFE(pVCpu); 4958 VMMRZCallRing3SetNotification(pVCpu, hmR0SvmCallRing3Callback, NULL /* pvUser */);4959 4956 4960 4957 uint32_t cLoops = 0; 4961 4958 int rc; 4962 4959 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM 4963 if (!CPUMIsGuestInSvmNestedHwVirtMode( &pVCpu->cpum.GstCtx))4960 if (!CPUMIsGuestInSvmNestedHwVirtMode(pCtx)) 4964 4961 #endif 4965 4962 { … … 4996 4993 /* Prepare to return to ring-3. This will remove longjmp notifications. */ 4997 4994 rc = hmR0SvmExitToRing3(pVCpu, rc); 4995 Assert(!ASMAtomicUoReadU64(&pCtx->fExtrn)); 4998 4996 Assert(!VMMRZCallRing3IsNotificationSet(pVCpu)); 4999 4997 return rc; -
trunk/src/VBox/VMM/VMMR0/HMSVMR0.h
r80274 r80587 41 41 VMMR0DECL(int) SVMR0Enter(PVMCPUCC pVCpu); 42 42 VMMR0DECL(void) SVMR0ThreadCtxCallback(RTTHREADCTXEVENT enmEvent, PVMCPUCC pVCpu, bool fGlobalInit); 43 VMMR0DECL(int) SVMR0CallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation); 43 44 VMMR0DECL(int) SVMR0EnableCpu(PHMPHYSCPU pHostCpu, PVMCC pVM, void *pvPageCpu, RTHCPHYS HCPhysCpuPage, 44 45 bool fEnabledBySystem, PCSUPHWVIRTMSRS pHwvirtMsrs); -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r80580 r80587 7252 7252 { 7253 7253 int rc = VINF_SUCCESS; 7254 PVMCC pVM = pVCpu->CTX_SUFF(pVM);7254 PVMCC pVM = pVCpu->CTX_SUFF(pVM); 7255 7255 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 7256 7256 uint32_t u32Val; … … 7555 7555 * Honor any pending CR3 updates. 7556 7556 * 7557 * Consider this scenario: VM-exit -> VMMRZCallRing3Enable() -> do stuff that causes a longjmp -> hmR0VmxCallRing3Callback()7557 * Consider this scenario: VM-exit -> VMMRZCallRing3Enable() -> do stuff that causes a longjmp -> VMXR0CallRing3Callback() 7558 7558 * -> VMMRZCallRing3Disable() -> hmR0VmxImportGuestState() -> Sets VMCPU_FF_HM_UPDATE_CR3 pending -> return from the longjmp 7559 7559 * -> continue with VM-exit handling -> hmR0VmxImportGuestState() and here we are. … … 7873 7873 /* 7874 7874 * !!! IMPORTANT !!! 7875 * If you modify code here, check whether hmR0VmxCallRing3Callback() needs to be updated too.7875 * If you modify code here, check whether VMXR0CallRing3Callback() needs to be updated too. 7876 7876 */ 7877 7877 … … 8001 8001 /* 8002 8002 * !!! IMPORTANT !!! 8003 * If you modify code here, make sure to check whether hmR0VmxCallRing3Callback() needs to be updated too.8003 * If you modify code here, make sure to check whether VMXR0CallRing3Callback() needs to be updated too. 8004 8004 */ 8005 8005 … … 8010 8010 VMMR0ThreadCtxHookDisable(pVCpu); 8011 8011 8012 /* Leave HM context. This takes care of local init (term) . */8012 /* Leave HM context. This takes care of local init (term) and deregistering the longjmp-to-ring-3 callback. */ 8013 8013 int rc = HMR0LeaveCpu(pVCpu); 8014 8015 8014 HM_RESTORE_PREEMPT(); 8016 8015 return rc; … … 8123 8122 8124 8123 /* Thread-context hooks are unregistered at this point!!! */ 8124 /* Ring-3 callback notifications are unregistered at this point!!! */ 8125 8125 8126 8126 /* Sync recompiler state. */ … … 8150 8150 8151 8151 STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchExitToR3); 8152 8153 /* We do -not- want any longjmp notifications after this! We must return to ring-3 ASAP. */8154 VMMRZCallRing3RemoveNotification(pVCpu);8155 8152 VMMRZCallRing3Enable(pVCpu); 8156 8157 8153 return rc; 8158 8154 } … … 8166 8162 * @param pVCpu The cross context virtual CPU structure. 8167 8163 * @param enmOperation The operation causing the ring-3 longjump. 8168 * @param pvUser User argument, currently unused, NULL. 8169 */ 8170 static DECLCALLBACK(int) hmR0VmxCallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation, void *pvUser) 8171 { 8172 RT_NOREF(pvUser); 8164 */ 8165 VMMR0DECL(int) VMXR0CallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation) 8166 { 8173 8167 if (enmOperation == VMMCALLRING3_VM_R0_ASSERTION) 8174 8168 { … … 8180 8174 VMMRZCallRing3RemoveNotification(pVCpu); 8181 8175 VMMRZCallRing3Disable(pVCpu); 8182 RTTHREADPREEMPTSTATE PreemptState = RTTHREADPREEMPTSTATE_INITIALIZER; 8183 RTThreadPreemptDisable(&PreemptState); 8176 HM_DISABLE_PREEMPT(pVCpu); 8184 8177 8185 8178 PVMXVMCSINFO pVmcsInfo = hmGetVmxActiveVmcsInfo(pVCpu); … … 8208 8201 /** @todo eliminate the need for calling VMMR0ThreadCtxHookDisable here! */ 8209 8202 VMMR0ThreadCtxHookDisable(pVCpu); 8203 8204 /* Leave HM context. This takes care of local init (term). */ 8210 8205 HMR0LeaveCpu(pVCpu); 8211 RTThreadPreemptRestore(&PreemptState);8206 HM_RESTORE_PREEMPT(); 8212 8207 return VINF_SUCCESS; 8213 8208 } 8214 8209 8215 8210 Assert(pVCpu); 8216 Assert(pvUser);8217 8211 Assert(VMMRZCallRing3IsEnabled(pVCpu)); 8218 8212 HMVMX_ASSERT_PREEMPT_SAFE(pVCpu); … … 12363 12357 HMVMX_ASSERT_PREEMPT_SAFE(pVCpu); 12364 12358 12365 VMMRZCallRing3SetNotification(pVCpu, hmR0VmxCallRing3Callback, pCtx);12366 12367 12359 VBOXSTRICTRC rcStrict; 12368 12360 uint32_t cLoops = 0; -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.h
r80274 r80587 33 33 VMMR0DECL(int) VMXR0Enter(PVMCPUCC pVCpu); 34 34 VMMR0DECL(void) VMXR0ThreadCtxCallback(RTTHREADCTXEVENT enmEvent, PVMCPUCC pVCpu, bool fGlobalInit); 35 VMMR0DECL(int) VMXR0CallRing3Callback(PVMCPUCC pVCpu, VMMCALLRING3 enmOperation); 35 36 VMMR0DECL(int) VMXR0EnableCpu(PHMPHYSCPU pHostCpu, PVMCC pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys, 36 37 bool fEnabledBySystem, PCSUPHWVIRTMSRS pHwvirtMsrs); -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r80531 r80587 1015 1015 * @bugref{7726#c19} explains the need for this trick: 1016 1016 * 1017 * hmR0VmxCallRing3Callback/hmR0SvmCallRing3Callback &1017 * VMXR0CallRing3Callback/SVMR0CallRing3Callback & 1018 1018 * hmR0VmxLeaveSession/hmR0SvmLeaveSession disables context hooks during 1019 1019 * longjmp & normal return to ring-3, which opens a window where we may be
Note:
See TracChangeset
for help on using the changeset viewer.

