What causes a bug check 0xD1 (IRQL_NOT_LESS_OR_EQUAL)

The MSDN document summarizes the cause for the D1 (IRQL_NOT_LESS_OR_EQUAL) pretty well, for people who know how the memory manager in Windows works. It basically says that the cause is: A driver tried to access an address that is pageable (or that is completely invalid) while the IRQL was too high. This bug check is usually caused by drivers that have used improper addresses.

 

 

Detour to the memory manager: in order to understand the D1 bugcheck we have to (briefly) discuss the memory manager subsystem and how it works. The memory manager runs at IRQL 0 (sometimes called PASSIVE) – in other words it runs as a thread with regular priority. If a driver tries to access some piece of memory the processor will throw an "exception" if the memory is not in the RAM (its not paged in). The memory manager will catch this exception, fetch the memory from disk and return the CPU’s attention to the driver that tried to access the memory in first place and now the memory will be paged in. The problem occurs when the driver that is trying to access the memory is running at a higher IRQL, for example IRQL 2 (a.k.a DPC – Deffered Procedure Call).

 

 

This is a problem because when the driver accesses paged out memory at IRQL 2, the memory manager will be invoked to page-in the memory and it runs at IRQL 0. Code at lower IRQL cannot preempt code at a higher IRQL so the memory manager bugchecks the system since no forward progress can be made (deadlock) at this point and the memory manager knows that this is unrecoverable error. Read this white paper [.doc] for a more in-depth explanation of thread scheduling, thread context and driver routines, driver threads, and Interrupt Request Levels (IRQL) in Windows.

 

It is important to remember that the driver can be merely trying to access paged-out memory or it can be trying to access some invalid memory address. For example if a driver is trying to access memory address 0x4E41F00F the system will crash with 0xD1 because  this is not a valid kernel mode address. The kernel address space usually starts at 0xFF… This reference is most likely a bug or memory corruption that eventually manifests itself as a bad pointer. When we try to reference memory at that bad pointer we get a D1 bug check.

 

- Rade Trimceski