VirtualBox

Changeset 81106 in vbox


Ignore:
Timestamp:
Oct 3, 2019 9:23:00 PM (5 years ago)
Author:
vboxsync
Message:

IPRT,SUP,*: Some GIP related fixes for supporting APIC IDs over 256 and more than 256 CPUs. bugref:9501

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/sup.h

    r81096 r81106  
    504504
    505505    /** Table indexed by the CPU APIC ID to get the CPU table index. */
    506     uint16_t            aiCpuFromApicId[1024];
     506    uint16_t            aiCpuFromApicId[4096];
    507507    /** CPU set index to CPU table index. */
    508508    uint16_t            aiCpuFromCpuSetIdx[1024];
    509509    /** Table indexed by CPU group to containing offsets to SUPGIPCPUGROUP
    510      * structures, invalid entries are set to UINT16_MAX.  The offsets are relative
     510     * structures, invalid entries are set to UINT32_MAX.  The offsets are relative
    511511     * to the start of this structure.
    512      * @note Windows only. The other hosts sets all entries to UINT16_MAX! */
    513     uint16_t            aoffCpuGroup[SUPGIP_MAX_CPU_GROUPS];
     512     * @note Windows only. The other hosts sets all entries to UINT32_MAX! */
     513    uint32_t            aoffCpuGroup[SUPGIP_MAX_CPU_GROUPS];
    514514
    515515    /** Array of per-cpu data.
     
    542542 * Upper 16 bits is the major version. Major version is only changed with
    543543 * incompatible changes in the GIP. */
    544 #define SUPGLOBALINFOPAGE_VERSION   0x00090000
     544#define SUPGLOBALINFOPAGE_VERSION   0x000a0000
    545545
    546546/**
  • trunk/include/VBox/sup.mac

    r81096 r81106  
    8888    .PossibleCpuSet             resq 16
    8989    .au32Padding1               resd 48
    90     .aiCpuFromApicId            resw 1024
     90    .aiCpuFromApicId            resw 4096
    9191    .aiCpuFromCpuSetIdx         resw 1024
    92     .aoffCpuGroup               resw 256
     92    .aoffCpuGroup               resd 256
    9393    .aCPUs                      resb SUPGIPCPU_size
    9494endstruc
  • trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp

    r81096 r81106  
    189189
    190190
     191/**
     192 * Gets the APIC ID using the best available method, slow version.
     193 */
     194static uint32_t supdrvGipGetApicIdSlow(void)
     195{
     196    uint32_t const idApic = ASMGetApicId();
     197
     198    /* The Intel CPU topology leaf: */
     199    uint32_t uOther = ASMCpuId_EAX(0);
     200    if (uOther >= UINT32_C(0xb) && ASMIsValidStdRange(uOther))
     201    {
     202        uOther = ASMGetApicIdExt0B();
     203        if ((uOther & 0xff) == idApic)
     204            return uOther;
     205        AssertMsgFailed(("ASMGetApicIdExt0B=>%#x idApic=%#x\n", uOther, idApic));
     206    }
     207
     208    /* The AMD leaf: */
     209    uOther = ASMCpuId_EAX(UINT32_C(0x80000000));
     210    if (uOther >= UINT32_C(0x8000001e) && ASMIsValidExtRange(uOther))
     211    {
     212        uOther = ASMGetApicIdExt8000001E();
     213        if ((uOther & 0xff) == idApic)
     214            return uOther;
     215        AssertMsgFailed(("ASMGetApicIdExt8000001E=>%#x idApic=%#x\n", uOther, idApic));
     216    }
     217    return idApic;
     218}
     219
     220
    191221/*
    192222 *
     
    235265        if (RT_LIKELY(iCpu < pGip->cCpus && pGip->aCPUs[iCpu].idCpu == idCpu))
    236266            supdrvGipReInitCpu(&pGip->aCPUs[iCpu], *(uint64_t *)pvUser2);
    237     }
     267        else
     268            LogRelMax(64, ("supdrvGipReInitCpuCallback: iCpu=%#x out of bounds (%#zx, idApic=%#x)\n",
     269                           iCpu, RT_ELEMENTS(pGip->aiCpuFromApicId), idApic));
     270    }
     271    else
     272        LogRelMax(64, ("supdrvGipReInitCpuCallback: idApic=%#x out of bounds (%#zx)\n",
     273                       idApic, RT_ELEMENTS(pGip->aiCpuFromApicId)));
    238274
    239275    NOREF(pvUser2);
     
    248284    /** Bitmap of APIC IDs that has been seen (initialized to zero).
    249285     *  Used to detect duplicate APIC IDs (paranoia). */
    250     uint8_t volatile    bmApicId[1024 / 8];
     286    uint8_t volatile    bmApicId[4096 / 8];
    251287    /** Mask of supported GIP CPU getter methods (SUPGIPGETCPU_XXX) (all bits set
    252288     *  initially). The callback clears the methods not detected. */
     
    611647                if (RT_SUCCESS(rc))
    612648                {
    613                     SUPDRVGIPDETECTGETCPU DetectState;
    614                     RT_BZERO((void *)&DetectState.bmApicId, sizeof(DetectState.bmApicId));
    615                     DetectState.fSupported   = UINT32_MAX;
    616                     DetectState.idCpuProblem = NIL_RTCPUID;
    617                     rc = RTMpOnAll(supdrvGipDetectGetGipCpuCallback, &DetectState, pGipR0);
    618                     if (DetectState.idCpuProblem == NIL_RTCPUID)
     649                    PSUPDRVGIPDETECTGETCPU pDetectState = (PSUPDRVGIPDETECTGETCPU)RTMemTmpAllocZ(sizeof(*pDetectState));
     650                    if (pDetectState)
    619651                    {
    620                         if (   DetectState.fSupported != UINT32_MAX
    621                             && DetectState.fSupported != 0)
     652                        pDetectState->fSupported   = UINT32_MAX;
     653                        pDetectState->idCpuProblem = NIL_RTCPUID;
     654                        rc = RTMpOnAll(supdrvGipDetectGetGipCpuCallback, pDetectState, pGipR0);
     655                        if (pDetectState->idCpuProblem == NIL_RTCPUID)
    622656                        {
    623                             if (pGipR0->fGetGipCpu != DetectState.fSupported)
     657                            if (   pDetectState->fSupported != UINT32_MAX
     658                                && pDetectState->fSupported != 0)
    624659                            {
    625                                 pGipR0->fGetGipCpu = DetectState.fSupported;
    626                                 LogRel(("SUPR0GipMap: fGetGipCpu=%#x\n", DetectState.fSupported));
     660                                if (pGipR0->fGetGipCpu != pDetectState->fSupported)
     661                                {
     662                                    pGipR0->fGetGipCpu = pDetectState->fSupported;
     663                                    LogRel(("SUPR0GipMap: fGetGipCpu=%#x\n", pDetectState->fSupported));
     664                                }
     665                            }
     666                            else
     667                            {
     668                                LogRel(("SUPR0GipMap: No supported ways of getting the APIC ID or CPU number in ring-3! (%#x)\n",
     669                                        pDetectState->fSupported));
     670                                rc = VERR_UNSUPPORTED_CPU;
    627671                            }
    628672                        }
    629673                        else
    630674                        {
    631                             LogRel(("SUPR0GipMap: No supported ways of getting the APIC ID or CPU number in ring-3! (%#x)\n",
    632                                     DetectState.fSupported));
    633                             rc = VERR_UNSUPPORTED_CPU;
     675                            LogRel(("SUPR0GipMap: APIC ID, CPU ID or CPU set index problem detected on CPU #%u (%#x)!\n",
     676                                    pDetectState->idCpuProblem, pDetectState->idCpuProblem));
     677                            rc = VERR_INVALID_CPU_ID;
    634678                        }
     679                        RTMemTmpFree(pDetectState);
    635680                    }
    636681                    else
    637                     {
    638                         LogRel(("SUPR0GipMap: APIC ID, CPU ID or CPU set index problem detected on CPU #%u (%#x)!\n",
    639                                 DetectState.idCpuProblem, DetectState.idCpuProblem));
    640                         rc = VERR_INVALID_CPU_ID;
    641                     }
     682                        rc = VERR_NO_TMP_MEMORY;
    642683                }
    643684
     
    13921433    supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS, pGip->u64CpuHz);
    13931434
    1394     idApic = supdrvGipGetApicId(pGip);
     1435    idApic = supdrvGipGetApicIdSlow();
    13951436    ASMAtomicWriteU16(&pGip->aCPUs[i].idApic,  idApic);
    13961437    ASMAtomicWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet);
     
    14081449    if (idApic < RT_ELEMENTS(pGip->aiCpuFromApicId))
    14091450        ASMAtomicWriteU16(&pGip->aiCpuFromApicId[idApic],     i);
     1451    else
     1452        LogRelMax(64, ("supdrvGipMpEventOnlineOrInitOnCpu: idApic=%#x is out of bounds (%#zx, i=%u, iCpuSet=%d)\n",
     1453                       idApic, RT_ELEMENTS(pGip->aiCpuFromApicId), i, iCpuSet));
    14101454    if ((unsigned)iCpuSet < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx))
    14111455        ASMAtomicWriteU16(&pGip->aiCpuFromCpuSetIdx[iCpuSet], i);
     1456    else
     1457        LogRelMax(64, ("supdrvGipMpEventOnlineOrInitOnCpu: iCpuSet=%d is out of bounds (%#zx, i=%u, idApic=%d)\n",
     1458                       iCpuSet, RT_ELEMENTS(pGip->aiCpuFromApicId), i, idApic));
    14121459
    14131460    /* Add this CPU to this set of CPUs we need to calculate the TSC-delta for. */
     
    18811928        pGip->aiCpuFromCpuSetIdx[i] = UINT16_MAX;
    18821929    for (i = 0; i < RT_ELEMENTS(pGip->aoffCpuGroup); i++)
    1883         pGip->aoffCpuGroup[i] = UINT16_MAX;
     1930        pGip->aoffCpuGroup[i]       = UINT32_MAX;
    18841931    for (i = 0; i < cCpus; i++)
    18851932        supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS, 0 /*uCpuHz*/);
     
    20242071            RTCpuSetEmpty(&pDevExt->TscDeltaCpuSet);
    20252072            RTCpuSetEmpty(&pDevExt->TscDeltaObtainedCpuSet);
    2026     #ifdef SUPDRV_USE_TSC_DELTA_THREAD
     2073#ifdef SUPDRV_USE_TSC_DELTA_THREAD
    20272074            if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED)
    20282075                rc = supdrvTscDeltaThreadInit(pDevExt);
    2029     #endif
     2076#endif
    20302077            if (RT_SUCCESS(rc))
    20312078            {
     
    20402087                    if (RT_SUCCESS(rc))
    20412088                    {
    2042     #ifdef SUPDRV_USE_TSC_DELTA_THREAD
     2089#ifdef SUPDRV_USE_TSC_DELTA_THREAD
    20432090                        supdrvTscDeltaThreadStartMeasurement(pDevExt, true /* fForceAll */);
    2044     #else
     2091#else
    20452092                        uint16_t iCpu;
    20462093                        if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED)
     
    20662113                        }
    20672114                        if (RT_SUCCESS(rc))
    2068     #endif
     2115#endif
    20692116                        {
    20702117                            /*
     
    48944941                /* This really shouldn't happen. */
    48954942                AssertMsgFailed(("idCpu=%#x iCpuSet=%#x (%d)\n", RTMpCpuId(), iCpuSet, iCpuSet));
    4896                 pReq->u.Out.idApic = supdrvGipGetApicId(pGip);
     4943                pReq->u.Out.idApic = supdrvGipGetApicIdSlow();
    48974944                pReq->u.Out.u64AdjustedTsc = ASMReadTSC();
    48984945                ASMSetFlags(fEFlags);
     
    49144961            pReq->u.Out.idApic = pGip->aCPUs[iGipCpu].idApic;
    49154962        else
    4916             pReq->u.Out.idApic = supdrvGipGetApicId(pGip);
     4963            pReq->u.Out.idApic = supdrvGipGetApicIdSlow();
    49174964        pReq->u.Out.u64AdjustedTsc = ASMReadTSC();
    49184965        ASMSetFlags(fEFlags);
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r81096 r81106  
    223223 *          - Move SUP_IOCTL_FAST_DO_NOP and SUP_VMMR0_DO_NEM_RUN after NEM.
    224224 */
    225 #define SUPDRV_IOC_VERSION                              0x002c0000
     225#define SUPDRV_IOC_VERSION                              0x002d0000
    226226
    227227/** SUP_IOCTL_COOKIE. */
  • trunk/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp

    r81096 r81106  
    155155                {
    156156                    SUPGIPCPU const *pGipCpu = &g_pSUPGlobalInfoPage->aCPUs[iCpu];
    157                     RTPrintf("tstGIP-2: aCPU[%u]: enmState=%d iCpuSet=%u idCpu=%#010x iCpuGroup=%u iCpuGroupMember=%u idApic=%#x\n",
     157                    RTPrintf("tstGIP-2: aCPU[%3u]: enmState=%d iCpuSet=%-3u idCpu=%#010x iCpuGroup=%-2u iCpuGroupMember=%-3u idApic=%#06x\n",
    158158                             iCpu, pGipCpu->enmState, pGipCpu->iCpuSet, pGipCpu->idCpu, pGipCpu->iCpuGroup,
    159159                             pGipCpu->iCpuGroupMember, pGipCpu->idApic);
     
    164164                     : "tstGIP-2:     it: u64NanoTS        delta     u64TSC             UpIntTSC H    TransId      CpuHz      %sTSC Interval History...\n",
    165165                     uCpuHzRef ? "  CpuHz deviation  Compat  " : "");
    166             static SUPGIPCPU s_aaCPUs[2][256];
     166            static SUPGIPCPU s_aaCPUs[2][RTCPUSET_MAX_CPUS];
    167167            for (uint32_t i = 0; i < cIterations; i++)
    168168            {
     
    274274            RTPrintf("tstGIP-2: TSC deltas:\n");
    275275            RTPrintf("tstGIP-2:  idApic: i64TSCDelta\n");
    276             for (unsigned i = 0; i < RT_ELEMENTS(g_pSUPGlobalInfoPage->aiCpuFromApicId); i++)
     276            for (uint32_t i = 0; i < RT_ELEMENTS(g_pSUPGlobalInfoPage->aiCpuFromApicId); i++)
    277277            {
    278278                uint16_t iCpu = g_pSUPGlobalInfoPage->aiCpuFromApicId[i];
    279279                if (iCpu != UINT16_MAX)
    280                 {
    281                     RTPrintf("tstGIP-2: %7d: %lld\n", g_pSUPGlobalInfoPage->aCPUs[iCpu].idApic,
    282                              g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta);
    283                 }
     280                    RTPrintf("tstGIP-2: %#7x: %6lld (grp=%#04x mbr=%#05x set=%d cpu=%#05x)\n",
     281                             g_pSUPGlobalInfoPage->aCPUs[iCpu].idApic, g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta,
     282                             g_pSUPGlobalInfoPage->aCPUs[iCpu].iCpuGroup, g_pSUPGlobalInfoPage->aCPUs[iCpu].iCpuGroupMember,
     283                             g_pSUPGlobalInfoPage->aCPUs[iCpu].iCpuSet, iCpu);
    284284            }
    285285
    286             for (unsigned iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++)
     286            for (uint32_t iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++)
    287287                if (g_pSUPGlobalInfoPage->aCPUs[iCpu].idApic == UINT16_MAX)
    288                     RTPrintf("tstGIP-2: offline: %lld\n", g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta);
     288                    RTPrintf("tstGIP-2: offline: %6lld (grp=%#04x mbr=%#05x set=%d cpu=%#05x)\n",
     289                             g_pSUPGlobalInfoPage->aCPUs[iCpu].i64TSCDelta, g_pSUPGlobalInfoPage->aCPUs[iCpu].iCpuGroup,
     290                             g_pSUPGlobalInfoPage->aCPUs[iCpu].iCpuGroupMember, g_pSUPGlobalInfoPage->aCPUs[iCpu].iCpuSet, iCpu);
    289291
    290292            RTPrintf("tstGIP-2: enmUseTscDelta=%d  fGetGipCpu=%#x\n",
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r77816 r81106  
    17621762    for (uint32_t idxGroup = 0; idxGroup < cGroups; idxGroup++)
    17631763    {
    1764         uint32_t cActive  = 0;
    1765         uint32_t cMax     = RTMpGetCpuGroupCounts(idxGroup, &cActive);
    1766         uint32_t cbNeeded = RT_UOFFSETOF_DYN(SUPGIPCPUGROUP, aiCpuSetIdxs[cMax]);
     1764        uint32_t        cActive  = 0;
     1765        uint32_t  const cMax     = RTMpGetCpuGroupCounts(idxGroup, &cActive);
     1766        uint32_t  const cbNeeded = RT_UOFFSETOF_DYN(SUPGIPCPUGROUP, aiCpuSetIdxs[cMax]);
     1767        uintptr_t const offGroup = (uintptr_t)pGroup - (uintptr_t)pGip;
    17671768        AssertReturn(cbNeeded <= cbGipCpuGroups, VERR_INTERNAL_ERROR_3);
    17681769        AssertReturn(cActive <= cMax, VERR_INTERNAL_ERROR_4);
    1769 
    1770         pGip->aoffCpuGroup[idxGroup] = (uint16_t)((uintptr_t)pGroup - (uintptr_t)pGip);
     1770        AssertReturn(offGroup == (uint32_t)offGroup, VERR_INTERNAL_ERROR_5);
     1771
     1772        pGip->aoffCpuGroup[idxGroup] = offGroup;
    17711773        pGroup->cMembers    = cActive;
    17721774        pGroup->cMaxMembers = cMax;
     
    18131815     */
    18141816    for (uint32_t idxGroup = 0; idxGroup < pGip->cPossibleCpuGroups; idxGroup++)
    1815         if (pGip->aoffCpuGroup[idxGroup] != UINT16_MAX)
    1816         {
    1817             PSUPGIPCPUGROUP pGroup = (PSUPGIPCPUGROUP)((uintptr_t)pGip + pGip->aoffCpuGroup[idxGroup]);
    1818 
    1819             uint32_t cActive  = 0;
    1820             uint32_t cMax     = RTMpGetCpuGroupCounts(idxGroup, &cActive);
     1817    {
     1818        uint32_t offGroup = pGip->aoffCpuGroup[idxGroup];
     1819        if (offGroup != UINT32_MAX)
     1820        {
     1821            PSUPGIPCPUGROUP pGroup   = (PSUPGIPCPUGROUP)((uintptr_t)pGip + offGroup);
     1822            uint32_t        cActive  = 0;
     1823            uint32_t        cMax     = RTMpGetCpuGroupCounts(idxGroup, &cActive);
     1824
    18211825            AssertStmt(cMax == pGroup->cMaxMembers, cMax = pGroup->cMaxMembers);
    18221826            AssertStmt(cActive <= cMax, cActive = cMax);
    18231827            if (pGroup->cMembers != cActive)
    1824                 pGroup->cMembers = cActive;
     1828                ASMAtomicWriteU16(&pGroup->cMembers, cActive);
    18251829
    18261830            for (uint32_t idxMember = 0; idxMember < cMax; idxMember++)
     
    18311835
    18321836                if (pGroup->aiCpuSetIdxs[idxMember] != idxCpuSet)
    1833                     pGroup->aiCpuSetIdxs[idxMember] = idxCpuSet;
    1834             }
    1835         }
     1837                    ASMAtomicWriteS16(&pGroup->aiCpuSetIdxs[idxMember], idxCpuSet);
     1838            }
     1839        }
     1840    }
    18361841}
    18371842
  • trunk/src/VBox/Runtime/r3/win/mp-win.cpp

    r81096 r81106  
    422422        {
    423423            uint32_t idxMember;
    424             unsigned offCpuGroup = pGip->aoffCpuGroup[idxGroup];
     424            uint32_t offCpuGroup = pGip->aoffCpuGroup[idxGroup];
    425425            if (offCpuGroup < cbGip)
    426426            {
     
    480480            for (uint32_t idxGroup = 0; idxGroup < g_cRtMpWinMaxCpus; idxGroup++)
    481481            {
    482                 unsigned offCpuGroup = pGip->aoffCpuGroup[idxGroup];
     482                uint32_t offCpuGroup = pGip->aoffCpuGroup[idxGroup];
    483483                if (offCpuGroup < cbGip)
    484484                {
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