设备驱动程序IRQL和线程/上下文切换

时间:2010-02-22 13:15:10

标签: windows device-driver

我是Windows设备驱动程序编程的新手。我知道某些操作只能在IRQL PASSIVE_LEVEL执行。例如,Microsoft有一个如何从内核驱动程序写入文件的示例代码:

if (KeGetCurrentIrql() != PASSIVE_LEVEL)
    return STATUS_INVALID_DEVICE_STATE; 

Status = ZwCreateFile(...);

我的问题是:在上面的KeGetCurrentIrql()检查后,是什么阻止了IRQL的引发?假设发生了上下文或线程切换,当IRQL返回到我的驱动程序时会突然变为DISPATCH_LEVEL,这会导致系统崩溃吗?

如果这不可能,那么为什么不检查DriverEntry函数中的IRQL并且一劳永逸地完成它?

3 个答案:

答案 0 :(得分:2)

线程的irql只能自己引发。

因为从上/下驱动程序调用,所以当前运行上下文的irql可能不同。还有一些函数可以提升/降低irql。

几个例子:

IRP_MJ_READ

   NTSTATUS DispatchRead(
    __in struct _DEVICE_OBJECT  *DeviceObject,
    __in struct _IRP  *Irp
    )
  {
     // this will be called at irql == PASSIVE_LEVEL
     ...
     // we have acquire a spinlock
     KSSPIN_LOCK lck;
     KeInititializeSpinLock( &lck );
     KIRQL prev_irql;
     KeAcquireSpinLock( &lck,&prev_irql );

     // KeGetCurrentIrql() == DISPATCH_LEVEL 

     KeReleaseSpinLock( &lck, prev_irql );
     // KeGetCurrentIrql() == PASSIVE_LEVEL 
     ...
  }

(Io-)可以在DISPATCH_LEVEL调用完成例程,因此应该相应地运行。

NTSTATUS CompleteSth(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context)
{
    // KeGetCurrentIrql() >= PASSIVE_LEVEL
}

答案 1 :(得分:2)

IRQL只能通过设置在您的控制下以任何有意义的方式进行更改。有两个“特定于线程”的IRQL - PASSIVE_LEVEL和APC_LEVEL。您可以使用快速互斥体等控制进出这些级别,并且上下文切换到您的线程将始终保持您之前的水平。以上是“特定于处理器”的IRQL。那是DISPATCH_LEVEL或以上。在这些级别中,不能发生上下文切换。你可以使用自旋锁等进入这些级别。 ISR将在您的线程上更高的IRQL上发生,但您无法看到它们。当他们将控制权交还给您时,您的IRQL就会恢复。

答案 2 :(得分:0)

还在PASSIVE_LEVEL调用DriverEntry。

如果您想在PASSIVE_LEVEL完成工作,请使用IoQueueWorkItem

等功能