VirtualBox

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


Ignore:
Timestamp:
May 24, 2009 4:21:24 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
47671
Message:

IPRT/r0drv-nt: Cleaning up the preemption hacks; XP SP2 is done.

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

Legend:

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

    r9603 r19969  
    3333*******************************************************************************/
    3434#include "the-nt-kernel.h"
     35#include <iprt/assert.h>
    3536#include <iprt/err.h>
    36 #include <iprt/assert.h>
    3737#include <iprt/mp.h>
     38#include <iprt/string.h>
    3839#include "internal/initterm.h"
    3940#include "internal-r0drv-nt.h"
     
    5051 * and update this variable as CPUs comes online. (The code is done already.)
    5152 */
    52 RTCPUSET g_rtMpNtCpuSet;
     53RTCPUSET                    g_rtMpNtCpuSet;
    5354
    5455/** ExSetTimerResolution, introduced in W2K. */
    55 PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
     56PFNMYEXSETTIMERRESOLUTION   g_pfnrtNtExSetTimerResolution;
    5657/** KeFlushQueuedDpcs, introduced in XP. */
    57 PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
     58PFNMYKEFLUSHQUEUEDDPCS      g_pfnrtNtKeFlushQueuedDpcs;
     59
     60/** Offset of the _KPRCB::QuantumEnd field. 0 if not found. */
     61uint32_t                    g_offrtNtPbQuantumEnd;
     62/** Size of the _KPRCB::QuantumEnd field. 0 if not found. */
     63uint32_t                    g_cbrtNtPbQuantumEnd;
     64/** Offset of the _KPRCB::DpcQueueDepth field. 0 if not found. */
     65uint32_t                    g_offrtNtPbDpcQueueDepth;
     66
    5867
    5968
     
    7786    g_pfnrtNtKeFlushQueuedDpcs = (PFNMYKEFLUSHQUEUEDDPCS)MmGetSystemRoutineAddress(&RoutineName);
    7887
     88    /*
     89     * Get some info that might come in handy below.
     90     */
     91    ULONG MajorVersion = 0;
     92    ULONG MinorVersion = 0;
     93    ULONG BuildNumber  = 0;
     94    PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);
     95
     96    KIRQL OldIrql;
     97    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* make sure we stay on the same cpu */
     98
     99    union
     100    {
     101        uint32_t auRegs[4];
     102        char szVendor[4*3+1];
     103    } u;
     104    ASMCpuId(0, &u.auRegs[3], &u.auRegs[0], &u.auRegs[2], &u.auRegs[1]);
     105    u.szVendor[4*3] = '\0';
     106
     107    /*
     108     * Try find _KPRCB::QuantumEnd and possibly also _KPRCB::DpcQueueDepth.
     109     */
     110    __try
     111    {
     112        /* HACK ALERT! The offsets are from poking around in windbg. */
     113#if defined(RT_ARCH_X86)
     114        PKPCR    pPcr   = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
     115        uint8_t *pbPrcb = (uint8_t *)pPcr->Prcb;
     116
     117        if (    BuildNumber == 2600                             /* XP SP2 */
     118            &&  !memcmp(&pbPrcb[0x900], &u.szVendor[0], 4*3))
     119        {
     120            g_offrtNtPbQuantumEnd    = 0x88c;
     121            g_cbrtNtPbQuantumEnd     = 4;
     122            g_offrtNtPbDpcQueueDepth = 0x870;
     123        }
     124        /** @todo more */
     125        //pbQuantumEnd = (uint8_t volatile *)pPcr->Prcb + 0x1a41;
     126
     127#elif defined(RT_ARCH_AMD64)
     128        PKPCR    pPcr   = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
     129        uint8_t *pbPrcb = (uint8_t *)pPcr->CurrentPrcb;
     130        /** @todo proper detection! */
     131        if (pbPrcb[0x3375] <= 1)
     132        {
     133            g_offrtNtPbQuantumEnd    = 0x3375;
     134            g_cbrtNtPbQuantumEnd     = 1;
     135            g_offrtNtPbDpcQueueDepth = 0;
     136        }
     137
     138#else
     139# error "port me"
     140#endif
     141    }
     142    __except(EXCEPTION_EXECUTE_HANDLER)
     143    {
     144        g_offrtNtPbQuantumEnd    = 0;
     145        g_cbrtNtPbQuantumEnd     = 0;
     146        g_offrtNtPbDpcQueueDepth = 0;
     147    }
     148
     149    KeLowerIrql(OldIrql);
     150
     151#ifndef IN_GUEST /** @todo fix above for all Nt versions. */
     152    if (!g_offrtNtPbQuantumEnd && !g_offrtNtPbDpcQueueDepth)
     153        DbgPrint("IPRT: Neither _KPRCB::QuantumEnd nor _KPRCB::DpcQueueDepth was not found!\n");
     154#endif
     155
    79156    return VINF_SUCCESS;
    80157}
  • trunk/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h

    r9582 r19969  
    4646*   Global Variables                                                           *
    4747*******************************************************************************/
    48 extern RTCPUSET g_rtMpNtCpuSet;
    49 extern PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
    50 extern PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
     48extern RTCPUSET                     g_rtMpNtCpuSet;
     49extern PFNMYEXSETTIMERRESOLUTION    g_pfnrtNtExSetTimerResolution;
     50extern PFNMYKEFLUSHQUEUEDDPCS       g_pfnrtNtKeFlushQueuedDpcs;
     51extern uint32_t                     g_offrtNtPbQuantumEnd;
     52extern uint32_t                     g_cbrtNtPbQuantumEnd;
     53extern uint32_t                     g_offrtNtPbDpcQueueDepth;
    5154
    5255
  • trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp

    r19915 r19969  
    3838#include <iprt/assert.h>
    3939#include <iprt/asm.h>
     40
     41#include "internal-r0drv-nt.h"
    4042
    4143__BEGIN_DECLS
     
    9294    Assert(hThread == NIL_RTTHREAD);
    9395
    94     uint8_t volatile *pbQuantumEnd;
    95     RTCCUINTREG       fSavedFlags  = ASMIntDisableFlags();
     96    /*
     97     * Read the globals and check if they are useful.
     98     */
     99    uint32_t const offQuantumEnd     = g_offrtNtPbQuantumEnd;
     100    uint32_t const cbQuantumEnd      = g_cbrtNtPbQuantumEnd;
     101    uint32_t const offDpcQueueDepth  = g_offrtNtPbDpcQueueDepth;
     102    if (!offQuantumEnd && !cbQuantumEnd && !offDpcQueueDepth)
     103        return false;
     104    Assert((offQuantumEnd && cbQuantumEnd) || (!offQuantumEnd && !cbQuantumEnd));
    96105
    97 #if   defined(RT_ARCH_X86)
    98     /* HACK ALERT! The offset is from ks386.inc. */
    99     PKPCR pPcr = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
    100     pbQuantumEnd = (uint8_t volatile *)pPcr->Prcb + 0x1a41;
     106    /*
     107     * Disable interrupts so we won't be messed around.
     108     */
     109    bool            fPending;
     110    RTCCUINTREG     fSavedFlags  = ASMIntDisableFlags();
     111
     112#ifdef RT_ARCH_X86
     113    PKPCR       pPcr   = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
     114    uint8_t    *pbPrcb = (uint8_t *)pPcr->Prcb;
    101115
    102116#elif defined(RT_ARCH_AMD64)
    103117    /* HACK ALERT! The offset is from windbg/vista64. */
    104     PKPCR pPcr = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
    105     pbQuantumEnd = (uint8_t volatile *)pPcr->CurrentPrcb + 0x3375;
     118    PKPCR       pPcr  = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
     119    uint8_t    *pbPrcb = (uint8_t *)pPcr->CurrentPrcb;
    106120
    107121#else
    108122# error "port me"
    109123#endif
    110     uint8_t QuantumEnd = *pbQuantumEnd;
     124
     125    /* Check QuantumEnd. */
     126    if (cbQuantumEnd == 1)
     127    {
     128        uint8_t volatile *pbQuantumEnd = (uint8_t volatile *)(pbPrcb + offQuantumEnd);
     129        fPending = *pbQuantumEnd == TRUE;
     130    }
     131    else if (cbQuantumEnd == sizeof(uint32_t))
     132    {
     133        uint32_t volatile *pu32QuantumEnd = (uint32_t volatile *)(pbPrcb + offQuantumEnd);
     134        fPending = *pu32QuantumEnd != 0;
     135    }
     136
     137    /* Check DpcQueueDepth. */
     138    if (    !fPending
     139        &&  offDpcQueueDepth)
     140    {
     141        uint32_t volatile *pu32DpcQueueDepth = (uint32_t volatile *)(pbPrcb + offDpcQueueDepth);
     142        fPending = *pu32DpcQueueDepth > 0;
     143    }
     144
    111145    ASMSetFlags(fSavedFlags);
    112 
    113     AssertMsg(QuantumEnd == FALSE || QuantumEnd == TRUE, ("%x\n", QuantumEnd));
    114     return QuantumEnd == TRUE;
     146    return fPending;
    115147}
    116148
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