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 -