VirtualBox

Changeset 50606 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Feb 26, 2014 2:04:17 PM (11 years ago)
Author:
vboxsync
Message:

cpumR3IsEcxRelevantForCpuIdLeaf: Improved exit conditions, fixing trouble with the 0x4 leaves on some intel CPUs.

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

Legend:

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

    r50087 r50606  
    771771    *pfFinalEcxUnchanged = false;
    772772
     773    uint32_t auCur[4];
    773774    uint32_t auPrev[4];
    774775    ASMCpuIdExSlow(uLeaf, 0, 0, 0, &auPrev[0], &auPrev[1], &auPrev[2], &auPrev[3]);
     
    778779    for (;;)
    779780    {
    780         uint32_t auCur[4];
    781781        ASMCpuIdExSlow(uLeaf, 0, uSubLeaf, 0, &auCur[0], &auCur[1], &auCur[2], &auCur[3]);
    782782        if (memcmp(auCur, auPrev, sizeof(auCur)))
     
    793793
    794794    /* Count sub-leaves. */
     795    uint32_t cRepeats = 0;
    795796    uSubLeaf = 0;
    796797    for (;;)
    797798    {
    798         uint32_t auCur[4];
    799799        ASMCpuIdExSlow(uLeaf, 0, uSubLeaf, 0, &auCur[0], &auCur[1], &auCur[2], &auCur[3]);
    800800
    801         /* Exactly when this terminates isn't quite consistent.  When working
    802            0xb, we should probably only check if ebx == 0... */
     801        /* Figuring out when to stop isn't entirely straight forward as we need
     802           to cover undocumented behavior up to a point and implementation shortcuts. */
     803
     804        /* 1. Look for zero values. */
    803805        if (   auCur[0] == 0
    804806            && auCur[1] == 0
    805807            && (auCur[2] == 0 || auCur[2] == uSubLeaf)
    806             && (auCur[3] == 0 || uLeaf == 0xb) )
    807         {
    808             if (auCur[2] == uSubLeaf)
    809                 *pfFinalEcxUnchanged = true;
    810             *pcSubLeaves = uSubLeaf + 1;
    811             return true;
    812         }
    813 
    814         /* Advance / give up. */
    815         uSubLeaf++;
     808            && (auCur[3] == 0 || uLeaf == 0xb /* edx is fixed */) )
     809            break;
     810
     811        /* 2. Look for more than 4 repeating value sets. */
     812        if (   auCur[0] == auPrev[0]
     813            && auCur[1] == auPrev[1]
     814            && (auCur[2] == auPrev[2] || (auCur[2] == uSubLeaf && auPrev[1] == uSubLeaf - 1))
     815            && auCur[3] == auPrev[3])
     816        {
     817            cRepeats++;
     818            if (cRepeats > 4)
     819                break;
     820        }
     821        else
     822            cRepeats = 0;
     823
     824        /* 3. Leaf 0xb level type 0 check. */
     825        if (   uLeaf == 0xb
     826            && (auCur[3]  & 0xff00) == 0
     827            && (auPrev[3] & 0xff00) == 0)
     828            break;
     829
     830        /* 99. Give up. */
    816831        if (uSubLeaf >= 128)
    817832        {
     833#ifndef IN_VBOX_CPU_REPORT
     834            /* Ok, limit it according to the documentation if possible just to
     835               avoid annoying users with these detection issues. */
     836            uint32_t cDocLimit = UINT32_MAX;
     837            if (uLeaf == 0x4)
     838                cDocLimit = 4;
     839            else if (uLeaf == 0x7)
     840                cDocLimit = 1;
     841            else if (uLeaf == 0xf)
     842                cDocLimit = 2;
     843            if (cDocLimit != UINT32_MAX)
     844            {
     845                *pfFinalEcxUnchanged = auCur[2] == uSubLeaf;
     846                *pcSubLeaves = cDocLimit + 3;
     847                return true;
     848            }
     849#endif
    818850            *pcSubLeaves = UINT32_MAX;
    819851            return true;
    820852        }
    821     }
     853
     854        /* Advance. */
     855        uSubLeaf++;
     856        memcpy(auPrev, auCur, sizeof(auCur));
     857    }
     858
     859    /* Standard exit. */
     860    *pfFinalEcxUnchanged = auCur[2] == uSubLeaf;
     861    *pcSubLeaves = uSubLeaf + 1 - cRepeats;
     862    return true;
    822863}
    823864
  • trunk/src/VBox/VMM/tools/Makefile.kmk

    r49894 r50606  
    5656PROGRAMS += VBoxCpuReport
    5757VBoxCpuReport_TEMPLATE := VBoxR3Static
    58 VBoxCpuReport_DEFS      = IN_VMM_R3
     58VBoxCpuReport_DEFS      = IN_VMM_R3 IN_VBOX_CPU_REPORT
    5959VBoxCpuReport_INCS      = ../include
    6060VBoxCpuReport_SOURCES   = \
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