VirtualBox

Changeset 64255 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Oct 13, 2016 3:18:21 PM (8 years ago)
Author:
vboxsync
Message:

SUP,VMM,IPRT: SUPDrv and GIP major version bump! Added processor group info to GIP along with a new RDTSCP-based method for getting the current CPU (for the timesup code).

Location:
trunk/src/VBox/HostDrivers/Support
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp

    r64236 r64255  
    274274            && RT_IS_POWER_OF_TWO(RTCPUSET_MAX_CPUS))
    275275        {
     276            PSUPGIPCPU pGipCpu = SUPGetGipCpuBySetIndex(pGip, iCpuSet);
     277
    276278            /*
    277279             * Check whether the IDTR.LIMIT contains a CPU number.
     
    305307                    && (ASMCpuId_EDX(UINT32_C(0x80000001)) & X86_CPUID_EXT_FEATURE_EDX_RDTSCP) )
    306308                {
    307                     uint32_t uAux;
     309                    uint32_t const  uGroupedAux = (uint8_t)pGipCpu->iCpuGroupMember | ((uint32_t)pGipCpu->iCpuGroup << 8);
     310                    uint32_t        uAux;
    308311                    ASMReadTscWithAux(&uAux);
    309312                    if ((uAux & (RTCPUSET_MAX_CPUS - 1)) == idCpu)
     
    313316                        if ((uAux & (RTCPUSET_MAX_CPUS - 1)) == idCpu)
    314317                            fSupported |= SUPGIPGETCPU_RDTSCP_MASK_MAX_SET_CPUS;
     318                    }
     319
     320                    if (   (uAux & UINT16_MAX) == uGroupedAux
     321                        && pGipCpu->iCpuGroupMember <= UINT8_MAX)
     322                    {
     323                        ASMNopPause();
     324                        ASMReadTscWithAux(&uAux);
     325                        if ((uAux & UINT16_MAX) == uGroupedAux)
     326                            fSupported |= SUPGIPGETCPU_RDTSCP_GROUP_IN_CH_NUMBER_IN_CL;
    315327                    }
    316328                }
     
    12591271static void supdrvGipMpEventOnlineOrInitOnCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu)
    12601272{
    1261     int         iCpuSet = 0;
    1262     uint16_t    idApic = UINT16_MAX;
    1263     uint32_t    i = 0;
    1264     uint64_t    u64NanoTS = 0;
    1265     PSUPGLOBALINFOPAGE pGip = pDevExt->pGip;
     1273    PSUPGLOBALINFOPAGE  pGip      = pDevExt->pGip;
     1274    int                 iCpuSet   = 0;
     1275    uint16_t            idApic    = UINT16_MAX;
     1276    uint32_t            i        = 0;
     1277    uint64_t            u64NanoTS = 0;
    12661278
    12671279    AssertPtrReturnVoid(pGip);
     
    13011313    ASMAtomicWriteS16(&pGip->aCPUs[i].iCpuSet, (int16_t)iCpuSet);
    13021314    ASMAtomicWriteSize(&pGip->aCPUs[i].idCpu,  idCpu);
     1315
     1316    pGip->aCPUs[i].iCpuGroup = 0;
     1317    pGip->aCPUs[i].iCpuGroupMember = iCpuSet;
     1318#ifdef RT_OS_WINDOWS
     1319    pGip->aCPUs[i].iCpuGroup = supdrvOSGipGetGroupFromCpu(pDevExt, idCpu, &pGip->aCPUs[i].iCpuGroupMember);
     1320#endif
    13031321
    13041322    /*
     
    16831701    pCpu->i64TSCDelta        = pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED ? INT64_MAX : 0;
    16841702
    1685     ASMAtomicWriteSize(&pCpu->enmState, SUPGIPCPUSTATE_INVALID);
    1686     ASMAtomicWriteU32(&pCpu->idCpu,     NIL_RTCPUID);
    1687     ASMAtomicWriteS16(&pCpu->iCpuSet,   -1);
    1688     ASMAtomicWriteU16(&pCpu->idApic,    UINT16_MAX);
     1703    ASMAtomicWriteSize(&pCpu->enmState,             SUPGIPCPUSTATE_INVALID);
     1704    ASMAtomicWriteU32(&pCpu->idCpu,                 NIL_RTCPUID);
     1705    ASMAtomicWriteS16(&pCpu->iCpuSet,               -1);
     1706    ASMAtomicWriteU16(&pCpu->iCpuGroup,             0);
     1707    ASMAtomicWriteU16(&pCpu->iCpuGroupMember,       UINT16_MAX);
     1708    ASMAtomicWriteU16(&pCpu->idApic,                UINT16_MAX);
     1709    ASMAtomicWriteU32(&pCpu->iReservedForNumaNode,  0);
    16891710
    16901711    /*
     
    17641785    pGip->cPresentCpus            = RTMpGetPresentCount();
    17651786    pGip->cPossibleCpus           = RTMpGetCount();
     1787    pGip->cPossibleCpuGroups      = 1;
    17661788    pGip->idCpuMax                = RTMpGetMaxCpuId();
    17671789    for (i = 0; i < RT_ELEMENTS(pGip->aiCpuFromApicId); i++)
     
    17691791    for (i = 0; i < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx); i++)
    17701792        pGip->aiCpuFromCpuSetIdx[i] = UINT16_MAX;
     1793    pGip->aiFirstCpuSetIdxFromCpuGroup[0] = 0;
     1794    for (i = 1; i < RT_ELEMENTS(pGip->aiFirstCpuSetIdxFromCpuGroup); i++)
     1795        pGip->aiFirstCpuSetIdxFromCpuGroup[i] = UINT16_MAX;
     1796#ifdef RT_OS_WINDOWS
     1797    supdrvOSInitGipGroupTable(pDevExt, pGip);
     1798#endif
    17711799    for (i = 0; i < cCpus; i++)
    17721800        supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS, 0 /*uCpuHz*/);
     
    23942422     * run.
    23952423     */
    2396     if (RT_UNLIKELY(iTick == 1))
     2424    if (RT_LIKELY(iTick != 1))
     2425    { /* likely*/ }
     2426    else
    23972427    {
    23982428        iCpu = supdrvGipFindOrAllocCpuIndexForCpuId(pGip, idCpu);
  • trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h

    r62664 r64255  
    215215 *          - nothing.
    216216 */
    217 #define SUPDRV_IOC_VERSION                              0x00260000
     217#define SUPDRV_IOC_VERSION                              0x00270000
    218218
    219219/** SUP_IOCTL_COOKIE. */
  • trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h

    r62664 r64255  
    800800void VBOXCALL   supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser);
    801801
     802/**
     803 * Called during GIP initialization to set up the group table and group count.
     804 *
     805 * This is currently only implemented on windows [lazy bird].
     806 *
     807 * @param   pDevExt             The device globals.
     808 * @param   pGip                The GIP which group table needs initialization.
     809 *                              It's only partially initialized at this point.
     810 */
     811void VBOXCALL   supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip);
     812
     813/**
     814 * Gets the CPU group and member indexes for the given CPU ID.
     815 *
     816 * This is currently only implemented on windows [lazy bird].
     817 *
     818 * @returns CPU group number.
     819 * @param   pDevExt             The device globals.
     820 * @param   idCpu               The ID of the CPU.
     821 * @param   piCpuGroupMember    Where to return the group member number.
     822 */
     823uint16_t VBOXCALL supdrvOSGipGetGroupFromCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu, uint16_t *piCpuGroupMember);
     824
    802825void VBOXCALL   supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession);
    803826bool VBOXCALL   supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc);
  • trunk/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp

    r62490 r64255  
    131131                SUPR3GipSetFlags(SUPGIP_FLAGS_TESTING_ENABLE, UINT32_MAX);
    132132
    133             RTPrintf("tstGIP-2: cCpus=%d  u32UpdateHz=%RU32  u32UpdateIntervalNS=%RU32  u64NanoTSLastUpdateHz=%RX64  u64CpuHz=%RU64  uCpuHzRef=%RU64  u32Mode=%d (%s)  fTestMode=%RTbool  u32Version=%#x\n",
     133            RTPrintf("tstGIP-2: u32Mode=%d (%s)  fTestMode=%RTbool  u32Version=%#x  fGetGipCpu=%#RX32\n",
     134                     g_pSUPGlobalInfoPage->u32Mode,
     135                     SUPGetGIPModeName(g_pSUPGlobalInfoPage),
     136                     fTestMode,
     137                     g_pSUPGlobalInfoPage->u32Version,
     138                     g_pSUPGlobalInfoPage->fGetGipCpu);
     139            RTPrintf("tstGIP-2: cCpus=%d  cPossibleCpus=%d cPossibleCpuGroups=%d cPresentCpus=%d cOnlineCpus=%d\n",
    134140                     g_pSUPGlobalInfoPage->cCpus,
     141                     g_pSUPGlobalInfoPage->cPossibleCpus,
     142                     g_pSUPGlobalInfoPage->cPossibleCpuGroups,
     143                     g_pSUPGlobalInfoPage->cPresentCpus,
     144                     g_pSUPGlobalInfoPage->cOnlineCpus);
     145            RTPrintf("tstGIP-2: u32UpdateHz=%RU32  u32UpdateIntervalNS=%RU32  u64NanoTSLastUpdateHz=%RX64  u64CpuHz=%RU64  uCpuHzRef=%RU64\n",
    135146                     g_pSUPGlobalInfoPage->u32UpdateHz,
    136147                     g_pSUPGlobalInfoPage->u32UpdateIntervalNS,
    137148                     g_pSUPGlobalInfoPage->u64NanoTSLastUpdateHz,
    138149                     g_pSUPGlobalInfoPage->u64CpuHz,
    139                      uCpuHzRef,
    140                      g_pSUPGlobalInfoPage->u32Mode,
    141                      SUPGetGIPModeName(g_pSUPGlobalInfoPage),
    142                      fTestMode,
    143                      g_pSUPGlobalInfoPage->u32Version);
     150                     uCpuHzRef);
     151
    144152            RTPrintf(fHex
    145153                     ? "tstGIP-2:     it: u64NanoTS        delta     u64TSC           UpIntTSC H  TransId      CpuHz      %sTSC Interval History...\n"
  • trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp

    r62677 r64255  
    359359#endif /* VBOXDRV_WITH_FAST_IO */
    360360
     361/** Default ZERO value. */
     362static ULONG                        g_fOptDefaultZero = 0;
     363/** Registry values.
     364 * We wrap these in a struct to ensure they are followed by a little zero
     365 * padding in order to limit the chance of trouble on unpatched systems.  */
     366struct
     367{
     368    /** The ForceAsync registry value. */
     369    ULONG                           fOptForceAsyncTsc;
     370    /** Padding. */
     371    uint64_t                        au64Padding[2];
     372}                                   g_Options = { FALSE, 0, 0 };
     373/** Registry query table for RtlQueryRegistryValues. */
     374static RTL_QUERY_REGISTRY_TABLE     g_aRegValues[] =
     375{
     376    {
     377        /* .QueryRoutine = */   NULL,
     378        /* .Flags = */          RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_TYPECHECK,
     379        /* .Name = */           L"ForceAsyncTsc",
     380        /* .EntryContext = */   &g_Options.fOptForceAsyncTsc,
     381        /* .DefaultType = */    (REG_DWORD << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT) | REG_DWORD,
     382        /* .DefaultData = */    &g_fOptDefaultZero,
     383        /* .DefaultLength = */  sizeof(g_fOptDefaultZero),
     384    },
     385    {   NULL, 0, NULL, NULL, 0, NULL, 0 } /* terminator entry. */
     386};
     387
     388/** Pointer to KeQueryMaximumGroupCount. */
     389static PFNKEQUERYMAXIMUMGROUPCOUNT      g_pfnKeQueryMaximumGroupCount = NULL;
     390/** Pointer to KeGetProcessorIndexFromNumber. */
     391static PFNKEGETPROCESSORINDEXFROMNUMBER g_pfnKeGetProcessorIndexFromNumber = NULL;
     392/** Pointer to KeGetProcessorNumberFromIndex. */
     393static PFNKEGETPROCESSORNUMBERFROMINDEX g_pfnKeGetProcessorNumberFromIndex = NULL;
     394
    361395#ifdef VBOX_WITH_HARDENING
    362396/** Pointer to the stub device instance. */
     
    554588
    555589    /*
     590     * Query options first so any overflows on unpatched machines will do less
     591     * harm (see MS11-011 / 2393802 / 2011-03-18).
     592     *
     593     * Unfortunately, pRegPath isn't documented as zero terminated, even if it
     594     * quite likely always is, so we have to make a copy here.
     595     */
     596    NTSTATUS rcNt;
     597    PWSTR pwszCopy = (PWSTR)ExAllocatePoolWithTag(NonPagedPool, pRegPath->Length + sizeof(WCHAR), 'VBox');
     598    if (pwszCopy)
     599    {
     600        memcpy(pwszCopy, pRegPath->Buffer, pRegPath->Length);
     601        pwszCopy[pRegPath->Length / sizeof(WCHAR)] = '\0';
     602        rcNt = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, pwszCopy,
     603                                      g_aRegValues, NULL /*pvContext*/, NULL /*pvEnv*/);
     604        ExFreePoolWithTag(pwszCopy, 'VBox');
     605        /* Probably safe to ignore rcNt here. */
     606    }
     607
     608    /*
     609     * Resolve methods we want but isn't available everywhere.
     610     */
     611    UNICODE_STRING RoutineName;
     612    RtlInitUnicodeString(&RoutineName, L"KeQueryMaximumGroupCount");
     613    g_pfnKeQueryMaximumGroupCount = (PFNKEQUERYMAXIMUMGROUPCOUNT)MmGetSystemRoutineAddress(&RoutineName);
     614
     615    RtlInitUnicodeString(&RoutineName, L"KeGetProcessorIndexFromNumber");
     616    g_pfnKeGetProcessorIndexFromNumber = (PFNKEGETPROCESSORINDEXFROMNUMBER)MmGetSystemRoutineAddress(&RoutineName);
     617
     618    RtlInitUnicodeString(&RoutineName, L"KeGetProcessorNumberFromIndex");
     619    g_pfnKeGetProcessorNumberFromIndex = (PFNKEGETPROCESSORNUMBERFROMINDEX)MmGetSystemRoutineAddress(&RoutineName);
     620
     621    Assert(   (g_pfnKeGetProcessorNumberFromIndex != NULL) == (g_pfnKeGetProcessorIndexFromNumber != NULL)
     622           && (g_pfnKeGetProcessorNumberFromIndex != NULL) == (g_pfnKeQueryMaximumGroupCount != NULL)); /* all or nothing. */
     623
     624    /*
    556625     * Initialize the runtime (IPRT).
    557626     */
    558     NTSTATUS rcNt;
    559627    int vrc = RTR0Init(0);
    560628    if (RT_SUCCESS(vrc))
     
    16431711
    16441712
     1713void VBOXCALL supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip)
     1714{
     1715    NOREF(pDevExt);
     1716
     1717    /*
     1718     * The indexes are assigned in group order (see initterm-r0drv-nt.cpp).
     1719     */
     1720    if (   g_pfnKeQueryMaximumGroupCount
     1721        && g_pfnKeGetProcessorIndexFromNumber)
     1722    {
     1723        unsigned cGroups = g_pfnKeQueryMaximumGroupCount();
     1724        AssertStmt(cGroups > 0, cGroups = 1);
     1725        AssertStmt(cGroups < RT_ELEMENTS(pGip->aiFirstCpuSetIdxFromCpuGroup),
     1726                   cGroups = RT_ELEMENTS(pGip->aiFirstCpuSetIdxFromCpuGroup));
     1727        pGip->cPossibleCpuGroups = cGroups;
     1728
     1729        KEPROCESSORINDEX idxCpuMin = 0;
     1730        for (unsigned iGroup = 0; iGroup < cGroups; iGroup++)
     1731        {
     1732            PROCESSOR_NUMBER ProcNum;
     1733            ProcNum.Group    = (USHORT)iGroup;
     1734            ProcNum.Number   = 0;
     1735            ProcNum.Reserved = 0;
     1736            KEPROCESSORINDEX idxCpu = g_pfnKeGetProcessorIndexFromNumber(&ProcNum);
     1737            Assert(idxCpu != INVALID_PROCESSOR_INDEX);
     1738            Assert(idxCpu >= idxCpuMin);
     1739            idxCpuMin = idxCpu;
     1740            pGip->aiFirstCpuSetIdxFromCpuGroup[iGroup] = (uint16_t)idxCpu;
     1741        }
     1742    }
     1743    else
     1744    {
     1745        Assert(!g_pfnKeQueryMaximumGroupCount);
     1746        Assert(!g_pfnKeGetProcessorIndexFromNumber);
     1747
     1748        pGip->cPossibleCpuGroups              = 1;
     1749        pGip->aiFirstCpuSetIdxFromCpuGroup[0] = 0;
     1750    }
     1751}
     1752
     1753
     1754uint16_t VBOXCALL supdrvOSGipGetGroupFromCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu, uint16_t *piCpuGroupMember)
     1755{
     1756    NOREF(pDevExt);
     1757
     1758    /*
     1759     * This is just a wrapper around KeGetProcessorNumberFromIndex.
     1760     */
     1761    if (g_pfnKeGetProcessorNumberFromIndex)
     1762    {
     1763        PROCESSOR_NUMBER ProcNum = { UINT16_MAX, UINT8_MAX, 0 };
     1764        NTSTATUS rcNt = g_pfnKeGetProcessorNumberFromIndex(idCpu, &ProcNum);
     1765        if (NT_SUCCESS(rcNt))
     1766        {
     1767            Assert(ProcNum.Group < g_pfnKeQueryMaximumGroupCount());
     1768            *piCpuGroupMember = ProcNum.Number;
     1769            return ProcNum.Group;
     1770        }
     1771
     1772        AssertMsgFailed(("rcNt=%#x for idCpu=%u\n", rcNt, idCpu));
     1773    }
     1774
     1775    *piCpuGroupMember = 0;
     1776    return idCpu;
     1777}
     1778
     1779
    16451780/**
    16461781 * Initializes any OS specific object creator fields.
     
    16801815{
    16811816    RT_NOREF1(pDevExt);
    1682     return false;
     1817    return g_Options.fOptForceAsyncTsc != 0;
    16831818}
    16841819
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