Invalid memory?

I’m getting a bsod in my driver from my XxxEvtDeviceControl. I am trying to write to the registry, and the error occurs on the write. I think this
code is OK for the level, or is it not? Also, the value/name pair does not exist at this point. I was hoping that it would create it if it didn’t.
If that is not correct, how should this be done?
#define TAPPCI_MEMMAPVER_KEY ( L"MemMapVer" )

WDFKEY hKey;
NTSTATUS status;

status = WdfDeviceOpenRegistryKey( devExt->WdfDevice, PLUGPLAY_REGKEY_DEVICE, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &hKey );

if ( NT_SUCCESS(status) )
{

// Get Memory Map Version (MemMapVer)
//
UNICODE_STRING MemMapVerKey;
ULONG MemMapVer = devExt->MemMapVer;
RtlInitUnicodeString( &MemMapVerKey, TAPPCI_MEMMAPVER_KEY );
status = WdfRegistryAssignULong( hKey, &MemMapVerKey, MemMapVer ); // <- blam!

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 8ee487cc, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, bitfield :
bit 0 : value 0 = read operation, 1 = write operation
bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: 82a3cf3b, address which referenced memory

OK, I think that I’m wrong on the IRQL. Windbg says that the IRQL is 2. But why? Why is it elevated? My device property page wants to set some
registry values, which worked fine in XP. Forgot to mention this is Win7 x86. Thanks again.

On Wed, 26 Jan 2011 11:24:53 -0800, Michael Wade wrote:

>I’m getting a bsod in my driver from my XxxEvtDeviceControl. I am trying to write to the registry, and the error occurs on the write. I think this
>code is OK for the level, or is it not? Also, the value/name pair does not exist at this point. I was hoping that it would create it if it didn’t.
>If that is not correct, how should this be done?
>#define TAPPCI_MEMMAPVER_KEY ( L"MemMapVer" )
>
> WDFKEY hKey;
> NTSTATUS status;
>
> status = WdfDeviceOpenRegistryKey( devExt->WdfDevice, PLUGPLAY_REGKEY_DEVICE, KEY_WRITE, WDF_NO_OBJECT_ATTRIBUTES, &hKey );
>
> if ( NT_SUCCESS(status) )
> {
>
> // Get Memory Map Version (MemMapVer)
> //
> UNICODE_STRING MemMapVerKey;
> ULONG MemMapVer = devExt->MemMapVer;
> RtlInitUnicodeString( &MemMapVerKey, TAPPCI_MEMMAPVER_KEY );
> status = WdfRegistryAssignULong( hKey, &MemMapVerKey, MemMapVer ); // <- blam!
>
>IRQL_NOT_LESS_OR_EQUAL (a)
>An attempt was made to access a pageable (or completely invalid) address at an
>interrupt request level (IRQL) that is too high. This is usually
>caused by drivers using improper addresses.
>If a kernel debugger is available get the stack backtrace.
>Arguments:
>Arg1: 8ee487cc, memory referenced
>Arg2: 00000002, IRQL
>Arg3: 00000001, bitfield :
> bit 0 : value 0 = read operation, 1 = write operation
> bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
>Arg4: 82a3cf3b, address which referenced memory
>

What IRQL are you running at?

Peter
OSR

what execution and sync level did you configure your wdfdevice with? are the IOs coming from user mode or another driver?

d

OK… So, that’s a problem.

The simple answer is that the IRQL is elevated because you didn’t specify an ExecutionLevel constraint. If you expected to be called at IRQL PASSIVE_LEVEL, the way you ensure this will happen is by specifying the appropriate constraint. Otherwise, the IRQL at which you’ll be called will be <= DISPATCH_LEVEL.

Peter
OSR

Ah! Thanks Peter!

I’ve looked for some examples in the DDK source, but I’m a bit confused. I have an interrupt in my driver, so don’t I need to have some of the code
being run at elevated IRQL? I think what I should do is set the ExecutionLevel when I do my WdfIoQueueCreate. Does that sound right? Something
like:

WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioCallbacks, WdfIoQueueDispatchSequential);

ioCallbacks.EvtIoDeviceControl = TapEvtDeviceControl;

WDF_OBJECT_ATTRIBUTES_INIT(&objAttributes);

objAttributes.ExecutionLevel = WdfExecutionLevelPassive;

status = WdfIoQueueCreate(device,
&ioCallbacks,
&objAttributes,
NULL); // optional pointer to receive queue handle

Hi Peter,

Do we have a similar API or way to restrict execution level in WDM ?
in KMDF : objAttributes.ExecutionLevel = WdfExecutionLevelPassive;

Thanks,
YS

no, WDM has no such automatic construct. one of the advantages of KMDF. YOu have build your own solution with queueing and work items if you need to defer to passive.

d

So I should do this when I do the WdfIoQueueCreate?
Thanks, Michael

On Thu, 27 Jan 2011 18:53:20 -0500 (EST), xxxxx@Microsoft.com wrote:

no, WDM has no such automatic construct. one of the advantages of KMDF. YOu have build your own solution with queueing and work items if you need to defer to passive.

d

I believe it is set to WdfSynchronizationScopeDevice. Thanks again.

On Wed, 26 Jan 2011 14:33:00 -0500 (EST), xxxxx@Microsoft.com wrote:

what execution and sync level did you configure your wdfdevice with? are the IOs coming from user mode or another driver?

d

Yes, that’s what you want to do if you want the I/O Event Processing Callback routines associated with that QUEUE to always be called at IRQL PASSIVE_LEVEL.

Well, then THAT’s the reason you’re seeing your requests arrive at IRQL DISPATCH_LEVEL… because KMDF will use a spin lock by default to create your sync scope. MORE serialization is NOT necessarily better in a KMDF driver… consider carefully whether you need this serialization at all. For this (and a few other hints, a couple of which are a bit outdated) see: http://www.osronline.com/article.cfm?article=496

So… in short:

a) Consider if you REALLY need the Sync Scope, or whether it’s OK to have your driver’s Event Processing Callbacks running in parallel… if you have a simple device, such as if you’re using sequential dispatching, you usually do not need a sync scope.

b) If you need your driver’s event processing callbacks to be called at IRQL PASSIVE_LEVEL, set an execution level constraint.

Hope that helps,

Peter
OSR

Thanks again Peter. To be honest, I just took that from the OSR example DIO. Is there some reason it is set in that driver?

On Sun, 30 Jan 2011 12:21:11 -0500 (EST), xxxxx@osr.com wrote:

Yes, that’s what you want to do if you want the I/O Event Processing Callback routines associated with that QUEUE to always be called at IRQL PASSIVE_LEVEL.

Well, then THAT’s the reason you’re seeing your requests arrive at IRQL DISPATCH_LEVEL… because KMDF will use a spin lock by default to create your sync scope. MORE serialization is NOT necessarily better in a KMDF driver… consider carefully whether you need this serialization at all. For this (and a few other hints, a couple of which are a bit outdated) see: http://www.osronline.com/article.cfm?article=496

So… in short:

a) Consider if you REALLY need the Sync Scope, or whether it’s OK to have your driver’s Event Processing Callbacks running in parallel… if you have a simple device, such as if you’re using sequential dispatching, you usually do not need a sync scope.

b) If you need your driver’s event processing callbacks to be called at IRQL PASSIVE_LEVEL, set an execution level constraint.

Hope that helps,

Peter
OSR

Well, I’m not looking at that driver at the moment (it’s being 11:30PM local time on a Sunday evening), but we probably didn’t set it without a reason – or we could have screwed-up :slight_smile:

Peter
OSR

Thanks very much Peter! It now runs perfectly!

On Sun, 30 Jan 2011 23:24:45 -0500 (EST), xxxxx@osr.com wrote:

Well, I’m not looking at that driver at the moment (it’s being 11:30PM local time on a Sunday evening), but we probably didn’t set it without a reason – or we could have screwed-up :slight_smile:

Peter
OSR