Changeset 72546 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Jun 13, 2018 3:45:39 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123036
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
r72544 r72546 84 84 NEM_TMPL_STATIC int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat); 85 85 NEM_TMPL_STATIC int nemR0WinQueryCpuTick(PGVM pGVM, PGVMCPU pGVCpu, uint64_t *pcTicks, uint32_t *pcAux); 86 NEM_TMPL_STATIC int nemR0WinResumeCpuTickOnAll(PGVM pGVM, PGVMCPU pGVCpu, uint64_t uPausedTscValue); 86 87 DECLINLINE(NTSTATUS) nemR0NtPerformIoControl(PGVM pGVM, uint32_t uFunction, void *pvInput, uint32_t cbInput, 87 88 void *pvOutput, uint32_t cbOutput); … … 595 596 HV_INPUT_SET_VP_REGISTERS *pInput = (HV_INPUT_SET_VP_REGISTERS *)pGVCpu->nem.s.HypercallData.pbPage; 596 597 AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3); 598 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 597 599 598 600 pInput->PartitionId = pGVM->nem.s.idHvPartition; … … 1304 1306 HV_INPUT_GET_VP_REGISTERS *pInput = (HV_INPUT_GET_VP_REGISTERS *)pGVCpu->nem.s.HypercallData.pbPage; 1305 1307 AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3); 1308 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 1306 1309 1307 1310 fWhat &= pCtx->fExtrn; … … 2222 2225 HV_INPUT_GET_VP_REGISTERS *pInput = (HV_INPUT_GET_VP_REGISTERS *)pGVCpu->nem.s.HypercallData.pbPage; 2223 2226 AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3); 2227 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 2224 2228 2225 2229 pInput->PartitionId = pGVM->nem.s.idHvPartition; … … 2280 2284 rc = nemR0WinQueryCpuTick(pGVM, pGVCpu, &pVCpu->nem.s.Hypercall.QueryCpuTick.cTicks, 2281 2285 &pVCpu->nem.s.Hypercall.QueryCpuTick.uAux); 2286 } 2287 return rc; 2288 } 2289 2290 2291 /** 2292 * Worker for NEMR0ResumeCpuTickOnAll and the ring-0 NEMHCResumeCpuTickOnAll. 2293 * 2294 * @returns VBox status code. 2295 * @param pGVM The ring-0 VM handle. 2296 * @param pGVCpu The ring-0 VCPU handle. 2297 * @param uPausedTscValue The TSC value at the time of pausing. 2298 */ 2299 NEM_TMPL_STATIC int nemR0WinResumeCpuTickOnAll(PGVM pGVM, PGVMCPU pGVCpu, uint64_t uPausedTscValue) 2300 { 2301 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 2302 2303 /* 2304 * Set up the hypercall parameters. 2305 */ 2306 HV_INPUT_SET_VP_REGISTERS *pInput = (HV_INPUT_SET_VP_REGISTERS *)pGVCpu->nem.s.HypercallData.pbPage; 2307 AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3); 2308 2309 pInput->PartitionId = pGVM->nem.s.idHvPartition; 2310 pInput->VpIndex = 0; 2311 pInput->RsvdZ = 0; 2312 pInput->Elements[0].Name = HvX64RegisterTsc; 2313 pInput->Elements[0].Pad0 = 0; 2314 pInput->Elements[0].Pad1 = 0; 2315 pInput->Elements[0].Value.Reg128.High64 = 0; 2316 pInput->Elements[0].Value.Reg64 = uPausedTscValue; 2317 2318 /* 2319 * Disable interrupts and do the first virtual CPU. 2320 */ 2321 RTCCINTREG const fSavedFlags = ASMIntDisableFlags(); 2322 uint64_t const uFirstTsc = ASMReadTSC(); 2323 uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallSetVpRegisters, 1), 2324 pGVCpu->nem.s.HypercallData.HCPhysPage, 0 /* no output */); 2325 AssertLogRelMsgReturnStmt(uResult == HV_MAKE_CALL_REP_RET(1), ("uResult=%RX64 uTsc=%#RX64\n", uResult, uPausedTscValue), 2326 ASMSetFlags(fSavedFlags), VERR_NEM_SET_TSC); 2327 2328 /* 2329 * Do secondary processors, adjusting for elapsed TSC and keeping finger crossed 2330 * that we don't introduce too much drift here. 2331 */ 2332 for (VMCPUID iCpu = 1; iCpu < pGVM->cCpus; iCpu++) 2333 { 2334 Assert(pInput->PartitionId == pGVM->nem.s.idHvPartition); 2335 Assert(pInput->RsvdZ == 0); 2336 Assert(pInput->Elements[0].Name == HvX64RegisterTsc); 2337 Assert(pInput->Elements[0].Pad0 == 0); 2338 Assert(pInput->Elements[0].Pad1 == 0); 2339 Assert(pInput->Elements[0].Value.Reg128.High64 == 0); 2340 2341 pInput->VpIndex = iCpu; 2342 const uint64_t offDelta = (ASMReadTSC() - uFirstTsc); 2343 pInput->Elements[0].Value.Reg64 = uPausedTscValue + offDelta; 2344 2345 uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallSetVpRegisters, 1), 2346 pGVCpu->nem.s.HypercallData.HCPhysPage, 0 /* no output */); 2347 AssertLogRelMsgReturnStmt(uResult == HV_MAKE_CALL_REP_RET(1), 2348 ("uResult=%RX64 uTsc=%#RX64 + %#RX64\n", uResult, uPausedTscValue, offDelta), 2349 ASMSetFlags(fSavedFlags), VERR_NEM_SET_TSC); 2350 } 2351 2352 /* 2353 * Done. 2354 */ 2355 ASMSetFlags(fSavedFlags); 2356 return VINF_SUCCESS; 2357 } 2358 2359 2360 /** 2361 * Sets the TSC register to @a uPausedTscValue on all CPUs. 2362 * 2363 * @returns VBox status code 2364 * @param pGVM The ring-0 VM handle. 2365 * @param pVM The cross context VM handle. 2366 * @param idCpu The calling EMT. Necessary for getting the 2367 * hypercall page and arguments. 2368 * @param uPausedTscValue The TSC value at the time of pausing. 2369 */ 2370 VMMR0_INT_DECL(int) NEMR0ResumeCpuTickOnAll(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t uPausedTscValue) 2371 { 2372 /* 2373 * Validate the call. 2374 */ 2375 int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu); 2376 if (RT_SUCCESS(rc)) 2377 { 2378 PVMCPU pVCpu = &pVM->aCpus[idCpu]; 2379 PGVMCPU pGVCpu = &pGVM->aCpus[idCpu]; 2380 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 2381 2382 /* 2383 * Call worker. 2384 */ 2385 pVCpu->nem.s.Hypercall.QueryCpuTick.cTicks = 0; 2386 pVCpu->nem.s.Hypercall.QueryCpuTick.uAux = 0; 2387 rc = nemR0WinResumeCpuTickOnAll(pGVM, pGVCpu, uPausedTscValue); 2282 2388 } 2283 2389 return rc; … … 2387 2493 if (RT_SUCCESS(rc)) 2388 2494 { 2389 Assert PtrReturn(g_pfnHvlInvokeHypercall, VERR_INTERNAL_ERROR_3);2495 AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API); 2390 2496 2391 2497 PGVMCPU pGVCpu = &pGVM->aCpus[idCpu]; -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r72541 r72546 2070 2070 break; 2071 2071 2072 case VMMR0_DO_NEM_RESUME_CPU_TICK_ON_ALL: 2073 if (pReqHdr || idCpu == NIL_VMCPUID) 2074 return VERR_INVALID_PARAMETER; 2075 rc = NEMR0ResumeCpuTickOnAll(pGVM, pVM, idCpu, u64Arg); 2076 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 2077 break; 2078 2072 2079 case VMMR0_DO_NEM_UPDATE_STATISTICS: 2073 2080 if (u64Arg || pReqHdr)
Note:
See TracChangeset
for help on using the changeset viewer.