VirtualBox

Ignore:
Timestamp:
Oct 13, 2016 3:18:21 PM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
111265
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).

File:
1 edited

Legend:

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette