VirtualBox

Changeset 55733 in vbox


Ignore:
Timestamp:
May 7, 2015 5:53:40 PM (9 years ago)
Author:
vboxsync
Message:

CPUMR3CpuId.cpp: Fixed CPUID sub-leaves collection for leaf 0xd. Didn't work on older systems because the logic quit too early.

File:
1 edited

Legend:

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

    r55716 r55733  
    935935
    936936    /* Count sub-leaves. */
     937    uint32_t cMinLeaves = uLeaf == 0xd ? 64 : 0;
    937938    uint32_t cRepeats = 0;
    938939    uSubLeaf = 0;
     
    944945           to cover undocumented behavior up to a point and implementation shortcuts. */
    945946
    946         /* 1. Look for zero values. */
    947         if (   auCur[0] == 0
    948             && auCur[1] == 0
    949             && (auCur[2] == 0 || auCur[2] == uSubLeaf)
    950             && (auCur[3] == 0 || uLeaf == 0xb /* edx is fixed */) )
    951         {
    952             cRepeats = 0;
    953             break;
    954         }
    955 
    956         /* 2. Look for more than 4 repeating value sets. */
     947        /* 1. Look for more than 4 repeating value sets. */
    957948        if (   auCur[0] == auPrev[0]
    958949            && auCur[1] == auPrev[1]
     
    962953            && auCur[3] == auPrev[3])
    963954        {
    964             cRepeats++;
    965             if (cRepeats > 4)
     955            if (   uLeaf != 0xd
     956                || uSubLeaf >= 64
     957                || (   auCur[0] == 0
     958                    && auCur[1] == 0
     959                    && auCur[2] == 0
     960                    && auCur[3] == 0
     961                    && auPrev[2] == 0) )
     962                cRepeats++;
     963            if (cRepeats > 4 && uSubLeaf >= cMinLeaves)
    966964                break;
    967965        }
    968966        else
    969967            cRepeats = 0;
     968
     969        /* 2. Look for zero values. */
     970        if (   auCur[0] == 0
     971            && auCur[1] == 0
     972            && (auCur[2] == 0 || auCur[2] == uSubLeaf)
     973            && (auCur[3] == 0 || uLeaf == 0xb /* edx is fixed */)
     974            && uSubLeaf >= cMinLeaves)
     975        {
     976            cRepeats = 0;
     977            break;
     978        }
    970979
    971980        /* 3. Leaf 0xb level type 0 check. */
     
    989998            else if (uLeaf == 0x7)
    990999                cDocLimit = 1;
     1000            else if (uLeaf == 0xd)
     1001                cDocLimit = 63;
    9911002            else if (uLeaf == 0xf)
    9921003                cDocLimit = 2;
     
    11541165                    && cpumR3IsEcxRelevantForCpuIdLeaf(uLeaf, &cSubLeaves, &fFinalEcxUnchanged))
    11551166                {
    1156                     if (cSubLeaves > 16)
     1167                    if (cSubLeaves > (uLeaf == 0xd ? 68U : 16U))
    11571168                    {
    11581169                        /* This shouldn't happen.  But in case it does, file all
     
    19831994
    19841995
     1996/**
     1997 * Installs the CPUID leaves and explods the data into structures like
     1998 * GuestFeatures and CPUMCTX::aoffXState.
     1999 *
     2000 * @returns VBox status code.
     2001 * @param   pVM         The cross context VM handle.
     2002 * @param   pCpum       The CPUM part of @a VM.
     2003 * @param   paLeaves    The leaves.  These will be copied (but not freed).
     2004 * @param   cLeaves     The number of leaves.
     2005 */
    19852006static int cpumR3CpuIdInstallAndExplodeLeaves(PVM pVM, PCPUM pCpum, PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves)
    19862007{
     
    20742095                *pLegacyLeaf = pCpum->GuestInfo.DefCpuId;
    20752096        }
     2097    }
     2098
     2099    /*
     2100     * Configure XSAVE offsets according to the CPUID info.
     2101     */
     2102    memset(&pVM->aCpus[0].cpum.s.Guest.aoffXState[0], 0xff, sizeof(pVM->aCpus[0].cpum.s.Guest.aoffXState));
     2103    pVM->aCpus[0].cpum.s.Guest.aoffXState[XSAVE_C_X87_BIT] = 0;
     2104    pVM->aCpus[0].cpum.s.Guest.aoffXState[XSAVE_C_SSE_BIT] = 0;
     2105    for (uint32_t iComponent = XSAVE_C_SSE_BIT + 1; iComponent < 63; iComponent++)
     2106        if (pCpum->fXStateGuestMask & RT_BIT_64(iComponent))
     2107        {
     2108            PCPUMCPUIDLEAF pSubLeaf = cpumR3CpuIdGetExactLeaf(pCpum, 0xd, iComponent);
     2109            AssertLogRelMsgReturn(pSubLeaf, ("iComponent=%#x\n"), VERR_CPUM_IPE_1);
     2110            AssertLogRelMsgReturn(pSubLeaf->fSubLeafMask >= iComponent, ("iComponent=%#x\n"), VERR_CPUM_IPE_1);
     2111            AssertLogRelMsgReturn(   pSubLeaf->uEax > 0
     2112                                  && pSubLeaf->uEax <= pCpum->GuestFeatures.cbMaxExtendedState
     2113                                  && pSubLeaf->uEbx >= 0x240
     2114                                  && pSubLeaf->uEbx <  pCpum->GuestFeatures.cbMaxExtendedState
     2115                                  && pSubLeaf->uEbx + pSubLeaf->uEax < pCpum->GuestFeatures.cbMaxExtendedState,
     2116                                  ("iComponent=%#x eax=%#x ebx=%#x cbMax=%#x\n", iComponent, pSubLeaf->uEax, pSubLeaf->uEbx,
     2117                                   pCpum->GuestFeatures.cbMaxExtendedState),
     2118                                  VERR_CPUM_IPE_1);
     2119            pVM->aCpus[0].cpum.s.Guest.aoffXState[iComponent] = pSubLeaf->uEbx;
     2120        }
     2121    memset(&pVM->aCpus[0].cpum.s.Hyper.aoffXState[0], 0xff, sizeof(pVM->aCpus[0].cpum.s.Hyper.aoffXState));
     2122
     2123    /* Copy the CPU #0  data to the other CPUs. */
     2124    for (VMCPUID iCpu = 1; iCpu < pVM->cCpus; iCpu++)
     2125    {
     2126        memcpy(&pVM->aCpus[iCpu].cpum.s.Guest.aoffXState[0], &pVM->aCpus[0].cpum.s.Guest.aoffXState[0],
     2127               sizeof(pVM->aCpus[iCpu].cpum.s.Guest.aoffXState));
     2128        memcpy(&pVM->aCpus[iCpu].cpum.s.Hyper.aoffXState[0], &pVM->aCpus[0].cpum.s.Hyper.aoffXState[0],
     2129               sizeof(pVM->aCpus[iCpu].cpum.s.Hyper.aoffXState));
    20762130    }
    20772131
     
    30163070
    30173071    /* Work the sub-leaves. */
     3072    uint32_t cbXSaveMax = sizeof(X86FXSTATE);
    30183073    for (uSubLeaf = 0; uSubLeaf < 63; uSubLeaf++)
    30193074    {
     
    30283083                        pCurLeaf->uEax &= RT_LO_U32(fGuestXcr0Mask);
    30293084                        pCurLeaf->uEdx &= RT_HI_U32(fGuestXcr0Mask);
     3085                        cbXSaveMax = pCurLeaf->uEcx;
     3086                        AssertLogRelMsgReturn(cbXSaveMax <= 8192 && cbXSaveMax >= 0x240, ("%#x\n", cbXSaveMax), VERR_CPUM_IPE_2);
     3087                        AssertLogRelMsgReturn(pCurLeaf->uEbx >= 0x240 && pCurLeaf->uEbx <= cbXSaveMax,
     3088                                              ("ebx=%#x cbXSaveMax=%#x\n", pCurLeaf->uEbx, cbXSaveMax),
     3089                                              VERR_CPUM_IPE_2);
    30303090                        continue;
    30313091                    case 1:
     
    30333093                        pCurLeaf->uEcx &= 0;
    30343094                        pCurLeaf->uEdx &= 0;
     3095                        /** @todo what about checking ebx? */
    30353096                        continue;
    30363097                    default:
    30373098                        if (fGuestXcr0Mask & RT_BIT_64(uSubLeaf))
    30383099                        {
     3100                            AssertLogRelMsgReturn(   pCurLeaf->uEax <= cbXSaveMax
     3101                                                  && pCurLeaf->uEax >  0
     3102                                                  && pCurLeaf->uEbx < cbXSaveMax
     3103                                                  && pCurLeaf->uEbx >= 0x240
     3104                                                  && pCurLeaf->uEbx + pCurLeaf->uEax <= cbXSaveMax,
     3105                                                  ("%#x: eax=%#x ebx=%#x cbMax=%#x\n", pCurLeaf->uEax, pCurLeaf->uEbx, cbXSaveMax),
     3106                                                  VERR_CPUM_IPE_2);
    30393107                            AssertLogRel(!(pCurLeaf->uEcx & 1));
    30403108                            pCurLeaf->uEcx = 0; /* Bit 0 should be zero (XCR0), the reset are reserved... */
     
    36333701    AssertLogRelRCReturn(rc, rc);
    36343702
    3635     /* Currently excluding older AMDs as we're seeing trouble booting 32-bit windows 7, due to
    3636        KiTrap07++ assuming the high 128-bit YMM component is in init state. Leading to a page fault. */
    36373703    bool const fMayHaveXSave = fNestedPagingAndFullGuestExec
    36383704                            && pVM->cpum.s.HostFeatures.fXSaveRstor
    3639                             && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor
    3640                             //&& !CPUMMICROARCH_IS_AMD_FAM_15H(pVM->cpum.s.HostFeatures.enmMicroarch);
    3641                             && pVM->cpum.s.HostFeatures.enmCpuVendor != CPUMCPUVENDOR_AMD;
     3705                            && pVM->cpum.s.HostFeatures.fOpSysXSaveRstor;
     3706
    36423707    /** @cfgm{/CPUM/IsaExts/XSAVE, boolean, depends}
    36433708     * Expose XSAVE/XRSTOR to the guest if available.  For the time being the
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