VirtualBox

Changeset 49141 in vbox


Ignore:
Timestamp:
Oct 16, 2013 2:07:14 PM (11 years ago)
Author:
vboxsync
Message:

tstVMM: Extended it with a 'msr' mode for dump the MSRs of the host CPU brute-force style.

Location:
trunk/src/VBox/VMM
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/VMMTests.cpp

    r47843 r49141  
    618618}
    619619
     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 */
     627static 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 */
     637static 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 */
     657VMMDECL(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  
    14521452}
    14531453
     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 */
     1463extern "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  
    4848static DECLCALLBACK(int) vmmGCTestTmpPFHandler(PVM pVM, PCPUMCTXCORE pRegFrame);
    4949static DECLCALLBACK(int) vmmGCTestTmpPFHandlerCorruptFS(PVM pVM, PCPUMCTXCORE pRegFrame);
     50DECLASM(bool)   vmmRCSafeMsrRead(uint32_t uMsr, uint64_t *pu64Value);
    5051
    5152
     
    344345
    345346
     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 */
     360extern "C" VMMRCDECL(int)
     361VMMRCTestReadMsrs(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
    346378/**
    347379 * Temporary \#PF trap handler for the \#PF test case.
  • trunk/src/VBox/VMM/VMMRC/VMMRCA.asm

    r41338 r49141  
    2424%include "VBox/vmm/vm.mac"
    2525%include "VMMInternal.mac"
     26%include "VMMRC.mac"
    2627
    2728
     
    5758extern NAME(RTLogLogger)
    5859extern NAME(vmmRCProbeFireHelper)
     60extern NAME(TRPMRCTrapHyperHandlerSetEIP)
    5961
    6062
     
    219221    ret
    220222ENDPROC 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;
     232GLOBALNAME 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
     241TRPM_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
     258ENDPROC vmmRCSafeMsrRead
    221259
    222260
  • trunk/src/VBox/VMM/include/VMMInternal.h

    r47467 r49141  
    526526
    527527
     528
     529/**
     530 * MSR test result entry.
     531 */
     532typedef 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. */
     541typedef VMMTESTMSRENTRY *PVMMTESTMSRENTRY;
     542
     543
     544
    528545RT_C_DECLS_BEGIN
    529546
  • trunk/src/VBox/VMM/testcase/tstVMM.cpp

    r46915 r49141  
    5555*   Internal Functions                                                         *
    5656*******************************************************************************/
    57 VMMR3DECL(int) VMMDoTest(PVM pVM); /* Linked into VMM, see ../VMMTests.cpp. */
     57VMMR3DECL(int) VMMDoTest(PVM pVM);    /* Linked into VMM, see ../VMMTests.cpp. */
     58VMMR3DECL(int) VMMDoBruteForceMsrs(PVM pVM); /* Ditto. */
    5859
    5960
     
    210211    enum
    211212    {
    212         kTstVMMTest_VMM,  kTstVMMTest_TM
     213        kTstVMMTest_VMM,  kTstVMMTest_TM, kTstVMMTest_MSRs
    213214    } enmTestOpt = kTstVMMTest_VMM;
    214215
     
    230231                else if (!strcmp("tm", ValueUnion.psz))
    231232                    enmTestOpt = kTstVMMTest_TM;
     233                else if (!strcmp("msr", ValueUnion.psz) || !strcmp("msrs", ValueUnion.psz))
     234                    enmTestOpt = kTstVMMTest_MSRs;
    232235                else
    233236                {
     
    238241
    239242            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");
    241244                return 1;
    242245
     
    274277                if (RT_FAILURE(rc))
    275278                    RTTestFailed(hTest, "VMMDoTest failed: rc=%Rrc\n", rc);
     279                STAMR3Dump(pUVM, "*");
    276280                break;
    277281            }
     
    290294                if (RT_FAILURE(rc))
    291295                    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        }
    297314
    298315        /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette