VirtualBox

Ignore:
Timestamp:
Oct 3, 2019 9:23:00 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
133729
Message:

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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);
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