VirtualBox

Changeset 53720 in vbox for trunk/src/VBox/Runtime/r0drv/nt


Ignore:
Timestamp:
Jan 3, 2015 5:57:05 AM (10 years ago)
Author:
vboxsync
Message:

IPRT/r0drv/nt: More RTMpPokeCpu work, this time for 32-bit windows 7 and later.

Location:
trunk/src/VBox/Runtime/r0drv/nt
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp

    r53718 r53720  
    5656/** KeFlushQueuedDpcs, introduced in XP. */
    5757PFNMYKEFLUSHQUEUEDDPCS              g_pfnrtNtKeFlushQueuedDpcs;
    58 /** HalRequestIpi, introduced in ??. */
    59 PFNHALREQUESTIPI                    g_pfnrtNtHalRequestIpi;
     58/** HalRequestIpi, version introduced with windows 7. */
     59PFNHALREQUESTIPI_W7PLUS             g_pfnrtHalRequestIpiW7Plus;
     60/** HalRequestIpi, version valid up to windows vista?? */
     61PFNHALREQUESTIPI_PRE_W7             g_pfnrtHalRequestIpiPreW7;
    6062/** HalSendSoftwareInterrupt, introduced in AMD64 version of W2K3. */
    6163PFNHALSENDSOFTWAREINTERRUPT         g_pfnrtNtHalSendSoftwareInterrupt;
     
    6466/** KeIpiGenericCall - Introduced in Windows Server 2003. */
    6567PFNRTKEIPIGENERICCALL               g_pfnrtKeIpiGenericCall;
     68/** KeInitializeAffinityEx - Introducted in Windows 7. */
     69PFNKEINITIALIZEAFFINITYEX           g_pfnrtKeInitializeAffinityEx;
     70/** KeAddProcessorAffinityEx - Introducted in Windows 7. */
     71PFNKEADDPROCESSORAFFINITYEX         g_pfnrtKeAddProcessorAffinityEx;
     72/** KeGetProcessorIndexFromNumber - Introducted in Windows  7. */
     73PFNKEGETPROCESSORINDEXFROMNUMBER    g_pfnrtKeGetProcessorIndexFromNumber;
    6674/** RtlGetVersion, introduced in ??. */
    6775PFNRTRTLGETVERSION                  g_pfnrtRtlGetVersion;
     
    216224    g_pfnrtNtExSetTimerResolution = NULL;
    217225    g_pfnrtNtKeFlushQueuedDpcs = NULL;
    218     g_pfnrtNtHalRequestIpi = NULL;
     226    g_pfnrtHalRequestIpiW7Plus = NULL;
     227    g_pfnrtHalRequestIpiPreW7 = NULL;
    219228    g_pfnrtNtHalSendSoftwareInterrupt = NULL;
    220229    g_pfnrtKeIpiGenericCall = NULL;
     230    g_pfnrtKeInitializeAffinityEx = NULL;
     231    g_pfnrtKeAddProcessorAffinityEx = NULL;
     232    g_pfnrtKeGetProcessorIndexFromNumber = NULL;
    221233    g_pfnrtRtlGetVersion = NULL;
    222234    g_pfnrtKeQueryInterruptTime = NULL;
     
    233245
    234246    RtlInitUnicodeString(&RoutineName, L"HalRequestIpi");
    235     g_pfnrtNtHalRequestIpi = (PFNHALREQUESTIPI)MmGetSystemRoutineAddress(&RoutineName);
     247    g_pfnrtHalRequestIpiW7Plus = (PFNHALREQUESTIPI_W7PLUS)MmGetSystemRoutineAddress(&RoutineName);
     248    g_pfnrtHalRequestIpiPreW7 = (PFNHALREQUESTIPI_PRE_W7)g_pfnrtHalRequestIpiW7Plus;
    236249
    237250    RtlInitUnicodeString(&RoutineName, L"HalSendSoftwareInterrupt");
     
    240253    RtlInitUnicodeString(&RoutineName, L"KeIpiGenericCall");
    241254    g_pfnrtKeIpiGenericCall = (PFNRTKEIPIGENERICCALL)MmGetSystemRoutineAddress(&RoutineName);
     255
     256    RtlInitUnicodeString(&RoutineName, L"KeInitializeAffinityEx");
     257    g_pfnrtKeInitializeAffinityEx = (PFNKEINITIALIZEAFFINITYEX)MmGetSystemRoutineAddress(&RoutineName);
     258
     259    RtlInitUnicodeString(&RoutineName, L"KeAddProcessorAffinityEx");
     260    g_pfnrtKeAddProcessorAffinityEx = (PFNKEADDPROCESSORAFFINITYEX)MmGetSystemRoutineAddress(&RoutineName);
     261
     262    RtlInitUnicodeString(&RoutineName, L"KeGetProcessorIndexFromNumber");
     263    g_pfnrtKeGetProcessorIndexFromNumber = (PFNKEGETPROCESSORINDEXFROMNUMBER)MmGetSystemRoutineAddress(&RoutineName);
    242264
    243265    RtlInitUnicodeString(&RoutineName, L"RtlGetVersion");
     
    388410     * Special IPI fun for RTMpPokeCpu.
    389411     *
    390      * On Vista and later the DPC fallback doesn't seem to reliably send IPIs,
     412     * On Vista and later the DPC method doesn't seem to reliably send IPIs,
    391413     * so we have to use alternative methods.  The NtHalSendSoftwareInterrupt
    392      * is preferrable, but if that's not available we'll settle for broadcast
    393      * IPIs.
    394      */
     414     * is preferrable, but it's AMD64 only.  The NalRequestIpip method changed
     415     * in Windows 7 with the lots-of-processors-support, but it's the only
     416     * targeted IPI game in town if we cannot use KeInsertQueueDpc.  Worst case
     417     * we use broadcast IPIs.
     418     */
     419    if (   OsVerInfo.uMajorVer > 6
     420        || (OsVerInfo.uMajorVer == 6 && OsVerInfo.uMinorVer > 0))
     421        g_pfnrtHalRequestIpiPreW7 = NULL;
     422    else
     423        g_pfnrtHalRequestIpiW7Plus = NULL;
     424
    395425    g_pfnrtMpPokeCpuWorker = rtMpPokeCpuUsingDpc;
    396426#ifndef IPRT_TARGET_NT4
    397427    if (g_pfnrtNtHalSendSoftwareInterrupt)
    398428        g_pfnrtMpPokeCpuWorker = rtMpPokeCpuUsingHalSendSoftwareInterrupt;
     429    else if (   g_pfnrtHalRequestIpiW7Plus
     430             && g_pfnrtKeInitializeAffinityEx
     431             && g_pfnrtKeAddProcessorAffinityEx
     432             && g_pfnrtKeGetProcessorIndexFromNumber)
     433        g_pfnrtMpPokeCpuWorker = rtMpPokeCpuUsingHalReqestIpiW7Plus;
    399434    else if (OsVerInfo.uMajorVer >= 6 && g_pfnrtKeIpiGenericCall)
    400435        g_pfnrtMpPokeCpuWorker = rtMpPokeCpuUsingBroadcastIpi;
  • trunk/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h

    r53718 r53720  
    2929
    3030#include <iprt/cpuset.h>
     31#include <iprt/nt/nt.h>
    3132
    3233RT_C_DECLS_BEGIN
     
    3738typedef ULONG (__stdcall *PFNMYEXSETTIMERRESOLUTION)(ULONG, BOOLEAN);
    3839typedef VOID (__stdcall *PFNMYKEFLUSHQUEUEDDPCS)(VOID);
    39 typedef VOID (__stdcall *PFNHALREQUESTIPI)(KAFFINITY TargetSet);
    4040typedef VOID (__stdcall *PFNHALSENDSOFTWAREINTERRUPT)(ULONG ProcessorNumber, KIRQL Irql);
    4141typedef int (__stdcall *PFNRTSENDIPI)(RTCPUID idCpu);
     
    5656extern PFNMYEXSETTIMERRESOLUTION        g_pfnrtNtExSetTimerResolution;
    5757extern PFNMYKEFLUSHQUEUEDDPCS           g_pfnrtNtKeFlushQueuedDpcs;
    58 extern PFNHALREQUESTIPI                 g_pfnrtNtHalRequestIpi;
     58extern PFNHALREQUESTIPI_W7PLUS          g_pfnrtHalRequestIpiW7Plus;
     59extern PFNHALREQUESTIPI_PRE_W7          g_pfnrtHalRequestIpiPreW7;
    5960extern PFNHALSENDSOFTWAREINTERRUPT      g_pfnrtNtHalSendSoftwareInterrupt;
    6061extern PFNRTSENDIPI                     g_pfnrtMpPokeCpuWorker;
    6162extern PFNRTKEIPIGENERICCALL            g_pfnrtKeIpiGenericCall;
     63extern PFNKEINITIALIZEAFFINITYEX        g_pfnrtKeInitializeAffinityEx;
     64extern PFNKEADDPROCESSORAFFINITYEX      g_pfnrtKeAddProcessorAffinityEx;
     65extern PFNKEGETPROCESSORINDEXFROMNUMBER g_pfnrtKeGetProcessorIndexFromNumber;
     66
    6267extern PFNRTRTLGETVERSION               g_pfnrtRtlGetVersion;
    6368#ifndef RT_ARCH_AMD64
     
    7580int rtMpPokeCpuUsingBroadcastIpi(RTCPUID idCpu);
    7681int rtMpPokeCpuUsingHalSendSoftwareInterrupt(RTCPUID idCpu);
     82int rtMpPokeCpuUsingHalReqestIpiW7Plus(RTCPUID idCpu);
     83int rtMpPokeCpuUsingHalReqestIpiPreW7(RTCPUID idCpu);
    7784
    7885RT_C_DECLS_END
  • trunk/src/VBox/Runtime/r0drv/nt/mp-r0drv-nt.cpp

    r53718 r53720  
    454454#ifndef IPRT_TARGET_NT4
    455455
     456/** Callback used by rtMpPokeCpuUsingBroadcastIpi. */
    456457static ULONG_PTR __stdcall rtMpIpiGenericCall(ULONG_PTR Argument)
    457458{
     
    461462
    462463
     464/**
     465 * RTMpPokeCpu worker that uses broadcast IPIs for doing the work.
     466 *
     467 * @returns VINF_SUCCESS
     468 * @param   idCpu           The CPU identifier.
     469 */
    463470int rtMpPokeCpuUsingBroadcastIpi(RTCPUID idCpu)
    464471{
     
    467474}
    468475
    469 # if 0
    470 int rtMpSendIpiVista(RTCPUID idCpu)
    471 {
    472     /* If we start care about Vista, we should investigate a non-broadcast API. */
    473     g_pfnrtKeIpiGenericCall(rtMpIpiGenericCall, 0);
    474 ////    g_pfnrtNtHalRequestIpi(1 << idCpu);
    475     return VINF_SUCCESS;
    476 }
    477 # endif
    478 
    479 
     476
     477/**
     478 * RTMpPokeCpu worker that uses HalSendSoftwareInterrupt to get the job done.
     479 *
     480 * This is only really available on AMD64, at least at the time of writing.
     481 *
     482 * @returns VINF_SUCCESS
     483 * @param   idCpu           The CPU identifier.
     484 */
    480485int rtMpPokeCpuUsingHalSendSoftwareInterrupt(RTCPUID idCpu)
    481486{
     
    484489}
    485490
    486 #endif /* IPRT_TARGET_NT4 */
     491
     492/**
     493 * RTMpPokeCpu worker that uses the Windows 7 and later version of
     494 * HalRequestIpip to get the job done.
     495 *
     496 * @returns VINF_SUCCESS
     497 * @param   idCpu           The CPU identifier.
     498 */
     499int rtMpPokeCpuUsingHalReqestIpiW7Plus(RTCPUID idCpu)
     500{
     501    /*
     502     * I think we'll let idCpu be an NT processor number and not a HAL processor
     503     * index.  KeAddProcessorAffinityEx is for HAL and uses HAL processor
     504     * indexes as input from what I can tell.
     505     */
     506    PROCESSOR_NUMBER ProcNumber = { /*Group=*/ idCpu / 64, /*Number=*/ idCpu % 64, /* Reserved=*/ 0};
     507    KAFFINITY_EX     Target;
     508    g_pfnrtKeInitializeAffinityEx(&Target);
     509    g_pfnrtKeAddProcessorAffinityEx(&Target, g_pfnrtKeGetProcessorIndexFromNumber(&ProcNumber));
     510
     511    g_pfnrtHalRequestIpiW7Plus(0, &Target);
     512    return VINF_SUCCESS;
     513}
     514
     515
     516/**
     517 * RTMpPokeCpu worker that uses the Vista and earlier version of HalRequestIpip
     518 * to get the job done.
     519 *
     520 * @returns VINF_SUCCESS
     521 * @param   idCpu           The CPU identifier.
     522 */
     523int rtMpPokeCpuUsingHalReqestIpiPreW7(RTCPUID idCpu)
     524{
     525    __debugbreak(); /** @todo this code needs testing!!  */
     526    KAFFINITY Target = 1;
     527    Target <<= idCpu;
     528    g_pfnrtHalRequestIpiPreW7(Target);
     529    return VINF_SUCCESS;
     530}
     531
     532#endif /* !IPRT_TARGET_NT4 */
    487533
    488534
  • trunk/src/VBox/Runtime/r0drv/nt/the-nt-kernel.h

    r44528 r53720  
    4141# pragma warning(disable : 4163)
    4242RT_C_DECLS_BEGIN
    43 # include <ntddk.h>
     43# include <iprt/nt/nt.h>
    4444RT_C_DECLS_END
    4545# pragma warning(default : 4163)
     
    5050#else
    5151RT_C_DECLS_BEGIN
    52 # include <ntddk.h>
     52# include <iprt/nt/nt.h>
    5353RT_C_DECLS_END
    5454#endif
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