Comments in italics are mine and express my own views, thoughts and opinions
Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:
message-based interrupts and IoConnectInterruptEx (p. 106) - if we look at API (http://msdn.microsoft.com/en-us/library/aa490464.aspx) and compare it with IoConnectInterrupt (http://msdn.microsoft.com/en-us/library/ms801597.aspx) we would see that it now accepts only one structure parameter and it is a union of various structures including FULLY_SPECIFIEDÂ that contains all previous parameters from IoConnectInterrupt
DPC objects (p. 107)
1: kd> dt _KDPC
nt!_KDPC
  +0x000 Type            : UChar
  +0x001 Importance      : UChar
  +0x002 Number          : Uint2B
  +0x008 DpcListEntry    : _LIST_ENTRY
  +0x018 DeferredRoutine : Ptr64    void
  +0x020 DeferredContext : Ptr64 Void
  +0x028 SystemArgument1 : Ptr64 Void
  +0x030 SystemArgument2 : Ptr64 Void
  +0x038 DpcData         : Ptr64 Void
Kernel processes DPCs when IRQL is about to drop below DPC level (p. 107)
Idle thread also processes DPCs (p. 108)Â - here are some code fragments:
nt!KiIdleLoop+0x1b:
80545d57 mov    cl,2
80545d59 call   dword ptr [nt!_imp_HalClearSoftwareInterrupt (804d80b4)]
80545d5f call   nt!KiRetireDpcList (80545e1e)
nt!KiIdleLoop+0x31:
80545d6d mov    ecx,1Ch
80545d72 call   dword ptr [nt!_imp_KfRaiseIrql (804d802c)]
80545d78 sti
80545d79 lea    ecx,[ebx+540h]
80545d7f call   nt!KeAcquireQueuedSpinLockAtDpcLevel (80540a90)
80545d84 mov    esi,dword ptr [ebx+128h]
80545d8a mov    edi,dword ptr [ebx+124h]
80545d90 cmp    byte ptr [esi+50h],0
80545d94 jne    nt!KiIdleLoop+0×97 (80545dd3)
nt!KiIdleLoop+0x9d:
80545dd9 call   nt!KeReleaseQueuedSpinLockFromDpcLevel (80540abc)
80545dde mov    ecx,2
80545de3 call   dword ptr [nt!_imp_KfLowerIrql (804d8030)]
80545de9 lea    ebp,[ebx+980h]
80545def jmp    nt!KiIdleLoop+0×10 (80545d4c)
on x64 it looks like IRQL management is done via CR8 Task Priority Register:
1: kd> uf KfRaiseIrql
nt!KfRaiseIrql:
fffff800`018b00e0 mov    rax,cr8
fffff800`018b00e4 movzx  ecx,cl
fffff800`018b00e7 mov    cr8,rcx
fffff800`018b00eb ret
1: kd> uf KeLowerIrql
nt!KeLowerIrql:
fffff800`018b0110 movzx  eax,cl
fffff800`018b0113 mov    cr8,rax
fffff800`018b0117 ret
1: kd> uf KiIdleLoop
[...]
nt!KiIdleLoop+0x5a:
fffff800`01871e6a mov    rcx,rbx
fffff800`01871e6d call   nt!KiRetireDpcList (fffff800`01870bc0)
[...]
Threaded DPC - passive IRQL on a real-time thread (p. 110)
APC interrupts and objects (p. 112)
1: kd> dt _KAPC
nt!_KAPC
  +0x000 Type            : UChar
  +0x001 SpareByte0      : UChar
  +0x002 Size            : UChar
  +0x003 SpareByte1      : UChar
  +0x004 SpareLong0      : Uint4B
  +0x008 Thread          : Ptr64 _KTHREAD
  +0x010 ApcListEntry    : _LIST_ENTRY
  +0x020 KernelRoutine   : Ptr64    void
  +0x028 RundownRoutine  : Ptr64    void
  +0x030 NormalRoutine   : Ptr64    void
  +0x038 NormalContext   : Ptr64 Void
  +0x040 SystemArgument1 : Ptr64 Void
  +0x048 SystemArgument2 : Ptr64 Void
  +0x050 ApcStateIndex   : Char
  +0x051 ApcMode         : Char
  +0x052 Inserted        : UChar
DPC queue is system-wide, APC queue is thread-specific (p. 112)
kernel APC (special vs. normal (called by associated special)) and user APC (execute at passive level) (pp. 112 - 113)
Guarded region (special and normal APC) vs. Critical region (normal APC) (p. 112)
POSIX signals are emulated by APC (p. 112)
Thread suspension, termination and APC (p. 112) - see thread stack with ExitThread / PsExitSpecialApc in wait chain pattern case study: http://www.dumpanalysis.org/blog/index.php/2007/12/14/crash-dump-analysis-patterns-part-42a/
APC delivery reorders wait queues (p. 114)
- Dmitry Vostokov @ SoftwareGeneralist.com -