DPC execution time exceeds system limit

carbon

  • main code :
    PSTOP_PROCESSORS_DATA stopData = stop_processors();
    if (stopData == nullptr) {
        return false;
    }

    // dosomething
    // ...

    resume_processors(stopData); // sometimes will be crash at here

I just want to suspend the processor. Is there a better safe and stable way? thanks.

windbg output:

1: kd> !running -it

System Processors:  (0000000000000003)
  Idle Processors:  (0000000000000002)

       Prcbs             Current         (pri) Next            (pri) Idle
  0    fffff8051f1ca180  ffffd90feae67500 (12)                       fffff80524591400  ................

 # Child-SP          RetAddr           Call Site
00 fffffa8f`1198e6c0 fffff805`294271ae main!wait_for_equality+0x2c [E:\src\hook.cpp @ 377] 
01 fffffa8f`1198e6e0 fffff805`29427582 main!resume_processors+0x3e [E:\src\hook.cpp @ 441] 
02 fffffa8f`1198e710 fffff805`2942149d main!build_status+0x122 [E:\src\hook.cpp @ 1022] 
03 fffffa8f`1198e780 fffff805`294212db main!hook_now_internal+0x45 [E:\src\HookUtils.cpp @ 12] 
04 fffffa8f`1198e7c0 fffff805`29424328 main!HookUtils::hook_now+0xc7 [E:\src\HookUtils.cpp @ 50] 
05 fffffa8f`1198e820 fffff805`294215a4 main!NtQueryFunctions::hook_nt+0x3ac [E:\src\NtQueryFunctions.cpp @ 401] 
06 fffffa8f`1198e860 fffff805`294211fe main!HookEntry::init+0x2c [E:\src\HookEntry.cpp @ 20] 
07 fffffa8f`1198e8d0 fffff805`29496020 main!DriverEntry+0x7e [E:\src\main.cpp @ 58] 
08 fffffa8f`1198e920 fffff805`247107c6 main!GsDriverEntry+0x20 [minkernel\tools\gs_support\kmode\gs_support.c @ 117] 
09 fffffa8f`1198e950 fffff805`247101fe nt!IopLoadDriver+0x4c2
0a fffffa8f`1198eb30 fffff805`240bd095 nt!IopLoadUnloadDriver+0x4e
0b fffffa8f`1198eb70 fffff805`2412a7a5 nt!ExpWorkerThread+0x105
0c fffffa8f`1198ec10 fffff805`241c8b2a nt!PspSystemThreadStartup+0x55
0d fffffa8f`1198ec60 00000000`00000000 nt!KiStartSystemThread+0x2a

  1    ffffc300eb4a7180  ffffc300eb4b80c0 ( 0)                       ffffc300eb4b80c0  ................

 # Child-SP          RetAddr           Call Site
00 ffffc300`eb4ffb10 fffff805`2401f897 nt!KeAccumulateTicks+0x1cbfa0
01 ffffc300`eb4ffb70 fffff805`23f601e1 nt!KeClockInterruptNotify+0xc07
02 ffffc300`eb4fff30 fffff805`24002a25 hal!HalpTimerClockIpiRoutine+0x21
03 ffffc300`eb4fff60 fffff805`241c2f7a nt!KiCallInterruptServiceRoutine+0xa5
04 ffffc300`eb4fffb0 fffff805`241c34e7 nt!KiInterruptSubDispatchNoLockNoEtw+0xfa
05 fffffa8f`11629700 fffff805`294273ec nt!KiInterruptDispatchNoLockNoEtw+0x37
06 fffffa8f`11629890 fffff805`2942721d main!wait_for_equality+0x2c [E:\src\hook.cpp @ 377] 
07 fffffa8f`116298b0 fffff805`2406ae95 main!stall_dpc_routine+0x3d [E:\src\hook.cpp @ 393] 
08 fffffa8f`116298f0 fffff805`2406a4ef nt!KiExecuteAllDpcs+0x305
09 fffffa8f`11629a30 fffff805`241c5024 nt!KiRetireDpcList+0x1ef
0a fffffa8f`11629c60 00000000`00000000 nt!KiIdleLoop+0x84

I just want to suspend the processor. Is there a better safe and stable way? thanks.

You should tell us what problem you are trying to solve, because the code you’ve posted there is total bullshit. A DPC is not supposed to stall, because it affects the performance of the entire system. That’s why the bug check is in there to begin with.

If you’re just playing around, perhaps you should try Linux instead. If you actually have a legitimate problem to solve, then there is obviously a better way. Tell us about the overall goal.

1 Like

@Tim_Roberts
Thank you for pointing out, as in the stack context provided above, I need to hook certain functions, but in order to prevent the processor from executing where I am at the hook, I need to pause it and then resume after I install the hook., It only occasionally triggers this error.

    PSTOP_PROCESSORS_DATA stopData = stop_processors();
    if (stopData == nullptr) {
        return false;
    }

    // dosomething 
   /* similar to user mode hooks, first suspend all threads and then check the eip/rip position to determine whether to hook, but I think the driver mode should be safer to suspend the processor
   */
    hook_fun()

    resume_processors(stopData); // sometimes will be crash at here

You’re using brute force to solve a problem that can be solved much more elegantly. You’re going to be inserting a jmp instruction, right? A jmp instruction is less than 8 bytes. If you use InterlockedExchange64, you can swap 8 bytes atomically. Atomically, in this case, means "all or nothing’. Any given processor will either execute all of the old code, or all of the new code. You don’t have to stop any processors at all.

Kids today. No imagination.

I use absolute jump (relative jump does not work in a space greater than 2gb)

ffffbc80`6a6790f0 ff2500000000    jmp     qword ptr [ffffbc80`6a6790f6]
ffffbc80`6a6790f6 90              nop
ffffbc80`6a6790f7 38e1            cmp     cl,ah
ffffbc80`6a6790f9 55              push    rbp
ffffbc80`6a6790fa 06              ???
ffffbc80`6a6790fb f8              clc
ffffbc80`6a6790fc ff              ???
ffffbc80`6a6790fd ff0e            dec     dword ptr [rsi]

Atomic exchange can only exchange 8 bytes at a time, so there may be security risks

Well this is still bullshit code, but you need to implement a processor
corral. You could use the existing IPC mechanism’s support, but it is
closed off. So instead you need to schedule dpcs on each cpu and have them
rendez-vous with each other and elect one of them to perform the horrible
nonsense you think you need to do.

Good luck.

Also if your implementation sucks you will still have to deal with dpc
timeouts.

Mark Roddy