Changeset 64281 in vbox for trunk/src/VBox/HostDrivers/Support
- Timestamp:
- Oct 15, 2016 4:46:29 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 111296
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPDrvGip.cpp
r64260 r64281 1320 1320 pGip->aCPUs[i].iCpuGroupMember = iCpuSet; 1321 1321 #ifdef RT_OS_WINDOWS 1322 pGip->aCPUs[i].iCpuGroup = supdrvOSGipGetGroupFromCpu(pDevExt, idCpu, &pGip->aCPUs[i].iCpuGroupMember);1322 supdrvOSGipInitGroupBitsForCpu(pDevExt, pGip, &pGip->aCPUs[i]); 1323 1323 #endif 1324 1324 … … 1744 1744 * Initializes the GIP data. 1745 1745 * 1746 * @returns VBox status code. 1746 1747 * @param pDevExt Pointer to the device instance data. 1747 1748 * @param pGip Pointer to the read-write kernel mapping of the GIP. … … 1751 1752 * @param uUpdateIntervalNS The update interval in nanoseconds. 1752 1753 * @param cCpus The CPU count. 1753 */ 1754 static void supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys, 1755 uint64_t u64NanoTS, unsigned uUpdateHz, unsigned uUpdateIntervalNS, unsigned cCpus) 1756 { 1757 size_t const cbGip = RT_ALIGN_Z(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[cCpus]), PAGE_SIZE); 1758 unsigned i; 1754 * @param cbGipCpuGroups The supdrvOSGipGetGroupTableSize return value we 1755 * used when allocating the GIP structure. 1756 */ 1757 static int supdrvGipInit(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, RTHCPHYS HCPhys, 1758 uint64_t u64NanoTS, unsigned uUpdateHz, unsigned uUpdateIntervalNS, 1759 unsigned cCpus, size_t cbGipCpuGroups) 1760 { 1761 size_t const cbGip = RT_ALIGN_Z(RT_OFFSETOF(SUPGLOBALINFOPAGE, aCPUs[cCpus]) + cbGipCpuGroups, PAGE_SIZE); 1762 unsigned i; 1759 1763 #ifdef DEBUG_DARWIN_GIP 1760 1764 OSDBGPRINT(("supdrvGipInit: pGip=%p HCPhys=%lx u64NanoTS=%llu uUpdateHz=%d cCpus=%u\n", pGip, (long)HCPhys, u64NanoTS, uUpdateHz, cCpus)); … … 1794 1798 for (i = 0; i < RT_ELEMENTS(pGip->aiCpuFromCpuSetIdx); i++) 1795 1799 pGip->aiCpuFromCpuSetIdx[i] = UINT16_MAX; 1796 pGip->aiFirstCpuSetIdxFromCpuGroup[0] = 0; 1797 for (i = 1; i < RT_ELEMENTS(pGip->aiFirstCpuSetIdxFromCpuGroup); i++) 1798 pGip->aiFirstCpuSetIdxFromCpuGroup[i] = UINT16_MAX; 1799 #ifdef RT_OS_WINDOWS 1800 supdrvOSInitGipGroupTable(pDevExt, pGip); 1801 #endif 1800 for (i = 0; i < RT_ELEMENTS(pGip->aoffCpuGroup); i++) 1801 pGip->aoffCpuGroup[i] = UINT16_MAX; 1802 1802 for (i = 0; i < cCpus; i++) 1803 1803 supdrvGipInitCpu(pGip, &pGip->aCPUs[i], u64NanoTS, 0 /*uCpuHz*/); 1804 #ifdef RT_OS_WINDOWS 1805 int rc = supdrvOSInitGipGroupTable(pDevExt, pGip, cbGipCpuGroups); 1806 AssertRCReturn(rc, rc); 1807 #endif 1804 1808 1805 1809 /* … … 1809 1813 pDevExt->HCPhysGip = HCPhys; 1810 1814 pDevExt->cGipUsers = 0; 1815 1816 return VINF_SUCCESS; 1811 1817 } 1812 1818 … … 1821 1827 { 1822 1828 PSUPGLOBALINFOPAGE pGip; 1829 size_t cbGip; 1830 size_t cbGipCpuGroups; 1823 1831 RTHCPHYS HCPhysGip; 1824 1832 uint32_t u32SystemResolution; … … 1862 1870 * Allocate a contiguous set of pages with a default kernel mapping. 1863 1871 */ 1864 rc = RTR0MemObjAllocCont(&pDevExt->GipMemObj, RT_UOFFSETOF(SUPGLOBALINFOPAGE, aCPUs[cCpus]), false /*fExecutable*/); 1872 cbGipCpuGroups = supdrvOSGipGetGroupTableSize(pDevExt); 1873 cbGip = RT_UOFFSETOF(SUPGLOBALINFOPAGE, aCPUs[cCpus]) + cbGipCpuGroups; 1874 rc = RTR0MemObjAllocCont(&pDevExt->GipMemObj, cbGip, false /*fExecutable*/); 1865 1875 if (RT_FAILURE(rc)) 1866 1876 { … … 1884 1894 u32Interval += u32SystemResolution - uMod; 1885 1895 1886 supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), RT_NS_1SEC / u32Interval /*=Hz*/, u32Interval, cCpus); 1887 1888 /* 1889 * Important sanity check... 1896 rc = supdrvGipInit(pDevExt, pGip, HCPhysGip, RTTimeSystemNanoTS(), RT_NS_1SEC / u32Interval /*=Hz*/, u32Interval, 1897 cCpus, cbGipCpuGroups); 1898 1899 /* 1900 * Important sanity check... (Sets rc) 1890 1901 */ 1891 1902 if (RT_UNLIKELY( pGip->enmUseTscDelta == SUPGIPUSETSCDELTA_ZERO_CLAIMED … … 1894 1905 { 1895 1906 OSDBGPRINT(("supdrvGipCreate: Host-OS/user claims the TSC-deltas are zero but we detected async. TSC! Bad.\n")); 1896 r eturnVERR_INTERNAL_ERROR_2;1907 rc = VERR_INTERNAL_ERROR_2; 1897 1908 } 1898 1909 1899 1910 /* It doesn't make sense to do TSC-delta detection on systems we detect as async. */ 1900 AssertReturn( pGip->u32Mode != SUPGIPMODE_ASYNC_TSC 1901 || pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ZERO_CLAIMED, VERR_INTERNAL_ERROR_3); 1911 AssertStmt( pGip->u32Mode != SUPGIPMODE_ASYNC_TSC 1912 || pGip->enmUseTscDelta <= SUPGIPUSETSCDELTA_ZERO_CLAIMED, 1913 rc = VERR_INTERNAL_ERROR_3); 1902 1914 1903 1915 /* … … 1912 1924 * array with more reasonable values. 1913 1925 */ 1914 if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC)1915 {1916 rc = supdrvGipInitMeasureTscFreq(pGip, true /*fRough*/); /* cannot fail */1917 supdrvGipInitStartTimerForRefiningInvariantTscFreq(pDevExt);1918 }1919 else1920 rc = supdrvGipInitMeasureTscFreq(pGip, false /*fRough*/);1921 1926 if (RT_SUCCESS(rc)) 1922 1927 { 1923 /* 1924 * Start TSC-delta measurement thread before we start getting MP 1925 * events that will try kick it into action (includes the 1926 * RTMpOnAll/supdrvGipInitOnCpu call below). 1927 */ 1928 RTCpuSetEmpty(&pDevExt->TscDeltaCpuSet); 1929 RTCpuSetEmpty(&pDevExt->TscDeltaObtainedCpuSet); 1930 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 1931 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED) 1932 rc = supdrvTscDeltaThreadInit(pDevExt); 1933 #endif 1928 if (pGip->u32Mode == SUPGIPMODE_INVARIANT_TSC) 1929 { 1930 rc = supdrvGipInitMeasureTscFreq(pGip, true /*fRough*/); /* cannot fail */ 1931 supdrvGipInitStartTimerForRefiningInvariantTscFreq(pDevExt); 1932 } 1933 else 1934 rc = supdrvGipInitMeasureTscFreq(pGip, false /*fRough*/); 1934 1935 if (RT_SUCCESS(rc)) 1935 1936 { 1936 rc = RTMpNotificationRegister(supdrvGipMpEvent, pDevExt); 1937 /* 1938 * Start TSC-delta measurement thread before we start getting MP 1939 * events that will try kick it into action (includes the 1940 * RTMpOnAll/supdrvGipInitOnCpu call below). 1941 */ 1942 RTCpuSetEmpty(&pDevExt->TscDeltaCpuSet); 1943 RTCpuSetEmpty(&pDevExt->TscDeltaObtainedCpuSet); 1944 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 1945 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED) 1946 rc = supdrvTscDeltaThreadInit(pDevExt); 1947 #endif 1937 1948 if (RT_SUCCESS(rc)) 1938 1949 { 1939 /* 1940 * Do GIP initialization on all online CPUs. Wake up the 1941 * TSC-delta thread afterwards. 1942 */ 1943 rc = RTMpOnAll(supdrvGipInitOnCpu, pDevExt, pGip); 1950 rc = RTMpNotificationRegister(supdrvGipMpEvent, pDevExt); 1944 1951 if (RT_SUCCESS(rc)) 1945 1952 { 1946 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 1947 supdrvTscDeltaThreadStartMeasurement(pDevExt, true /* fForceAll */); 1948 #else 1949 uint16_t iCpu; 1950 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED) 1953 /* 1954 * Do GIP initialization on all online CPUs. Wake up the 1955 * TSC-delta thread afterwards. 1956 */ 1957 rc = RTMpOnAll(supdrvGipInitOnCpu, pDevExt, pGip); 1958 if (RT_SUCCESS(rc)) 1951 1959 { 1952 /*1953 * Measure the TSC deltas now that we have MP notifications.1954 */1955 int cTries = 5;1956 do1960 #ifdef SUPDRV_USE_TSC_DELTA_THREAD 1961 supdrvTscDeltaThreadStartMeasurement(pDevExt, true /* fForceAll */); 1962 #else 1963 uint16_t iCpu; 1964 if (pGip->enmUseTscDelta > SUPGIPUSETSCDELTA_ZERO_CLAIMED) 1957 1965 { 1958 rc = supdrvTscMeasureInitialDeltas(pDevExt); 1959 if ( rc != VERR_TRY_AGAIN 1960 && rc != VERR_CPU_OFFLINE) 1961 break; 1962 } while (--cTries > 0); 1963 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++) 1964 Log(("supdrvTscDeltaInit: cpu[%u] delta %lld\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta)); 1966 /* 1967 * Measure the TSC deltas now that we have MP notifications. 1968 */ 1969 int cTries = 5; 1970 do 1971 { 1972 rc = supdrvTscMeasureInitialDeltas(pDevExt); 1973 if ( rc != VERR_TRY_AGAIN 1974 && rc != VERR_CPU_OFFLINE) 1975 break; 1976 } while (--cTries > 0); 1977 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++) 1978 Log(("supdrvTscDeltaInit: cpu[%u] delta %lld\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta)); 1979 } 1980 else 1981 { 1982 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++) 1983 AssertMsg(!pGip->aCPUs[iCpu].i64TSCDelta, ("iCpu=%u %lld mode=%d\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta, pGip->u32Mode)); 1984 } 1985 if (RT_SUCCESS(rc)) 1986 #endif 1987 { 1988 /* 1989 * Create the timer. 1990 * If CPU_ALL isn't supported we'll have to fall back to synchronous mode. 1991 */ 1992 if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC) 1993 { 1994 rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, RTTIMER_FLAGS_CPU_ALL, 1995 supdrvGipAsyncTimer, pDevExt); 1996 if (rc == VERR_NOT_SUPPORTED) 1997 { 1998 OSDBGPRINT(("supdrvGipCreate: omni timer not supported, falling back to synchronous mode\n")); 1999 pGip->u32Mode = SUPGIPMODE_SYNC_TSC; 2000 } 2001 } 2002 if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC) 2003 rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0 /* fFlags */, 2004 supdrvGipSyncAndInvariantTimer, pDevExt); 2005 if (RT_SUCCESS(rc)) 2006 { 2007 /* 2008 * We're good. 2009 */ 2010 Log(("supdrvGipCreate: %u ns interval.\n", u32Interval)); 2011 supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt); 2012 2013 g_pSUPGlobalInfoPage = pGip; 2014 return VINF_SUCCESS; 2015 } 2016 2017 OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %u ns interval. rc=%Rrc\n", u32Interval, rc)); 2018 Assert(!pDevExt->pGipTimer); 2019 } 1965 2020 } 1966 2021 else 1967 { 1968 for (iCpu = 0; iCpu < pGip->cCpus; iCpu++) 1969 AssertMsg(!pGip->aCPUs[iCpu].i64TSCDelta, ("iCpu=%u %lld mode=%d\n", iCpu, pGip->aCPUs[iCpu].i64TSCDelta, pGip->u32Mode)); 1970 } 1971 if (RT_SUCCESS(rc)) 1972 #endif 1973 { 1974 /* 1975 * Create the timer. 1976 * If CPU_ALL isn't supported we'll have to fall back to synchronous mode. 1977 */ 1978 if (pGip->u32Mode == SUPGIPMODE_ASYNC_TSC) 1979 { 1980 rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, RTTIMER_FLAGS_CPU_ALL, 1981 supdrvGipAsyncTimer, pDevExt); 1982 if (rc == VERR_NOT_SUPPORTED) 1983 { 1984 OSDBGPRINT(("supdrvGipCreate: omni timer not supported, falling back to synchronous mode\n")); 1985 pGip->u32Mode = SUPGIPMODE_SYNC_TSC; 1986 } 1987 } 1988 if (pGip->u32Mode != SUPGIPMODE_ASYNC_TSC) 1989 rc = RTTimerCreateEx(&pDevExt->pGipTimer, u32Interval, 0 /* fFlags */, 1990 supdrvGipSyncAndInvariantTimer, pDevExt); 1991 if (RT_SUCCESS(rc)) 1992 { 1993 /* 1994 * We're good. 1995 */ 1996 Log(("supdrvGipCreate: %u ns interval.\n", u32Interval)); 1997 supdrvGipReleaseHigherTimerFrequencyFromSystem(pDevExt); 1998 1999 g_pSUPGlobalInfoPage = pGip; 2000 return VINF_SUCCESS; 2001 } 2002 2003 OSDBGPRINT(("supdrvGipCreate: failed create GIP timer at %u ns interval. rc=%Rrc\n", u32Interval, rc)); 2004 Assert(!pDevExt->pGipTimer); 2005 } 2022 OSDBGPRINT(("supdrvGipCreate: RTMpOnAll failed. rc=%Rrc\n", rc)); 2006 2023 } 2007 2024 else 2008 OSDBGPRINT(("supdrvGipCreate: RTMpOnAll failed. rc=%Rrc\n", rc));2025 OSDBGPRINT(("supdrvGipCreate: failed to register MP event notfication. rc=%Rrc\n", rc)); 2009 2026 } 2010 2027 else 2011 OSDBGPRINT(("supdrvGipCreate: failed to register MP event notfication. rc=%Rrc\n", rc));2028 OSDBGPRINT(("supdrvGipCreate: supdrvTscDeltaInit failed. rc=%Rrc\n", rc)); 2012 2029 } 2013 2030 else 2014 OSDBGPRINT(("supdrvGipCreate: supdrvTscDeltaInit failed. rc=%Rrc\n", rc)); 2015 } 2016 else 2017 OSDBGPRINT(("supdrvGipCreate: supdrvTscMeasureInitialDeltas failed. rc=%Rrc\n", rc)); 2031 OSDBGPRINT(("supdrvGipCreate: supdrvTscMeasureInitialDeltas failed. rc=%Rrc\n", rc)); 2032 } 2018 2033 2019 2034 /* Releases timer frequency increase too. */ -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r64255 r64281 215 215 * - nothing. 216 216 */ 217 #define SUPDRV_IOC_VERSION 0x002 70000217 #define SUPDRV_IOC_VERSION 0x00280000 218 218 219 219 /** SUP_IOCTL_COOKIE. */ -
trunk/src/VBox/HostDrivers/Support/SUPDrvInternal.h
r64255 r64281 801 801 802 802 /** 803 * Called during GIP initializtion to calc the CPU group table size. 804 * 805 * This is currently only implemented on windows [lazy bird]. 806 * 807 * @returns Number of bytes needed for SUPGIPCPUGROUP structures. 808 * @param pDevExt The device globals. 809 */ 810 size_t VBOXCALL supdrvOSGipGetGroupTableSize(PSUPDRVDEVEXT pDevExt); 811 812 /** 803 813 * Called during GIP initialization to set up the group table and group count. 804 814 * … … 808 818 * @param pGip The GIP which group table needs initialization. 809 819 * It's only partially initialized at this point. 810 */ 811 void VBOXCALL supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip); 812 813 /** 814 * Gets the CPU group and member indexes for the given CPU ID. 820 * @param cbGipCpuGroups What supdrvOSGipGetGroupTableSize returned. 821 */ 822 int VBOXCALL supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, size_t cbGipCpuGroups); 823 824 /** 825 * Initializes the group related members when a CPU is added to the GIP. 826 * 827 * This is called both during GIP initalization and during an CPU online event. 815 828 * 816 829 * This is currently only implemented on windows [lazy bird]. … … 821 834 * @param piCpuGroupMember Where to return the group member number. 822 835 */ 823 uint16_t VBOXCALL supdrvOSGipGetGroupFromCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu, uint16_t *piCpuGroupMember);836 void VBOXCALL supdrvOSGipInitGroupBitsForCpu(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pGipCpu); 824 837 825 838 void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession); -
trunk/src/VBox/HostDrivers/Support/testcase/tstGIP-2.cpp
r64255 r64281 137 137 g_pSUPGlobalInfoPage->u32Version, 138 138 g_pSUPGlobalInfoPage->fGetGipCpu); 139 RTPrintf("tstGIP-2: cCpus=%d cPossibleCpus=%d cPossibleCpuGroups=%d cPresentCpus=%d cOnlineCpus=%d \n",139 RTPrintf("tstGIP-2: cCpus=%d cPossibleCpus=%d cPossibleCpuGroups=%d cPresentCpus=%d cOnlineCpus=%d idCpuMax=%#x\n", 140 140 g_pSUPGlobalInfoPage->cCpus, 141 141 g_pSUPGlobalInfoPage->cPossibleCpus, 142 142 g_pSUPGlobalInfoPage->cPossibleCpuGroups, 143 143 g_pSUPGlobalInfoPage->cPresentCpus, 144 g_pSUPGlobalInfoPage->cOnlineCpus); 144 g_pSUPGlobalInfoPage->cOnlineCpus, 145 g_pSUPGlobalInfoPage->idCpuMax); 145 146 RTPrintf("tstGIP-2: u32UpdateHz=%RU32 u32UpdateIntervalNS=%RU32 u64NanoTSLastUpdateHz=%RX64 u64CpuHz=%RU64 uCpuHzRef=%RU64\n", 146 147 g_pSUPGlobalInfoPage->u32UpdateHz, … … 149 150 g_pSUPGlobalInfoPage->u64CpuHz, 150 151 uCpuHzRef); 152 for (uint32_t iCpu = 0; iCpu < g_pSUPGlobalInfoPage->cCpus; iCpu++) 153 if (g_pSUPGlobalInfoPage->aCPUs[iCpu].enmState != SUPGIPCPUSTATE_INVALID) 154 { 155 SUPGIPCPU const *pGipCpu = &g_pSUPGlobalInfoPage->aCPUs[iCpu]; 156 RTPrintf("tstGIP-2: aCPU[%u]: enmState=%d iCpuSet=%u idCpu=%#010x iCpuGroup=%u iCpuGroupMember=%u idApic=%#x\n", 157 iCpu, pGipCpu->enmState, pGipCpu->iCpuSet, pGipCpu->idCpu, pGipCpu->iCpuGroup, 158 pGipCpu->iCpuGroupMember, pGipCpu->idApic); 159 } 151 160 152 161 RTPrintf(fHex -
trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
r64255 r64281 1711 1711 1712 1712 1713 void VBOXCALL supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip)1713 size_t VBOXCALL supdrvOSGipGetGroupTableSize(PSUPDRVDEVEXT pDevExt) 1714 1714 { 1715 1715 NOREF(pDevExt); 1716 uint32_t cMaxCpus = RTMpGetCount(); 1717 uint32_t cGroups = RTMpGetMaxCpuGroupCount(); 1718 1719 return cGroups * RT_OFFSETOF(SUPGIPCPUGROUP, aiCpuSetIdxs) 1720 + RT_SIZEOFMEMB(SUPGIPCPUGROUP, aiCpuSetIdxs[0]) * cMaxCpus; 1721 } 1722 1723 1724 int VBOXCALL supdrvOSInitGipGroupTable(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, size_t cbGipCpuGroups) 1725 { 1726 Assert(cbGipCpuGroups > 0); NOREF(cbGipCpuGroups); NOREF(pDevExt); 1727 1728 unsigned const cGroups = RTMpGetMaxCpuGroupCount(); 1729 AssertReturn(cGroups > 0 && cGroups < RT_ELEMENTS(pGip->aoffCpuGroup), VERR_INTERNAL_ERROR_2); 1730 pGip->cPossibleCpuGroups = cGroups; 1731 1732 PSUPGIPCPUGROUP pGroup = (PSUPGIPCPUGROUP)&pGip->aCPUs[pGip->cCpus]; 1733 for (uint32_t idxGroup = 0; idxGroup < cGroups; idxGroup++) 1734 { 1735 uint32_t cActive = 0; 1736 uint32_t cMax = RTMpGetCpuGroupCounts(idxGroup, &cActive); 1737 uint32_t cbNeeded = RT_OFFSETOF(SUPGIPCPUGROUP, aiCpuSetIdxs[cMax]); 1738 AssertReturn(cbNeeded <= cbGipCpuGroups, VERR_INTERNAL_ERROR_3); 1739 AssertReturn(cActive <= cMax, VERR_INTERNAL_ERROR_4); 1740 1741 pGip->aoffCpuGroup[idxGroup] = (uint16_t)((uintptr_t)pGroup - (uintptr_t)pGip); 1742 pGroup->cMembers = cActive; 1743 pGroup->cMaxMembers = cMax; 1744 for (uint32_t idxMember = 0; idxMember < cMax; idxMember++) 1745 { 1746 pGroup->aiCpuSetIdxs[idxMember] = RTMpSetIndexFromCpuGroupMember(idxGroup, idxMember); 1747 Assert((unsigned)pGroup->aiCpuSetIdxs[idxMember] < pGip->cPossibleCpus); 1748 } 1749 1750 /* advance. */ 1751 cbGipCpuGroups -= cbNeeded; 1752 pGroup = (PSUPGIPCPUGROUP)&pGroup->aiCpuSetIdxs[cMax]; 1753 } 1754 1755 return VINF_SUCCESS; 1756 } 1757 1758 1759 void VBOXCALL supdrvOSGipInitGroupBitsForCpu(PSUPDRVDEVEXT pDevExt, PSUPGLOBALINFOPAGE pGip, PSUPGIPCPU pGipCpu) 1760 { 1761 NOREF(pDevExt); 1716 1762 1717 1763 /* 1718 * T he indexes are assigned in group order (see initterm-r0drv-nt.cpp).1764 * Translate the CPU index into a group and member. 1719 1765 */ 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 1754 uint16_t VBOXCALL supdrvOSGipGetGroupFromCpu(PSUPDRVDEVEXT pDevExt, RTCPUID idCpu, uint16_t *piCpuGroupMember) 1755 { 1756 NOREF(pDevExt); 1766 PROCESSOR_NUMBER ProcNum = { 0, pGipCpu->iCpuSet, 0 }; 1767 if (g_pfnKeGetProcessorNumberFromIndex) 1768 { 1769 NTSTATUS rcNt = g_pfnKeGetProcessorNumberFromIndex(pGipCpu->iCpuSet, &ProcNum); 1770 if (NT_SUCCESS(rcNt)) 1771 Assert(ProcNum.Group < g_pfnKeQueryMaximumGroupCount()); 1772 else 1773 { 1774 AssertFailed(); 1775 ProcNum.Group = 0; 1776 ProcNum.Number = pGipCpu->iCpuSet; 1777 } 1778 } 1779 pGipCpu->iCpuGroup = ProcNum.Group; 1780 pGipCpu->iCpuGroupMember = ProcNum.Number; 1757 1781 1758 1782 /* 1759 * This is just a wrapper around KeGetProcessorNumberFromIndex.1783 * Update the group info. Just do this wholesale for now (doesn't scale well). 1760 1784 */ 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; 1785 for (uint32_t idxGroup = 0; idxGroup < pGip->cPossibleCpuGroups; idxGroup++) 1786 if (pGip->aoffCpuGroup[idxGroup] != UINT16_MAX) 1787 { 1788 PSUPGIPCPUGROUP pGroup = (PSUPGIPCPUGROUP)((uintptr_t)pGip + pGip->aoffCpuGroup[idxGroup]); 1789 1790 uint32_t cActive = 0; 1791 uint32_t cMax = RTMpGetCpuGroupCounts(idxGroup, &cActive); 1792 AssertStmt(cMax == pGroup->cMaxMembers, cMax = pGroup->cMaxMembers); 1793 AssertStmt(cActive <= cMax, cActive = cMax); 1794 if (pGroup->cMembers != cActive) 1795 pGroup->cMembers = cActive; 1796 1797 for (uint32_t idxMember = 0; idxMember < cMax; idxMember++) 1798 { 1799 int idxCpuSet = RTMpSetIndexFromCpuGroupMember(idxGroup, idxMember); 1800 AssertMsg((unsigned)idxCpuSet < pGip->cPossibleCpus, 1801 ("%d vs %d for %u.%u\n", idxCpuSet, pGip->cPossibleCpus, idxGroup, idxMember)); 1802 1803 if (pGroup->aiCpuSetIdxs[idxMember] != idxCpuSet) 1804 pGroup->aiCpuSetIdxs[idxMember] = idxCpuSet; 1805 } 1806 } 1777 1807 } 1778 1808
Note:
See TracChangeset
for help on using the changeset viewer.