Changeset 72924 in vbox
- Timestamp:
- Jul 5, 2018 4:14:26 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123474
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/NEMAllNativeTemplate-win.cpp.h
r72917 r72924 151 151 NEM_TMPL_STATIC int nemHCWinCopyStateToHyperV(PVM pVM, PVMCPU pVCpu) 152 152 { 153 # ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 154 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, 0, NULL); 155 AssertLogRelRCReturn(rc, rc); 156 return rc; 157 158 # else 153 # if defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) || defined(NEM_WIN_WITH_RING0_RUNLOOP) 154 # if !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) && defined(NEM_WIN_WITH_RING0_RUNLOOP) 155 if (pVM->nem.s.fUseRing0Runloop) 156 # endif 157 { 158 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, 0, NULL); 159 AssertLogRelRCReturn(rc, rc); 160 return rc; 161 } 162 # endif 163 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 164 159 165 /* 160 166 * The following is very similar to what nemR0WinExportState() does. … … 480 486 NEM_TMPL_STATIC int nemHCWinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, uint64_t fWhat) 481 487 { 482 # ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 483 /* See NEMR0ImportState */ 484 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, fWhat, NULL); 485 if (RT_SUCCESS(rc)) 488 # if defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) || defined(NEM_WIN_WITH_RING0_RUNLOOP) 489 # if !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) && defined(NEM_WIN_WITH_RING0_RUNLOOP) 490 if (pVM->nem.s.fUseRing0Runloop) 491 # endif 492 { 493 /* See NEMR0ImportState */ 494 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, fWhat, NULL); 495 if (RT_SUCCESS(rc)) 496 return rc; 497 if (rc == VERR_NEM_FLUSH_TLB) 498 return PGMFlushTLB(pVCpu, pVCpu->cpum.GstCtx.cr3, true /*fGlobal*/); 499 if (rc == VERR_NEM_CHANGE_PGM_MODE) 500 return PGMChangeMode(pVCpu, pVCpu->cpum.GstCtx.cr0, pVCpu->cpum.GstCtx.cr4, pVCpu->cpum.GstCtx.msrEFER); 501 AssertLogRelRCReturn(rc, rc); 486 502 return rc; 487 if (rc == VERR_NEM_FLUSH_TLB) 488 return PGMFlushTLB(pVCpu, pVCpu->cpum.GstCtx.cr3, true /*fGlobal*/); 489 if (rc == VERR_NEM_CHANGE_PGM_MODE) 490 return PGMChangeMode(pVCpu, pVCpu->cpum.GstCtx.cr0, pVCpu->cpum.GstCtx.cr4, pVCpu->cpum.GstCtx.msrEFER); 491 AssertLogRelRCReturn(rc, rc); 492 return rc; 493 494 # else 503 } 504 # endif 505 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 495 506 WHV_REGISTER_NAME aenmNames[128]; 496 507 … … 1122 1133 1123 1134 #ifdef IN_RING0 1135 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 1124 1136 /** @todo improve and secure this translation */ 1125 1137 PGVM pGVM = GVMMR0ByHandle(pVCpu->pVMR0->hSelf); … … 1130 1142 1131 1143 return nemR0WinImportState(pGVM, &pGVM->aCpus[idCpu], &pVCpu->cpum.GstCtx, fWhat); 1144 # else 1145 RT_NOREF(pVCpu, fWhat); 1146 return VERR_NOT_IMPLEMENTED; 1147 # endif 1132 1148 #else 1133 1149 return nemHCWinCopyStateFromHyperV(pVCpu->pVMR3, pVCpu, fWhat); … … 1153 1169 AssertReturn(VM_IS_NEM_ENABLED(pVM), VERR_NEM_IPE_9); 1154 1170 1155 # ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 1156 /* Call ring-0 and get the values. */ 1157 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_QUERY_CPU_TICK, 0, NULL); 1158 AssertLogRelRCReturn(rc, rc); 1159 *pcTicks = pVCpu->nem.s.Hypercall.QueryCpuTick.cTicks; 1160 if (puAux) 1161 *puAux = pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_TSC_AUX 1162 ? pVCpu->nem.s.Hypercall.QueryCpuTick.uAux : CPUMGetGuestTscAux(pVCpu); 1163 return VINF_SUCCESS; 1164 1165 # else 1171 # if defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) || defined(NEM_WIN_WITH_RING0_RUNLOOP) 1172 # if !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) && defined(NEM_WIN_WITH_RING0_RUNLOOP) 1173 if (pVM->nem.s.fUseRing0Runloop) 1174 # endif 1175 { 1176 /* Call ring-0 and get the values. */ 1177 int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_QUERY_CPU_TICK, 0, NULL); 1178 AssertLogRelRCReturn(rc, rc); 1179 *pcTicks = pVCpu->nem.s.Hypercall.QueryCpuTick.cTicks; 1180 if (puAux) 1181 *puAux = pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_TSC_AUX 1182 ? pVCpu->nem.s.Hypercall.QueryCpuTick.uAux : CPUMGetGuestTscAux(pVCpu); 1183 return VINF_SUCCESS; 1184 } 1185 # endif 1186 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 1166 1187 /* Call the offical API. */ 1167 1188 WHV_REGISTER_NAME aenmNames[2] = { WHvX64RegisterTsc, WHvX64RegisterTscAux }; … … 1177 1198 *pcTicks = pVCpu->cpum.GstCtx.fExtrn & CPUMCTX_EXTRN_TSC_AUX ? aValues[0].Reg64 : CPUMGetGuestTscAux(pVCpu); 1178 1199 return VINF_SUCCESS; 1179 # endif1200 # endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ 1180 1201 #else /* IN_RING0 */ 1202 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 1181 1203 /** @todo improve and secure this translation */ 1182 1204 PGVM pGVM = GVMMR0ByHandle(pVCpu->pVMR0->hSelf); … … 1190 1212 *puAux = CPUMGetGuestTscAux(pVCpu); 1191 1213 return rc; 1214 # else 1215 RT_NOREF(pVCpu, pcTicks, puAux); 1216 return VERR_NOT_IMPLEMENTED; 1217 # endif 1192 1218 #endif /* IN_RING0 */ 1193 1219 } … … 1207 1233 { 1208 1234 #ifdef IN_RING0 1235 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 1209 1236 /** @todo improve and secure this translation */ 1210 1237 PGVM pGVM = GVMMR0ByHandle(pVM->hSelf); … … 1215 1242 1216 1243 return nemR0WinResumeCpuTickOnAll(pGVM, &pGVM->aCpus[idCpu], uPausedTscValue); 1244 # else 1245 RT_NOREF(pVM, pVCpu, uPausedTscValue); 1246 return VERR_NOT_IMPLEMENTED; 1247 # endif 1217 1248 #else /* IN_RING3 */ 1218 1249 VMCPU_ASSERT_EMT_RETURN(pVCpu, VERR_VM_THREAD_NOT_EMT); 1219 1250 AssertReturn(VM_IS_NEM_ENABLED(pVM), VERR_NEM_IPE_9); 1220 1251 1221 # ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 1222 /* Call ring-0 and do it all there. */ 1223 return VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_RESUME_CPU_TICK_ON_ALL, uPausedTscValue, NULL); 1224 1225 # else 1252 # if defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) || defined(NEM_WIN_WITH_RING0_RUNLOOP) 1253 # if !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) && defined(NEM_WIN_WITH_RING0_RUNLOOP) 1254 if (pVM->nem.s.fUseRing0Runloop) 1255 # endif 1256 { 1257 /* Call ring-0 and do it all there. */ 1258 return VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_RESUME_CPU_TICK_ON_ALL, uPausedTscValue, NULL); 1259 } 1260 # endif 1261 # ifndef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 1226 1262 /* 1227 1263 * Call the offical API to do the job. … … 1256 1292 1257 1293 return VINF_SUCCESS; 1258 # endif 1294 # endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ 1259 1295 #endif /* IN_RING3 */ 1260 1296 } … … 1341 1377 1342 1378 1343 #if def NEM_WIN_USE_OUR_OWN_RUN_API1379 #if defined(NEM_WIN_USE_OUR_OWN_RUN_API) || defined(NEM_WIN_WITH_RING0_RUNLOOP) 1344 1380 # ifdef IN_RING3 /* hopefully not needed in ring-0, as we'd need KTHREADs and KeAlertThread. */ 1345 1381 /** … … 1408 1444 } 1409 1445 # endif /* IN_RING3 */ 1410 #endif /* NEM_WIN_USE_OUR_OWN_RUN_API */1446 #endif /* NEM_WIN_USE_OUR_OWN_RUN_API || NEM_WIN_WITH_RING0_RUNLOOP */ 1411 1447 1412 1448 … … 1479 1515 while (0) 1480 1516 1481 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API1517 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 1482 1518 /** 1483 1519 * Translates the execution stat bitfield into a short log string, VID version. … … 1517 1553 SWITCH_IT("RM"); 1518 1554 } 1519 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */1555 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 1520 1556 #undef SWITCH_IT 1521 1557 1522 1558 1523 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API1559 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 1524 1560 /** 1525 1561 * Advances the guest RIP and clear EFLAGS.RF, VID version. … … 1572 1608 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); 1573 1609 } 1574 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */1610 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 1575 1611 1576 1612 … … 1796 1832 1797 1833 1798 #if defined(IN_RING0) && defined(NEM_WIN_ USE_OUR_OWN_RUN_API)1834 #if defined(IN_RING0) && defined(NEM_WIN_TEMPLATE_MODE_OWN_RUN_API) 1799 1835 /** 1800 1836 * Wrapper around nemR0WinImportState that converts VERR_NEM_CHANGE_PGM_MODE and … … 1825 1861 AssertMsgFailedReturn(("%s/%u: nemR0WinImportState failed: %Rrc\n", pszCaller, pGVCpu->idCpu, rc), rc); 1826 1862 } 1827 #endif /* IN_RING0 && NEM_WIN_ USE_OUR_OWN_RUN_API*/1828 1829 #if defined(NEM_WIN_ USE_OUR_OWN_RUN_API) || defined(IN_RING3)1863 #endif /* IN_RING0 && NEM_WIN_TEMPLATE_MODE_OWN_RUN_API*/ 1864 1865 #if defined(NEM_WIN_TEMPLATE_MODE_OWN_RUN_API) || defined(IN_RING3) 1830 1866 /** 1831 1867 * Wrapper around nemR0WinImportStateStrict and nemHCWinCopyStateFromHyperV. … … 1843 1879 if (pVCpu->cpum.GstCtx.fExtrn & fWhat) 1844 1880 { 1845 # ifdef IN_RING01881 # ifdef IN_RING0 1846 1882 return nemR0WinImportStateStrict(pGVCpu->pGVM, pGVCpu, pVCpu, fWhat, pszCaller); 1847 # else1883 # else 1848 1884 RT_NOREF(pGVCpu, pszCaller); 1849 1885 int rc = nemHCWinCopyStateFromHyperV(pVCpu->pVMR3, pVCpu, fWhat); 1850 1886 AssertRCReturn(rc, rc); 1851 # endif1887 # endif 1852 1888 } 1853 1889 return VINF_SUCCESS; 1854 1890 } 1855 #endif /* NEM_WIN_ USE_OUR_OWN_RUN_API || IN_RING3 */1856 1857 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API1891 #endif /* NEM_WIN_TEMPLATE_MODE_OWN_RUN_API || IN_RING3 */ 1892 1893 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 1858 1894 /** 1859 1895 * Copies register state from the X64 intercept message header. … … 1917 1953 pVCpu->cpum.GstCtx.fExtrn &= ~(CPUMCTX_EXTRN_RIP | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT); 1918 1954 } 1919 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */1920 1921 1922 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API1955 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 1956 1957 1958 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 1923 1959 /** 1924 1960 * Deals with memory intercept message. … … 2142 2178 return rcStrict; 2143 2179 } 2144 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */2145 2146 2147 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API2180 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 2181 2182 2183 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 2148 2184 /** 2149 2185 * Deals with I/O port intercept message. … … 2524 2560 return rcStrict; 2525 2561 } 2526 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */2527 2528 2529 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API2562 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 2563 2564 2565 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 2530 2566 /** 2531 2567 * Deals with interrupt window message. … … 2599 2635 return VINF_SUCCESS; 2600 2636 } 2601 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */2602 2603 2604 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API2637 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 2638 2639 2640 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 2605 2641 /** 2606 2642 * Deals with CPUID intercept message. … … 2767 2803 return rcStrict; 2768 2804 } 2769 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */2770 2771 2772 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API2805 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 2806 2807 2808 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 2773 2809 /** 2774 2810 * Deals with MSR intercept message. … … 3051 3087 return rcStrict; 3052 3088 } 3053 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */3089 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 3054 3090 3055 3091 … … 3119 3155 3120 3156 3121 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API3157 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 3122 3158 /** 3123 3159 * Copies state included in a exception intercept message. … … 3166 3202 pVCpu->cpum.GstCtx.fExtrn &= ~CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT; 3167 3203 } 3168 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */3169 3170 3171 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API3204 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 3205 3206 3207 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 3172 3208 /** 3173 3209 * Deals with exception intercept message (HvMessageTypeX64ExceptionIntercept). … … 3399 3435 return rcStrict; 3400 3436 } 3401 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */3402 3403 3404 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API3437 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 3438 3439 3440 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 3405 3441 /** 3406 3442 * Deals with unrecoverable exception (triple fault). … … 3519 3555 3520 3556 } 3521 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */3522 3523 3524 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API3557 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 3558 3559 3560 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 3525 3561 /** 3526 3562 * Handles messages (VM exits). … … 3683 3719 } 3684 3720 } 3685 #endif /* IN_RING3 && !NEM_WIN_ USE_OUR_OWN_RUN_API */3721 #endif /* IN_RING3 && !NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 3686 3722 3687 3723 … … 3740 3776 3741 3777 3742 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API3778 #ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 3743 3779 /** 3744 3780 * Worker for nemHCWinRunGC that stops the execution on the way out. … … 3898 3934 return rcStrict; 3899 3935 } 3900 #endif /* NEM_WIN_ USE_OUR_OWN_RUN_API */3901 3902 #if defined(NEM_WIN_ USE_OUR_OWN_RUN_API) || defined(IN_RING3)3936 #endif /* NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 3937 3938 #if defined(NEM_WIN_TEMPLATE_MODE_OWN_RUN_API) || defined(IN_RING3) 3903 3939 3904 3940 /** … … 4048 4084 * everything every time. This will be optimized later. 4049 4085 */ 4050 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4086 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4051 4087 VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader = (VID_MESSAGE_MAPPING_HEADER volatile *)pVCpu->nem.s.pvMsgSlotMapping; 4052 4088 uint32_t cMillies = 5000; /** @todo lower this later... */ … … 4079 4115 | VMCPU_FF_INTERRUPT_NMI | VMCPU_FF_INTERRUPT_SMI)) 4080 4116 { 4081 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4117 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4082 4118 /* Make sure the CPU isn't executing. */ 4083 4119 if (pVCpu->nem.s.fHandleAndGetFlags == VID_MSHAGN_F_GET_NEXT_MESSAGE) … … 4118 4154 || pVCpu->nem.s.fCurrentInterruptWindows != pVCpu->nem.s.fDesiredInterruptWindows) 4119 4155 { 4120 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4156 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4121 4157 Assert(pVCpu->nem.s.fHandleAndGetFlags != VID_MSHAGN_F_GET_NEXT_MESSAGE /* not running */); 4122 4158 # endif … … 4136 4172 && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK)) 4137 4173 { 4138 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4174 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4139 4175 if (pVCpu->nem.s.fHandleAndGetFlags) 4140 4176 { /* Very likely that the CPU does NOT need starting (pending msg, running). */ } … … 4157 4193 pVCpu->nem.s.fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; 4158 4194 } 4159 # endif /* NEM_WIN_ USE_OUR_OWN_RUN_API */4195 # endif /* NEM_WIN_TEMPLATE_MODE_OWN_RUN_API */ 4160 4196 4161 4197 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED_EXEC_NEM)) 4162 4198 { 4163 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4199 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4164 4200 # ifdef IN_RING0 4165 4201 pVCpu->nem.s.uIoCtlBuf.MsgSlotHandleAndGetNext.iCpu = pGVCpu->idCpu; … … 4189 4225 * Deal with the message. 4190 4226 */ 4191 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4227 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4192 4228 rcStrict = nemHCWinHandleMessage(pVM, pVCpu, pMappingHeader, pGVCpu); 4193 4229 pVCpu->nem.s.fHandleAndGetFlags |= VID_MSHAGN_F_HANDLE_MESSAGE; … … 4206 4242 else 4207 4243 { 4208 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4244 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4209 4245 4210 4246 /* VID.SYS merges STATUS_ALERTED and STATUS_USER_APC into STATUS_TIMEOUT, … … 4263 4299 * state and return to EM. We don't sync back the whole state if we can help it. 4264 4300 */ 4265 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API4301 # ifdef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 4266 4302 if (pVCpu->nem.s.fHandleAndGetFlags == VID_MSHAGN_F_GET_NEXT_MESSAGE) 4267 4303 { … … 4337 4373 } 4338 4374 4339 #endif /* defined(NEM_WIN_ USE_OUR_OWN_RUN_API) || defined(IN_RING3) */4375 #endif /* defined(NEM_WIN_TEMPLATE_MODE_OWN_RUN_API) || defined(IN_RING3) */ 4340 4376 4341 4377 /** -
trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
r72918 r72924 82 82 uint32_t cPages, uint32_t fFlags); 83 83 NEM_TMPL_STATIC int nemR0WinUnmapPages(PGVM pGVM, PGVMCPU pGVCpu, RTGCPHYS GCPhys, uint32_t cPages); 84 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 84 85 NEM_TMPL_STATIC int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx); 85 86 NEM_TMPL_STATIC int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat); 86 87 NEM_TMPL_STATIC int nemR0WinQueryCpuTick(PGVM pGVM, PGVMCPU pGVCpu, uint64_t *pcTicks, uint32_t *pcAux); 87 88 NEM_TMPL_STATIC int nemR0WinResumeCpuTickOnAll(PGVM pGVM, PGVMCPU pGVCpu, uint64_t uPausedTscValue); 89 #endif 88 90 DECLINLINE(NTSTATUS) nemR0NtPerformIoControl(PGVM pGVM, uint32_t uFunction, void *pvInput, uint32_t cbInput, 89 91 void *pvOutput, uint32_t cbOutput); … … 93 95 * Instantate the code we share with ring-0. 94 96 */ 97 #ifdef NEM_WIN_WITH_RING0_RUNLOOP 98 # define NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 99 #else 100 # undef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 101 #endif 95 102 #include "../VMMAll/NEMAllNativeTemplate-win.cpp.h" 103 104 96 105 97 106 /** … … 582 591 583 592 593 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 584 594 /** 585 595 * Worker for NEMR0ExportState. … … 722 732 723 733 /* Segments */ 724 # define COPY_OUT_SEG(a_idx, a_enmName, a_SReg) \734 # define COPY_OUT_SEG(a_idx, a_enmName, a_SReg) \ 725 735 do { \ 726 736 HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[a_idx]); \ … … 1098 1108 pInput->Elements[iReg].Value.Reg64 = pCtx->msrPAT; 1099 1109 iReg++; 1100 # if 0 /** @todo HvX64RegisterMtrrCap is read only? Seems it's not even readable. */1110 # if 0 /** @todo HvX64RegisterMtrrCap is read only? Seems it's not even readable. */ 1101 1111 HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]); 1102 1112 pInput->Elements[iReg].Name = HvX64RegisterMtrrCap; 1103 1113 pInput->Elements[iReg].Value.Reg64 = CPUMGetGuestIa32MtrrCap(pVCpu); 1104 1114 iReg++; 1105 # endif1115 # endif 1106 1116 1107 1117 PCPUMCTXMSRS pCtxMsrs = CPUMQueryGuestCtxMsrsPtr(pVCpu); … … 1163 1173 iReg++; 1164 1174 1165 # if 0 /** @todo Why can't we write these on Intel systems? Not that we really care... */1175 # if 0 /** @todo Why can't we write these on Intel systems? Not that we really care... */ 1166 1176 const CPUMCPUVENDOR enmCpuVendor = CPUMGetHostCpuVendor(pGVM->pVM); 1167 1177 if (enmCpuVendor != CPUMCPUVENDOR_AMD) … … 1176 1186 iReg++; 1177 1187 } 1178 # endif1188 # endif 1179 1189 } 1180 1190 … … 1260 1270 return VINF_SUCCESS; 1261 1271 } 1272 #endif /* NEM_WIN_WITH_RING0_RUNLOOP || NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ 1262 1273 1263 1274 … … 1273 1284 VMMR0_INT_DECL(int) NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu) 1274 1285 { 1286 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 1275 1287 /* 1276 1288 * Validate the call. … … 1289 1301 } 1290 1302 return rc; 1303 #else 1304 RT_NOREF(pGVM, pVM, idCpu); 1305 return VERR_NOT_IMPLEMENTED; 1306 #endif 1291 1307 } 1292 1308 1293 1309 1310 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 1294 1311 /** 1295 1312 * Worker for NEMR0ImportState. … … 1470 1487 } 1471 1488 1472 # ifdef LOG_ENABLED1489 # ifdef LOG_ENABLED 1473 1490 const CPUMCPUVENDOR enmCpuVendor = CPUMGetHostCpuVendor(pGVM->pVM); 1474 # endif1491 # endif 1475 1492 if (fWhat & CPUMCTX_EXTRN_OTHER_MSRS) 1476 1493 { 1477 1494 pInput->Names[iReg++] = HvX64RegisterApicBase; /// @todo APIC BASE 1478 1495 pInput->Names[iReg++] = HvX64RegisterPat; 1479 # if 0 /*def LOG_ENABLED*/ /** @todo something's wrong with HvX64RegisterMtrrCap? (AMD) */1496 # if 0 /*def LOG_ENABLED*/ /** @todo something's wrong with HvX64RegisterMtrrCap? (AMD) */ 1480 1497 pInput->Names[iReg++] = HvX64RegisterMtrrCap; 1481 # endif1498 # endif 1482 1499 pInput->Names[iReg++] = HvX64RegisterMtrrDefType; 1483 1500 pInput->Names[iReg++] = HvX64RegisterMtrrFix64k00000; … … 1493 1510 pInput->Names[iReg++] = HvX64RegisterMtrrFix4kF8000; 1494 1511 pInput->Names[iReg++] = HvX64RegisterTscAux; 1495 # if 0 /** @todo why can't we read HvX64RegisterIa32MiscEnable? */1512 # if 0 /** @todo why can't we read HvX64RegisterIa32MiscEnable? */ 1496 1513 if (enmCpuVendor != CPUMCPUVENDOR_AMD) 1497 1514 pInput->Names[iReg++] = HvX64RegisterIa32MiscEnable; 1498 # endif1499 # ifdef LOG_ENABLED1515 # endif 1516 # ifdef LOG_ENABLED 1500 1517 if (enmCpuVendor != CPUMCPUVENDOR_AMD) 1501 1518 pInput->Names[iReg++] = HvX64RegisterIa32FeatureControl; 1502 # endif1519 # endif 1503 1520 } 1504 1521 … … 1609 1626 1610 1627 /* Segments */ 1611 # define COPY_BACK_SEG(a_idx, a_enmName, a_SReg) \1628 # define COPY_BACK_SEG(a_idx, a_enmName, a_SReg) \ 1612 1629 do { \ 1613 1630 Assert(pInput->Names[a_idx] == a_enmName); \ … … 1989 2006 iReg++; 1990 2007 1991 # if 0 /*def LOG_ENABLED*/ /** @todo something's wrong with HvX64RegisterMtrrCap? (AMD) */2008 # if 0 /*def LOG_ENABLED*/ /** @todo something's wrong with HvX64RegisterMtrrCap? (AMD) */ 1992 2009 Assert(pInput->Names[iReg] == HvX64RegisterMtrrCap); 1993 2010 if (paValues[iReg].Reg64 != CPUMGetGuestIa32MtrrCap(pVCpu)) 1994 2011 Log7(("NEM/%u: MSR MTRR_CAP changed %RX64 -> %RX64 (!!)\n", pVCpu->idCpu, CPUMGetGuestIa32MtrrCap(pVCpu), paValues[iReg].Reg64)); 1995 2012 iReg++; 1996 # endif2013 # endif 1997 2014 1998 2015 PCPUMCTXMSRS pCtxMsrs = CPUMQueryGuestCtxMsrsPtr(pVCpu); … … 2077 2094 iReg++; 2078 2095 2079 # if 0 /** @todo why can't we even read HvX64RegisterIa32MiscEnable? */2096 # if 0 /** @todo why can't we even read HvX64RegisterIa32MiscEnable? */ 2080 2097 if (enmCpuVendor != CPUMCPUVENDOR_AMD) 2081 2098 { … … 2086 2103 iReg++; 2087 2104 } 2088 # endif2089 # ifdef LOG_ENABLED2105 # endif 2106 # ifdef LOG_ENABLED 2090 2107 if (enmCpuVendor != CPUMCPUVENDOR_AMD) 2091 2108 { … … 2095 2112 iReg++; 2096 2113 } 2097 # endif2114 # endif 2098 2115 } 2099 2116 … … 2179 2196 return rc; 2180 2197 } 2198 #endif /* NEM_WIN_WITH_RING0_RUNLOOP || NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ 2181 2199 2182 2200 … … 2194 2212 VMMR0_INT_DECL(int) NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat) 2195 2213 { 2214 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 2196 2215 /* 2197 2216 * Validate the call. … … 2210 2229 } 2211 2230 return rc; 2231 #else 2232 RT_NOREF(pGVM, pVM, idCpu, fWhat); 2233 return VERR_NOT_IMPLEMENTED; 2234 #endif 2212 2235 } 2213 2236 2214 2237 2238 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 2215 2239 /** 2216 2240 * Worker for NEMR0QueryCpuTick and the ring-0 NEMHCQueryCpuTick. … … 2258 2282 return VINF_SUCCESS; 2259 2283 } 2284 #endif /* NEM_WIN_WITH_RING0_RUNLOOP || NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ 2260 2285 2261 2286 … … 2271 2296 VMMR0_INT_DECL(int) NEMR0QueryCpuTick(PGVM pGVM, PVM pVM, VMCPUID idCpu) 2272 2297 { 2298 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 2273 2299 /* 2274 2300 * Validate the call. … … 2290 2316 } 2291 2317 return rc; 2318 #else 2319 RT_NOREF(pGVM, pVM, idCpu); 2320 return VERR_NOT_IMPLEMENTED; 2321 #endif 2292 2322 } 2293 2323 2294 2324 2325 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 2295 2326 /** 2296 2327 * Worker for NEMR0ResumeCpuTickOnAll and the ring-0 NEMHCResumeCpuTickOnAll. … … 2360 2391 return VINF_SUCCESS; 2361 2392 } 2393 #endif /* NEM_WIN_WITH_RING0_RUNLOOP || NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ 2362 2394 2363 2395 … … 2374 2406 VMMR0_INT_DECL(int) NEMR0ResumeCpuTickOnAll(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t uPausedTscValue) 2375 2407 { 2408 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 2376 2409 /* 2377 2410 * Validate the call. … … 2392 2425 } 2393 2426 return rc; 2427 #else 2428 RT_NOREF(pGVM, pVM, idCpu, uPausedTscValue); 2429 return VERR_NOT_IMPLEMENTED; 2430 #endif 2394 2431 } 2395 2432 … … 2397 2434 VMMR0_INT_DECL(VBOXSTRICTRC) NEMR0RunGuestCode(PGVM pGVM, VMCPUID idCpu) 2398 2435 { 2399 #ifdef NEM_WIN_ USE_OUR_OWN_RUN_API2436 #ifdef NEM_WIN_WITH_RING0_RUNLOOP 2400 2437 PVM pVM = pGVM->pVM; 2401 2438 return nemHCWinRunGC(pVM, &pVM->aCpus[idCpu], pGVM, &pGVM->aCpus[idCpu]); -
trunk/src/VBox/VMM/VMMR3/NEMR3.cpp
r72634 r72924 78 78 "/NEM/", 79 79 "Enabled" 80 "|Allow64BitGuests", 80 "|Allow64BitGuests" 81 #ifdef RT_OS_WINDOWS 82 "|UseRing0Runloop" 83 #endif 84 , 81 85 "" /* pszValidNodes */, "NEM" /* pszWho */, 0 /* uInstance */); 82 86 if (RT_FAILURE(rc)) … … 90 94 91 95 #ifdef VBOX_WITH_64_BITS_GUESTS 92 /** @cfgm{/ HM/Allow64BitGuests, bool, 32-bit:false, 64-bit:true}96 /** @cfgm{/NEM/Allow64BitGuests, bool, 32-bit:false, 64-bit:true} 93 97 * Enables AMD64 CPU features. 94 98 * On 32-bit hosts this isn't default and require host CPU support. 64-bit hosts … … 100 104 #endif 101 105 106 #ifdef RT_OS_WINDOWS 107 /** @cfgm{/NEM/UseRing0Runloop, bool, true} 108 * Whether to use the ring-0 runloop (if enabled in the build) or the ring-3 one. 109 * The latter is generally slower. This option serves as a way out in case 110 * something breaks in the ring-0 loop. */ 111 # ifdef NEM_WIN_USE_RING0_RUNLOOP_BY_DEFAULT 112 bool fUseRing0Runloop = true; 113 # else 114 bool fUseRing0Runloop = false; 115 # endif 116 rc = CFGMR3QueryBoolDef(pCfgNem, "UseRing0Runloop", &fUseRing0Runloop, fUseRing0Runloop); 117 AssertLogRelRCReturn(rc, rc); 118 pVM->nem.s.fUseRing0Runloop = fUseRing0Runloop; 119 #endif 102 120 103 121 return VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r72918 r72924 234 234 * Instantate the code we share with ring-0. 235 235 */ 236 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 237 # define NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 238 #else 239 # undef NEM_WIN_TEMPLATE_MODE_OWN_RUN_API 240 #endif 236 241 #include "../VMMAll/NEMAllNativeTemplate-win.cpp.h" 237 242 … … 1388 1393 Assert((HANDLE)pVCpu->nem.s.hNativeThreadHandle != INVALID_HANDLE_VALUE); 1389 1394 1390 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 1391 VID_MAPPED_MESSAGE_SLOT MappedMsgSlot = { NULL, UINT32_MAX, UINT32_MAX }; 1392 if (g_pfnVidMessageSlotMap(hPartitionDevice, &MappedMsgSlot, iCpu)) 1395 #ifndef NEM_WIN_USE_OUR_OWN_RUN_API 1396 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 1397 if (!pVM->nem.s.fUseRing0Runloop) 1398 # endif 1393 1399 { 1394 AssertLogRelMsg(MappedMsgSlot.iCpu == iCpu && MappedMsgSlot.uParentAdvisory == UINT32_MAX, 1395 ("%#x %#x (iCpu=%#x)\n", MappedMsgSlot.iCpu, MappedMsgSlot.uParentAdvisory, iCpu)); 1396 pVCpu->nem.s.pvMsgSlotMapping = MappedMsgSlot.pMsgBlock; 1400 hrc = WHvCreateVirtualProcessor(hPartition, iCpu, 0 /*fFlags*/); 1401 if (FAILED(hrc)) 1402 { 1403 NTSTATUS const rcNtLast = RTNtLastStatusValue(); 1404 DWORD const dwErrLast = RTNtLastErrorValue(); 1405 while (iCpu-- > 0) 1406 { 1407 HRESULT hrc2 = WHvDeleteVirtualProcessor(hPartition, iCpu); 1408 AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 1409 hPartition, iCpu, hrc2, RTNtLastStatusValue(), 1410 RTNtLastErrorValue())); 1411 } 1412 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 1413 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast); 1414 } 1397 1415 } 1416 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 1398 1417 else 1418 # endif 1419 #endif /* !NEM_WIN_USE_OUR_OWN_RUN_API */ 1420 #if defined(NEM_WIN_WITH_RING0_RUNLOOP) || defined(NEM_WIN_USE_OUR_OWN_RUN_API) 1399 1421 { 1400 NTSTATUS const rcNtLast = RTNtLastStatusValue(); 1401 DWORD const dwErrLast = RTNtLastErrorValue(); 1402 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 1403 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast); 1422 VID_MAPPED_MESSAGE_SLOT MappedMsgSlot = { NULL, UINT32_MAX, UINT32_MAX }; 1423 if (g_pfnVidMessageSlotMap(hPartitionDevice, &MappedMsgSlot, iCpu)) 1424 { 1425 AssertLogRelMsg(MappedMsgSlot.iCpu == iCpu && MappedMsgSlot.uParentAdvisory == UINT32_MAX, 1426 ("%#x %#x (iCpu=%#x)\n", MappedMsgSlot.iCpu, MappedMsgSlot.uParentAdvisory, iCpu)); 1427 pVCpu->nem.s.pvMsgSlotMapping = MappedMsgSlot.pMsgBlock; 1428 } 1429 else 1430 { 1431 NTSTATUS const rcNtLast = RTNtLastStatusValue(); 1432 DWORD const dwErrLast = RTNtLastErrorValue(); 1433 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 1434 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast); 1435 } 1404 1436 } 1405 #else 1406 hrc = WHvCreateVirtualProcessor(hPartition, iCpu, 0 /*fFlags*/); 1407 if (FAILED(hrc)) 1408 { 1409 NTSTATUS const rcNtLast = RTNtLastStatusValue(); 1410 DWORD const dwErrLast = RTNtLastErrorValue(); 1411 while (iCpu-- > 0) 1412 { 1413 HRESULT hrc2 = WHvDeleteVirtualProcessor(hPartition, iCpu); 1414 AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 1415 hPartition, iCpu, hrc2, RTNtLastStatusValue(), 1416 RTNtLastErrorValue())); 1417 } 1418 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 1419 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast); 1420 } 1421 #endif /* !NEM_WIN_USE_OUR_OWN_RUN_API */ 1437 #endif 1422 1438 } 1423 1439 pVM->nem.s.fCreatedEmts = true; … … 1583 1599 while (iCpu-- > 0) 1584 1600 { 1585 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API1586 1601 pVM->aCpus[iCpu].nem.s.pvMsgSlotMapping = NULL; 1587 #else 1588 HRESULT hrc = WHvDeleteVirtualProcessor(hPartition, iCpu); 1589 AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 1590 hPartition, iCpu, hrc, RTNtLastStatusValue(), 1591 RTNtLastErrorValue())); 1602 #ifndef NEM_WIN_USE_OUR_OWN_RUN_API 1603 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 1604 if (!pVM->nem.s.fUseRing0Runloop) 1605 # endif 1606 { 1607 HRESULT hrc = WHvDeleteVirtualProcessor(hPartition, iCpu); 1608 AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 1609 hPartition, iCpu, hrc, RTNtLastStatusValue(), 1610 RTNtLastErrorValue())); 1611 } 1592 1612 #endif 1593 1613 } … … 1634 1654 VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu) 1635 1655 { 1636 #if !defined(NEM_WIN_USE_OUR_OWN_RUN_API) || 0 1637 return nemHCWinRunGC(pVM, pVCpu, NULL /*pGVM*/, NULL /*pGVCpu*/); 1638 #else 1639 for (;;) 1656 #ifdef NEM_WIN_WITH_RING0_RUNLOOP 1657 if (pVM->nem.s.fUseRing0Runloop) 1640 1658 { 1641 VBOXSTRICTRC rcStrict = VMMR3CallR0EmtFast(pVM, pVCpu, VMMR0_DO_NEM_RUN); 1642 if (RT_SUCCESS(rcStrict)) 1659 for (;;) 1643 1660 { 1644 /* 1645 * We deal with VINF_NEM_CHANGE_PGM_MODE, VINF_NEM_FLUSH_TLB and 1646 * VINF_NEM_UPDATE_APIC_BASE here, since we're running the risk of 1647 * getting these while we already got another RC (I/O ports). 1648 * 1649 * The APIC base update and a PGM update can happen at the same time, so 1650 * we don't depend on the status code for that and always checks it first. 1651 */ 1652 /* APIC base: */ 1653 if (pVCpu->nem.s.uPendingApicBase != UINT64_MAX) 1661 VBOXSTRICTRC rcStrict = VMMR3CallR0EmtFast(pVM, pVCpu, VMMR0_DO_NEM_RUN); 1662 if (RT_SUCCESS(rcStrict)) 1654 1663 { 1655 LogFlow(("nemR3NativeRunGC: calling APICSetBaseMsr(,%RX64)...\n", pVCpu->nem.s.uPendingApicBase)); 1656 VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, pVCpu->nem.s.uPendingApicBase); 1657 AssertLogRelMsg(rc2 == VINF_SUCCESS, ("rc2=%Rrc [%#RX64]\n", VBOXSTRICTRC_VAL(rc2), pVCpu->nem.s.uPendingApicBase)); 1658 pVCpu->nem.s.uPendingApicBase = UINT64_MAX; 1659 } 1660 1661 /* Status codes: */ 1662 VBOXSTRICTRC rcPending = pVCpu->nem.s.rcPending; 1663 pVCpu->nem.s.rcPending = VINF_SUCCESS; 1664 if ( rcStrict == VINF_NEM_CHANGE_PGM_MODE 1665 || rcStrict == VINF_PGM_CHANGE_MODE 1666 || rcPending == VINF_NEM_CHANGE_PGM_MODE ) 1667 { 1668 LogFlow(("nemR3NativeRunGC: calling PGMChangeMode...\n")); 1669 int rc = PGMChangeMode(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR4(pVCpu), CPUMGetGuestEFER(pVCpu)); 1670 AssertRCReturn(rc, rc); 1664 /* 1665 * We deal with VINF_NEM_CHANGE_PGM_MODE, VINF_NEM_FLUSH_TLB and 1666 * VINF_NEM_UPDATE_APIC_BASE here, since we're running the risk of 1667 * getting these while we already got another RC (I/O ports). 1668 * 1669 * The APIC base update and a PGM update can happen at the same time, so 1670 * we don't depend on the status code for that and always checks it first. 1671 */ 1672 /* APIC base: */ 1673 if (pVCpu->nem.s.uPendingApicBase != UINT64_MAX) 1674 { 1675 LogFlow(("nemR3NativeRunGC: calling APICSetBaseMsr(,%RX64)...\n", pVCpu->nem.s.uPendingApicBase)); 1676 VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, pVCpu->nem.s.uPendingApicBase); 1677 AssertLogRelMsg(rc2 == VINF_SUCCESS, ("rc2=%Rrc [%#RX64]\n", VBOXSTRICTRC_VAL(rc2), pVCpu->nem.s.uPendingApicBase)); 1678 pVCpu->nem.s.uPendingApicBase = UINT64_MAX; 1679 } 1680 1681 /* Status codes: */ 1682 VBOXSTRICTRC rcPending = pVCpu->nem.s.rcPending; 1683 pVCpu->nem.s.rcPending = VINF_SUCCESS; 1671 1684 if ( rcStrict == VINF_NEM_CHANGE_PGM_MODE 1672 1685 || rcStrict == VINF_PGM_CHANGE_MODE 1673 || rc Strict == VINF_NEM_FLUSH_TLB)1686 || rcPending == VINF_NEM_CHANGE_PGM_MODE ) 1674 1687 { 1675 if ( !VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK | VM_FF_HP_R0_PRE_HM_MASK) 1676 && !VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_HIGH_PRIORITY_POST_MASK | VMCPU_FF_HP_R0_PRE_HM_MASK) 1677 & ~VMCPU_FF_RESUME_GUEST_MASK)) 1688 LogFlow(("nemR3NativeRunGC: calling PGMChangeMode...\n")); 1689 int rc = PGMChangeMode(pVCpu, CPUMGetGuestCR0(pVCpu), CPUMGetGuestCR4(pVCpu), CPUMGetGuestEFER(pVCpu)); 1690 AssertRCReturn(rc, rc); 1691 if ( rcStrict == VINF_NEM_CHANGE_PGM_MODE 1692 || rcStrict == VINF_PGM_CHANGE_MODE 1693 || rcStrict == VINF_NEM_FLUSH_TLB) 1678 1694 { 1679 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK); 1680 continue; 1695 if ( !VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK | VM_FF_HP_R0_PRE_HM_MASK) 1696 && !VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_HIGH_PRIORITY_POST_MASK | VMCPU_FF_HP_R0_PRE_HM_MASK) 1697 & ~VMCPU_FF_RESUME_GUEST_MASK)) 1698 { 1699 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK); 1700 continue; 1701 } 1702 rcStrict = VINF_SUCCESS; 1681 1703 } 1682 rcStrict = VINF_SUCCESS;1683 1704 } 1705 else if (rcStrict == VINF_NEM_FLUSH_TLB || rcPending == VINF_NEM_FLUSH_TLB) 1706 { 1707 LogFlow(("nemR3NativeRunGC: calling PGMFlushTLB...\n")); 1708 int rc = PGMFlushTLB(pVCpu, CPUMGetGuestCR3(pVCpu), true); 1709 AssertRCReturn(rc, rc); 1710 if (rcStrict == VINF_NEM_FLUSH_TLB || rcStrict == VINF_NEM_CHANGE_PGM_MODE) 1711 { 1712 if ( !VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK | VM_FF_HP_R0_PRE_HM_MASK) 1713 && !VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_HIGH_PRIORITY_POST_MASK | VMCPU_FF_HP_R0_PRE_HM_MASK) 1714 & ~VMCPU_FF_RESUME_GUEST_MASK)) 1715 { 1716 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK); 1717 continue; 1718 } 1719 rcStrict = VINF_SUCCESS; 1720 } 1721 } 1722 else if (rcStrict == VINF_NEM_UPDATE_APIC_BASE || rcPending == VERR_NEM_UPDATE_APIC_BASE) 1723 continue; 1724 else 1725 AssertMsg(rcPending == VINF_SUCCESS, ("rcPending=%Rrc\n", VBOXSTRICTRC_VAL(rcPending) )); 1684 1726 } 1685 else if (rcStrict == VINF_NEM_FLUSH_TLB || rcPending == VINF_NEM_FLUSH_TLB) 1686 { 1687 LogFlow(("nemR3NativeRunGC: calling PGMFlushTLB...\n")); 1688 int rc = PGMFlushTLB(pVCpu, CPUMGetGuestCR3(pVCpu), true); 1689 AssertRCReturn(rc, rc); 1690 if (rcStrict == VINF_NEM_FLUSH_TLB || rcStrict == VINF_NEM_CHANGE_PGM_MODE) 1691 { 1692 if ( !VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK | VM_FF_HP_R0_PRE_HM_MASK) 1693 && !VMCPU_FF_IS_PENDING(pVCpu, (VMCPU_FF_HIGH_PRIORITY_POST_MASK | VMCPU_FF_HP_R0_PRE_HM_MASK) 1694 & ~VMCPU_FF_RESUME_GUEST_MASK)) 1695 { 1696 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK); 1697 continue; 1698 } 1699 rcStrict = VINF_SUCCESS; 1700 } 1701 } 1702 else if (rcStrict == VINF_NEM_UPDATE_APIC_BASE || rcPending == VERR_NEM_UPDATE_APIC_BASE) 1703 continue; 1704 else 1705 AssertMsg(rcPending == VINF_SUCCESS, ("rcPending=%Rrc\n", VBOXSTRICTRC_VAL(rcPending) )); 1727 LogFlow(("nemR3NativeRunGC: returns %Rrc\n", VBOXSTRICTRC_VAL(rcStrict) )); 1728 return rcStrict; 1706 1729 } 1707 LogFlow(("nemR3NativeRunGC: returns %Rrc\n", VBOXSTRICTRC_VAL(rcStrict) ));1708 return rcStrict;1709 1730 } 1710 1731 #endif 1732 return nemHCWinRunGC(pVM, pVCpu, NULL /*pGVM*/, NULL /*pGVCpu*/); 1711 1733 } 1712 1734 … … 1741 1763 nemHCWinCancelRunVirtualProcessor(pVM, pVCpu); 1742 1764 #else 1743 Log8(("nemR3NativeNotifyFF: canceling %u\n", pVCpu->idCpu)); 1744 HRESULT hrc = WHvCancelRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, 0); 1745 AssertMsg(SUCCEEDED(hrc), ("WHvCancelRunVirtualProcessor -> hrc=%Rhrc\n", hrc)); 1746 RT_NOREF_PV(hrc); 1765 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 1766 if (pVM->nem.s.fUseRing0Runloop) 1767 nemHCWinCancelRunVirtualProcessor(pVM, pVCpu); 1768 else 1769 # endif 1770 { 1771 Log8(("nemR3NativeNotifyFF: canceling %u\n", pVCpu->idCpu)); 1772 HRESULT hrc = WHvCancelRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, 0); 1773 AssertMsg(SUCCEEDED(hrc), ("WHvCancelRunVirtualProcessor -> hrc=%Rhrc\n", hrc)); 1774 RT_NOREF_PV(hrc); 1775 } 1747 1776 #endif 1748 1777 RT_NOREF_PV(fFlags); -
trunk/src/VBox/VMM/include/NEMInternal.h
r72690 r72924 45 45 */ 46 46 # define NEM_WIN_USE_HYPERCALLS_FOR_PAGES 47 # define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS 48 # define NEM_WIN_USE_OUR_OWN_RUN_API 47 //# define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS /**< Applies to ring-3 code only. Useful for testing VID API. */ 48 //# define NEM_WIN_USE_OUR_OWN_RUN_API /**< Applies to ring-3 code only. Useful for testing VID API. */ 49 # define NEM_WIN_WITH_RING0_RUNLOOP /**< Enables the ring-0 runloop. */ 50 # define NEM_WIN_USE_RING0_RUNLOOP_BY_DEFAULT /**< For quickly testing ring-3 API without messing with CFGM. */ 49 51 # if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS) 50 52 # error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS" … … 52 54 # if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) 53 55 # error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_PAGES" 56 # endif 57 # if defined(NEM_WIN_WITH_RING0_RUNLOOP) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES) 58 # error "NEM_WIN_WITH_RING0_RUNLOOP requires NEM_WIN_USE_HYPERCALLS_FOR_PAGES" 54 59 # endif 55 60 … … 148 153 /** WHvRunVpExitReasonException is supported. */ 149 154 bool fExtendedXcptExit : 1; 155 /** Set if we're using the ring-0 API to do the work. */ 156 bool fUseRing0Runloop : 1; 150 157 /** Set if we've started more than one CPU and cannot mess with A20. */ 151 158 bool fA20Fixed : 1; … … 228 235 * This is set to UINT64_MAX when not pending */ 229 236 uint64_t uPendingApicBase; 230 # ifdef NEM_WIN_ USE_OUR_OWN_RUN_API237 # ifdef NEM_WIN_WITH_RING0_RUNLOOP 231 238 /** Pending VINF_NEM_CHANGE_PGM_MODE, VINF_NEM_FLUSH_TLB or VINF_NEM_UPDATE_APIC_BASE. */ 232 239 int32_t rcPending; 240 # else 241 uint32_t uPadding; 242 # endif 233 243 /** The VID_MSHAGN_F_XXX flags. 234 244 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */ … … 236 246 /** What VidMessageSlotMap returns and is used for passing exit info. */ 237 247 RTR3PTR pvMsgSlotMapping; 238 # endif239 248 /** The windows thread handle. */ 240 249 RTR3PTR hNativeThreadHandle;
Note:
See TracChangeset
for help on using the changeset viewer.