kernel-stack

Hello,
I have a doubt in Dispatcher objects.

Can I allocate a Dispatcher object in a kernel-stack of a user-mode
thread?

If yes, can I access that object (set/reset/wait) from any arbitrary
thread context or some other non-arbitrary thread context?

I think, while the context switching, the kernel-stack of the thread
will be swapped-out. So in arbitrary thread context, that address of
object refer some other thread’s kernel stack. Please tell me whether my
assumption is correct.

Thanks,
Raja

Your assumption is wrong. Although execution context (i.e. the state of registers) is specific to any given thread that runs in the kernel mode, the kernel address space in itself is the same for all threads. Therefore, kernel address XXXX will always refer to the same memory location, no matter which thread currently runs. Once every thread needs its own stack, kernel-mode ESP is unique for every single thread. What can happen here is that the page with the thread’s X stack gets paged out to the disk (i.e. the address in itself always refers to the same memory location, no matter which thread currently runs, but acessing it in context of any thread, apart from X, causes page fault).The only thing that gets swapped out is thread’s private storage, pointed to by FS register, so that FS:[0] at the time when thread X runs points to the location, different from the one FS:[0] points to at the time when thread Y runs.

According to MSDN, if you allocate the event on the stack, you must specify ‘KernelMode’ as WaitMode parameter wait when calling WaitXXX functions - if you do it this way, the stack containing the event will not be paged out while thread is inactive. However, at this point the only question that may arise is who is going to access an event, allocated on a stack of thread X, apart from thread X itself…

Anton Bassov

From the MSDN article on KeWaitForSingleObject, pasted verbatim:

>
If the WaitMode parameter is UserMode, the kernel stack can be swapped out during the wait. Consequently, a caller must never attempt to pass parameters on the stack when calling KeWaitForSingleObject using the UserMode argument. If you allocate the event on the stack, you must set the WaitMode parameter to KernelMode.
<<

The last sentence I believe answers your question best, but the whole bit provides some context.

Anton-

Fine detail in your post. But I did have a comment on the final statement.

I’m not going to pretend I know all the reasons why, but one good point is that if you specify “KernelMode”, then you can safely assume you can signal the event from a DPC- this seems at least reasonably conceivable as a driver design option.

Bob,

I’m not going to pretend I know all the reasons why, but one good point is that
if you specify “KernelMode”, then you can safely assume you can signal the event
from a DPC

Again, the same story - how can DPC routine access this event if it has been allocated by function X on the stack??? The only one who can get access to it is function X itself (plus all
other function that calls if it passes them a pointer to this event as an argument). Furthermore, event has been allocated on the stack by the function X in context of thread A is different from the one that has been allocated on the stack by the same function X in context of thread A. However, if this function X is DPC routine itself… well, then who is going to wait on this event or check its state???

Therefore, no matter how you look at it, if you want to make any practical use of this event, you have to save a pointer to it somewhere in a global memory location, which simly defeats the purpose of allocating event on the stack, in the first place…

Anton Bassov

Anton,

You can take a pointer to the event. For example this is the classic
approach for a synchronous IoCallDriver, you allocate the event on the
stack, then take a pointer which is passed into the completion routine (or
DPC) and it signals the event. Note: waiting in KernelMode locks the
stack into memory.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

wrote in message news:xxxxx@ntdev…
> Bob,
>
>> I’m not going to pretend I know all the reasons why, but one good point
>> is that
>> if you specify “KernelMode”, then you can safely assume you can signal
>> the event
>> from a DPC
>
> Again, the same story - how can DPC routine access this event if it has
> been allocated by function X on the stack??? The only one who can get
> access to it is function X itself (plus all
> other function that calls if it passes them a pointer to this event as an
> argument). Furthermore, event has been allocated on the stack by the
> function X in context of thread A is different from the one that has been
> allocated on the stack by the same function X in context of thread A.
> However, if this function X is DPC routine itself… well, then who is
> going to wait on this event or check its state???
>
> Therefore, no matter how you look at it, if you want to make any
> practical use of this event, you have to save a pointer to it somewhere
> in a global memory location, which simly defeats the purpose of
> allocating event on the stack, in the first place…
>
> Anton Bassov
>

Well actually you can have the event be passed as the completion context
for an IRP - so it is saved in the IRP itself. The originating thread
allocates the event on the stack, uses the event (or a context object
also stack allocated that contains the event) as the context for IRP
completion. The completion handler, running at DPC level as a
consequence of a DPC routine completing the IRP, then retrieves the
event from the completion context and signals the stack based event. All
of which works just fine assuming that the stack in question is not
paged out (wait must be kernel mode).

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of
xxxxx@hotmail.com
Sent: Thursday, March 01, 2007 9:40 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] kernel-stack

Bob,

I’m not going to pretend I know all the reasons why, but one good
point is that
if you specify “KernelMode”, then you can safely assume you can signal
the event
from a DPC

Again, the same story - how can DPC routine access this event if it has
been allocated by function X on the stack??? The only one who can get
access to it is function X itself (plus all
other function that calls if it passes them a pointer to this event as
an argument). Furthermore, event has been allocated on the stack by the
function X in context of thread A is different from the one that has
been allocated on the stack by the same function X in context of thread
A. However, if this function X is DPC routine itself… well, then
who is going to wait on this event or check its state???

Therefore, no matter how you look at it, if you want to make any
practical use of this event, you have to save a pointer to it somewhere
in a global memory location, which simly defeats the purpose of
allocating event on the stack, in the first place…

Anton Bassov


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Thank you all.

Then I think, I misunderstood the line,

“…Although the stack is mapped into system space, it is considered
part of the thread context of the original calling routine, not part of
the driver itself…”

from a Microsoft’s article,
http://www.microsoft.com/whdc/Driver/tips/KMstack.mspx

Regards,
Raja

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Don Burn
Sent: Thursday, March 01, 2007 8:19 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] kernel-stack

Anton,

You can take a pointer to the event. For example this is the
classic approach for a synchronous IoCallDriver, you allocate the event
on the stack, then take a pointer which is passed into the completion
routine (or
DPC) and it signals the event. Note: waiting in KernelMode locks the
stack into memory.


Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply

wrote in message news:xxxxx@ntdev…
> Bob,
>
>> I’m not going to pretend I know all the reasons why, but one good
>> point is that if you specify “KernelMode”, then you can safely assume

>> you can signal the event from a DPC
>
> Again, the same story - how can DPC routine access this event if it
> has been allocated by function X on the stack??? The only one who can
> get access to it is function X itself (plus all other function that
> calls if it passes them a pointer to this event as an argument).
> Furthermore, event has been allocated on the stack by the function X
> in context of thread A is different from the one that has been
> allocated on the stack by the same function X in context of thread A.
> However, if this function X is DPC routine itself… well, then who

> is going to wait on this event or check its state???
>
> Therefore, no matter how you look at it, if you want to make any
> practical use of this event, you have to save a pointer to it
> somewhere in a global memory location, which simly defeats the purpose

> of allocating event on the stack, in the first place…
>
> Anton Bassov
>


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer

Don,

You can take a pointer to the event. For example this is the classic approach for a synchronous > IoCallDriver

In the end of the day this pointer will still end up in some global memory location…

However, I see what you mean - my statement that “it simly defeats the purpose of
allocating event on the stack, in the first place” does not always hold. If you do things the way you have described, allocating event on the stack is, apparently, the most reasonable approach. In fact, I just wonder how I managed to overlook this scenario - I did it so many times myself…

Anton Bassov

>Can I allocate a Dispatcher object in a kernel-stack of a user-mode

thread?

Yes, but you must provide KernelMode for all waits on it. Waits with UserMode
allow the kernel stack to be outswapped.

I think, while the context switching, the kernel-stack of the thread
will be swapped-out.

Only if the thread is waiting with UserMode.


Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com