Changeset 49141 in vbox
- Timestamp:
- Oct 16, 2013 2:07:14 PM (11 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/VMMTests.cpp
r47843 r49141 618 618 } 619 619 620 621 #ifdef VBOX_WITH_RAW_MODE 622 623 /** 624 * Used by VMMDoBruteForceMsrs to dump the CPUID info of the host CPU as a 625 * prefix to the MSR report. 626 */ 627 static DECLCALLBACK(void) vmmDoPrintfVToStream(PCDBGFINFOHLP pHlp, const char *pszFormat, va_list va) 628 { 629 PRTSTREAM pOutStrm = ((PRTSTREAM *)pHlp)[-1]; 630 RTStrmPrintfV(pOutStrm, pszFormat, va); 631 } 632 633 /** 634 * Used by VMMDoBruteForceMsrs to dump the CPUID info of the host CPU as a 635 * prefix to the MSR report. 636 */ 637 static DECLCALLBACK(void) vmmDoPrintfToStream(PCDBGFINFOHLP pHlp, const char *pszFormat, ...) 638 { 639 va_list va; 640 va_start(va, pszFormat); 641 vmmDoPrintfVToStream(pHlp, pszFormat, va); 642 va_end(va); 643 } 644 645 #endif 646 647 648 /** 649 * Uses raw-mode to query all possible MSRs on the real hardware. 650 * 651 * This generates a msr-report.txt file (appending, no overwriting) as well as 652 * writing the values and process to stdout. 653 * 654 * @returns VBox status code. 655 * @param pVM The VM handle. 656 */ 657 VMMDECL(int) VMMDoBruteForceMsrs(PVM pVM) 658 { 659 #ifdef VBOX_WITH_RAW_MODE 660 RTRCPTR RCPtrEP; 661 int rc = PDMR3LdrGetSymbolRC(pVM, VMMGC_MAIN_MODULE_NAME, "VMMRCTestReadMsrs", &RCPtrEP); 662 if (RT_SUCCESS(rc)) 663 { 664 RTPrintf("VMM: VMMRCTestReadMsrs=%RRv\n", RCPtrEP); 665 PRTSTREAM pOutStrm; 666 rc = RTStrmOpen("msr-report.txt", "a", &pOutStrm); 667 if (RT_SUCCESS(rc)) 668 { 669 /* Header */ 670 struct 671 { 672 PRTSTREAM pOutStrm; 673 DBGFINFOHLP Hlp; 674 } MyHlp = { pOutStrm, { vmmDoPrintfToStream, vmmDoPrintfVToStream } }; 675 DBGFR3Info(pVM->pUVM, "cpuid", "verbose", &MyHlp.Hlp); 676 RTStrmPrintf(pOutStrm, "\n"); 677 678 /* 679 * The MSRs. 680 */ 681 uint32_t const cMsrsPerCall = 1024; 682 uint32_t cbResults = cMsrsPerCall * sizeof(VMMTESTMSRENTRY); 683 PVMMTESTMSRENTRY paResults; 684 rc = MMHyperAlloc(pVM, cbResults, 0, MM_TAG_VMM, (void **)&paResults); 685 if (RT_SUCCESS(rc)) 686 { 687 RTRCPTR RCPtrResults = MMHyperR3ToRC(pVM, paResults); 688 uint32_t cMsrsFound = 0; 689 uint32_t uLastMsr = 0; 690 uint64_t uNsTsStart = RTTimeNanoTS(); 691 692 for (uint32_t uCurMsr = 0; ; uCurMsr += cMsrsPerCall) 693 { 694 if ( uCurMsr - uLastMsr > _64K 695 && (uCurMsr & (_4M - 1)) == 0) 696 { 697 if (uCurMsr - uLastMsr < 16U*_1M) 698 RTStrmFlush(pOutStrm); 699 RTPrintf("... %#010x [%u ns/msr] ...\n", uCurMsr, (RTTimeNanoTS() - uNsTsStart) / uCurMsr); 700 } 701 702 RT_BZERO(paResults, cbResults); 703 rc = VMMR3CallRC(pVM, RCPtrEP, 4, pVM->pVMRC, uCurMsr, cMsrsPerCall, RCPtrResults); 704 if (RT_FAILURE(rc)) 705 { 706 RTPrintf("VMM: VMMR3CallRC failed rc=%Rrc, uCurMsr=%#x\n", rc, uCurMsr); 707 break; 708 } 709 710 for (uint32_t i = 0; i < cMsrsPerCall; i++) 711 if (paResults[i].uMsr != UINT64_MAX) 712 { 713 RTStrmPrintf(pOutStrm, "%#010x = %#llx\n", paResults[i].uMsr, paResults[i].uValue); 714 RTPrintf("%#010x = %#llx\n", paResults[i].uMsr, paResults[i].uValue); 715 cMsrsFound++; 716 uLastMsr = paResults[i].uMsr; 717 } 718 if (uCurMsr + cMsrsPerCall < uCurMsr) 719 break; 720 } 721 722 RTStrmPrintf(pOutStrm, "Total %u (%#x) MSRs\n", cMsrsFound, cMsrsFound); 723 RTPrintf("Total %u (%#x) MSRs\n", cMsrsFound, cMsrsFound); 724 MMHyperFree(pVM, paResults); 725 } 726 RTStrmClose(pOutStrm); 727 } 728 } 729 else 730 AssertMsgFailed(("Failed to resolved VMMRC.rc::VMMRCEntry(), rc=%Rrc\n", rc)); 731 return rc; 732 #else 733 return VERR_NOT_SUPPORTED; 734 #endif 735 } 736 -
trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp
r49134 r49141 1452 1452 } 1453 1453 1454 1455 /** 1456 * Generic hyper trap handler that sets the EIP to @a uUser. 1457 * 1458 * @returns VBox status code. (Anything but VINF_SUCCESS will cause guru.) 1459 * @param pVM Pointer to the cross context VM structure. 1460 * @param pRegFrame Pointer to the register frame (within VM) 1461 * @param uUser The user arg, which should be the new EIP address. 1462 */ 1463 extern "C" DECLCALLBACK(int) TRPMRCTrapHyperHandlerSetEIP(PVM pVM, PCPUMCTXCORE pRegFrame, uintptr_t uUser) 1464 { 1465 AssertReturn(MMHyperIsInsideArea(pVM, uUser), VERR_TRPM_IPE_3); 1466 pRegFrame->eip = uUser; 1467 return VINF_SUCCESS; 1468 } 1469 -
trunk/src/VBox/VMM/VMMRC/VMMRC.cpp
r46861 r49141 48 48 static DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame); 49 49 static DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame); 50 DECLASM(bool) vmmRCSafeMsrRead(uint32_t uMsr, uint64_t *pu64Value); 50 51 51 52 … … 344 345 345 346 347 348 /** 349 * Reads a range of MSRs. 350 * 351 * This is called directly via VMMR3CallRC. 352 * 353 * @returns VBox status code. 354 * @param pVM The VM handle. 355 * @param uMsr The MSR to start at. 356 * @param cMsrs The number of MSRs to read. 357 * @param paResults Where to store the results. This must be large 358 * enough to hold at least @a cMsrs result values. 359 */ 360 extern "C" VMMRCDECL(int) 361 VMMRCTestReadMsrs(PVM pVM, uint32_t uMsr, uint32_t cMsrs, PVMMTESTMSRENTRY paResults) 362 { 363 AssertReturn(cMsrs <= 4096, VERR_INVALID_PARAMETER); 364 AssertPtrReturn(paResults, VERR_INVALID_POINTER); 365 366 for (uint32_t i = 0; i < cMsrs; i++, uMsr++) 367 { 368 if (vmmRCSafeMsrRead(uMsr, &paResults[i].uValue)) 369 paResults[i].uMsr = uMsr; 370 else 371 paResults[i].uMsr = UINT64_MAX; 372 } 373 return VINF_SUCCESS; 374 } 375 376 377 346 378 /** 347 379 * Temporary \#PF trap handler for the \#PF test case. -
trunk/src/VBox/VMM/VMMRC/VMMRCA.asm
r41338 r49141 24 24 %include "VBox/vmm/vm.mac" 25 25 %include "VMMInternal.mac" 26 %include "VMMRC.mac" 26 27 27 28 … … 57 58 extern NAME(RTLogLogger) 58 59 extern NAME(vmmRCProbeFireHelper) 60 extern NAME(TRPMRCTrapHyperHandlerSetEIP) 59 61 60 62 … … 219 221 ret 220 222 ENDPROC vmmGCTestTrap0e 223 224 225 226 ;; 227 ; Safely reads an MSR. 228 ; @returns boolean 229 ; @param uMsr The MSR to red. 230 ; @param pu64Value Where to return the value on success. 231 ; 232 GLOBALNAME vmmRCSafeMsrRead 233 push ebp 234 mov ebp, esp 235 pushad 236 237 mov ecx, [ebp + 8] ; the MSR to read. 238 mov eax, 0deadbeefh 239 mov edx, 0deadbeefh 240 241 TRPM_GP_HANDLER NAME(TRPMRCTrapHyperHandlerSetEIP), .trapped 242 rdmsr 243 244 mov ecx, [ebp + 0ch] ; Where to store the result. 245 mov [ecx], eax 246 mov [ecx], edx 247 248 popad 249 mov eax, 1 250 leave 251 ret 252 253 .trapped: 254 popad 255 mov eax, 0 256 leave 257 ret 258 ENDPROC vmmRCSafeMsrRead 221 259 222 260 -
trunk/src/VBox/VMM/include/VMMInternal.h
r47467 r49141 526 526 527 527 528 529 /** 530 * MSR test result entry. 531 */ 532 typedef struct VMMTESTMSRENTRY 533 { 534 /** The MSR number, including padding. 535 * Set to UINT64_MAX if invalid MSR. */ 536 uint64_t uMsr; 537 /** The register value. */ 538 uint64_t uValue; 539 } VMMTESTMSRENTRY; 540 /** Pointer to an MSR test result entry. */ 541 typedef VMMTESTMSRENTRY *PVMMTESTMSRENTRY; 542 543 544 528 545 RT_C_DECLS_BEGIN 529 546 -
trunk/src/VBox/VMM/testcase/tstVMM.cpp
r46915 r49141 55 55 * Internal Functions * 56 56 *******************************************************************************/ 57 VMMR3DECL(int) VMMDoTest(PVM pVM); /* Linked into VMM, see ../VMMTests.cpp. */ 57 VMMR3DECL(int) VMMDoTest(PVM pVM); /* Linked into VMM, see ../VMMTests.cpp. */ 58 VMMR3DECL(int) VMMDoBruteForceMsrs(PVM pVM); /* Ditto. */ 58 59 59 60 … … 210 211 enum 211 212 { 212 kTstVMMTest_VMM, kTstVMMTest_TM 213 kTstVMMTest_VMM, kTstVMMTest_TM, kTstVMMTest_MSRs 213 214 } enmTestOpt = kTstVMMTest_VMM; 214 215 … … 230 231 else if (!strcmp("tm", ValueUnion.psz)) 231 232 enmTestOpt = kTstVMMTest_TM; 233 else if (!strcmp("msr", ValueUnion.psz) || !strcmp("msrs", ValueUnion.psz)) 234 enmTestOpt = kTstVMMTest_MSRs; 232 235 else 233 236 { … … 238 241 239 242 case 'h': 240 RTPrintf("usage: tstVMM [--cpus|-c cpus] [--test <vmm|tm >]\n");243 RTPrintf("usage: tstVMM [--cpus|-c cpus] [--test <vmm|tm|msr>]\n"); 241 244 return 1; 242 245 … … 274 277 if (RT_FAILURE(rc)) 275 278 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); 279 STAMR3Dump(pUVM, "*"); 276 280 break; 277 281 } … … 290 294 if (RT_FAILURE(rc)) 291 295 RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc); 292 break; 293 } 294 } 295 296 STAMR3Dump(pUVM, "*"); 296 STAMR3Dump(pUVM, "*"); 297 break; 298 } 299 300 case kTstVMMTest_MSRs: 301 { 302 RTTestSub(hTest, "MSRs"); 303 if (g_cCpus == 1) 304 { 305 rc = VMR3ReqCallWaitU(pUVM, 0 /*idDstCpu*/, (PFNRT)VMMDoBruteForceMsrs, 1, pVM); 306 if (RT_FAILURE(rc)) 307 RTTestFailed(hTest, "VMMDoBruteForceMsrs failed: rc=%Rrc\n", rc); 308 } 309 else 310 RTTestFailed(hTest, "The MSR test can only be run with one VCpu!\n"); 311 break; 312 } 313 } 297 314 298 315 /*
Note:
See TracChangeset
for help on using the changeset viewer.