Dear Folks,
This is what I do:
pKeVirtAdd = MmAllocateContiguousMemorySpecifyCache();
pMDL = IoAllocateMdl(pKeVirtAdd,… );
MmBuildMdlForNonPagedPool(pMDL);
pUserVirtAdd = MmMapLockedPagesSpecifyCache(pMDL, UserMode,…)
Then when the work is done in the DriverClose() routine at IRQL 0 I do:
if (MmIsAddressValid(pKeVirtAdd )) {
pMDL = IoAllocateMdl();
MmBuildMdlForNonPagedPool(pMDL);
MmUnmapLockedPages(pKeVirtAdd, pMDL);
IoFreeMdl(pMDL);
MmFreeContiguousMemory(pKeVirtAdd);
}
The moment I do MmUnmapLockedPages() and before I execute IoFreeMdl(), pKeVirAdd becomes invalid. A dd shows ??? If I attempt to free it further the system bugchecks which is expected.
The question is why does Unmapping the address from the MDL free the memory? WDK documentation does not talk about that?
Should I be unmapping pUserVirtAdd instead of pKeVirAdd? Then freeing pKeVirAdd would be logical … Any light on this please …
thanks
ananda
I just don’t know what to say here…
Where is the logic behind your code???
The question is why does Unmapping the address from the MDL free the memory?
And what else would you expect???
WDK documentation does not talk about that?
Does not it??? In fact, even if it does not, it is so plainly obvious that it is not even worth mentioning…
Should I be unmapping pUserVirtAdd instead of pKeVirAdd? Then freeing pKeVirAdd
would be logical …
Indeed, it would be a logical step - normally unload, free, unmap,etc are the reverse of load, allocate, map, etc, so that passing unload, free, unmap,etc a pointer that a previous call to load, allocate, map, etc has returned is quite logical step. It would be a good idea for you to apply this logic to any program you write…
Another logical step would be removing IoAllocateMDL() from DriverClose() - it does not really logically belong there, don’t you think???
Anton Bassov
Your error is obvious - you call MmUnmapLockedPages for the Mdl initialized by the MmBuildMdlForNonPagedPool, as a result MmUnmapLockedPages frees the system PTEs which map the buffer returned by the MmAllocateContiguousMemorySpecifyCache . You must not call MmUnmapLockedPages for an MDL initialized by MmBuildMdlForNonPagedPool.
Slava Imameyev , xxxxx@hotmail.com
> Your error is obvious
The only thing that is not so obvious is the OP’s logic (if any) behind the whole thing…
You must not call MmUnmapLockedPages for an MDL initialized by MmBuildMdlForNonPagedPool.
As long as you want to access the target MDL from the system address space, you must not call MmMapLockedPagesSpecifyCache() for an MDL initialized by MmBuildMdlForNonPagedPool(), in the first place - the virtual address MDL corresponds to is already mapped to non-paged pool at the time a call to MmBuildMdlForNonPagedPool() is made, so that MmBuildMdlForNonPagedPool() just updates MDL to make it describe underlying physical pages. Once you don’t have to call MmMapLockedPagesSpecifyCache(), you don’t have to call MmUnmapLockedPages() either.
However, in addition to mapping MDL to the kernel address space, the OP maps it to the user address space as well, so that pages that MDL describes can be accessed from 2 different virtual addresses , i.e. from (MDL)->MappedSystemVa and from the one in the user address space that MmMapLockedPagesSpecifyCache() has returned. In such case the OP has to call MmUnmapLockedPages() in order to unmap MDL from the user address space and to leave (MDL)->MappedSystemVa alone. Furthermore, once he unmaps the address from the user address space, he has to make a call MmUnmapLockedPages() in context of the same process that called MmMapLockedPagesSpecifyCache(), and, judging from the OP’s description, it does not seem to be the case here…
To summarize, the OP’s code has a good chance to win " The most stupid code of the year" contest - the fact of calling IoAllocateMDL() from DriverClose() alone is worth a prize…
Anton Bassov
> To summarize, the OP’s code has a good chance to win " The most stupid
code of the year" contest
Anton, You are too aggressive. Do you know that Ethics nad Interpesonal
Communication are compulsory for any graduate level CS course?
–
Slava Imameyev, xxxxx@hotmail.com
wrote in message news:xxxxx@ntdev…
>> Your error is obvious
>
> The only thing that is not so obvious is the OP’s logic (if any) behind
> the whole thing…
>
>> You must not call MmUnmapLockedPages for an MDL initialized by
>> MmBuildMdlForNonPagedPool.
>
> As long as you want to access the target MDL from the system address
> space, you must not call MmMapLockedPagesSpecifyCache() for an MDL
> initialized by MmBuildMdlForNonPagedPool(), in the first place - the
> virtual address MDL corresponds to is already mapped to non-paged pool at
> the time a call to MmBuildMdlForNonPagedPool() is made, so that
> MmBuildMdlForNonPagedPool() just updates MDL to make it describe
> underlying physical pages. Once you don’t have to call
> MmMapLockedPagesSpecifyCache(), you don’t have to call
> MmUnmapLockedPages() either.
>
> However, in addition to mapping MDL to the kernel address space, the OP
> maps it to the user address space as well, so that pages that MDL
> describes can be accessed from 2 different virtual addresses , i.e. from
> (MDL)->MappedSystemVa and from the one in the user address space that
> MmMapLockedPagesSpecifyCache() has returned. In such case the OP has to
> call MmUnmapLockedPages() in order to unmap MDL from the user address
> space and to leave (MDL)->MappedSystemVa alone. Furthermore, once he
> unmaps the address from the user address space, he has to make a call
> MmUnmapLockedPages() in context of the same process that called
> MmMapLockedPagesSpecifyCache(), and, judging from the OP’s description, it
> does not seem to be the case here…
>
>
> To summarize, the OP’s code has a good chance to win " The most stupid
> code of the year" contest - the fact of calling IoAllocateMDL() from
> DriverClose() alone is worth a prize…
>
> Anton Bassov
>
>
Slava,
Anton, You are too aggressive. Do you know that Ethics nad Interpesonal
Communication are compulsory for any graduate level CS course?
I see what you mean, but I haven’t seen a code that is so illogical for quite a while, so that I am just
kind of shocked (please note that I am speaking not about the OP but about the *code* that he wrote). I can understand the discrepancy between mapping and unmapping MDL; I can understand
the mistake with process context; but when all the above gets combined with IoAllocateMdl() in DriverClose() (and we are speaking about just 10 (!!!) lines of code here), I just cannot refrain myself from being a bit ironical - what the OP does here it is pretty much the same things as making 4 spelling mistakes in 3-letter word…
Anton Bassov
> pKeVirtAdd = MmAllocateContiguousMemorySpecifyCache();
Why not just page-aligned ExAllocatePoolWithTag?
The only valid need in contiguous memory is DMA, so,
MmAllocateContiguousMemorySpecifyCache is intended for use in DMA adapter
object implementations to implement ->AllocateCommonBuffer, and not for general
use.
pMDL = IoAllocateMdl(pKeVirtAdd,… );
MmBuildMdlForNonPagedPool(pMDL);
pUserVirtAdd = MmMapLockedPagesSpecifyCache(pMDL, UserMode,…)
Not the best way, but should work. Better way is to allocate in user mode and
map in kernel mode.
if (MmIsAddressValid(pKeVirtAdd )) {
Why this check?
It is you who assigns to pKeVirtAdd, not some beings from outer space
so,
you know that ( pKeVirtAdd != NULL ) is enough, since you will never assign
wrong value there.
pMDL = IoAllocateMdl();
MmBuildMdlForNonPagedPool(pMDL);
MmUnmapLockedPages(pKeVirtAdd, pMDL);
Why second MDL? Please keep the first MDL till here, and just call
MmUnmapLockedPages on it.
IoFreeMdl(pMDL);
Yes, destroy the first MDL.
MmFreeContiguousMemory(pKeVirtAdd);
ExFreePool instead.
–
Maxim Shatskih, Windows DDK MVP
StorageCraft Corporation
xxxxx@storagecraft.com
http://www.storagecraft.com