MmProbeAndLockPages does not seem to lock

I have encountered a problem with MmProbeAndLockPages() where when
memory size being locked down is significant portion of total system memory,
that memory does not appear to be locked down.

Memory size being locked down is 180 to 200MB out of total of 256MB.
Code fragment follows: Note that memory lockdown is being done within the
context of calling process thread. I/o is done via IOCTL where a virtual
memory address and size is being supplied from win32 space. Ioctl is
designed to return array of physical 4k page addresses corresponding
to locked down virtual address range.


ULONG sectionlength = SectionInfo->fullLength;

// want physical page addresses so…
// allocate physical pages addresses array
SectionInfo->pPageAddresses = ExAllocatePool( PagedPool, SectionInfo->fullLength / PAGE_SIZE );

// create MDL
pMdl = ExAllocatePool( NonPagedPool, MmSizeOfMdl( SectionInfo->mapAddress, sectionlength ) );

if( pMdl != NULL )
{

MmCreateMdl(
pMdl,
SectionInfo->mapAddress,
sectionlength );

// lock pages by mdl
__try
{
MmProbeAndLockPages(
pMdl,
KernelMode, //UserMode, // seems to make no difference
IoModifyAccess );

ProbeKdPrint((“Probe.SYS: MmProbeAndLockPages() - locked, about to get phys addresses\n”));

if( SectionInfo->pPageAddresses )
{
// get physical addresses for this section
ULONG Index;
PVOID virtualAddress = SectionInfo->mapAddress;

for( Index = 0; Index < (sectionlength/PAGE_SIZE); Index++ )
{
char buff[100];

if( MmIsAddressValid((PUCHAR)virtualAddress + Index * PAGE_SIZE) )
{
SectionInfo->pPageAddresses[Index] = MmGetPhysicalAddress((PUCHAR)virtualAddress + Index * PAGE_SIZE).LowPart;
//sprintf(buff,“Probe.SYS: Entry = %04d, VA = %08x, PHYS = %08x\n”,
// Index, (PUCHAR)SectionInfo->mapAddress + Index * PAGE_SIZE,SectionInfo->pPageAddresses[Index]);
//ProbeKdPrint((buff));
}
else
{
// #### address not valid
//SectionInfo->pPageAddresses[Index] = 0;
// MmGetPhysicalAddress() returns 0 as well…
SectionInfo->pPageAddresses[Index] = MmGetPhysicalAddress((PUCHAR)virtualAddress + Index * PAGE_SIZE).LowPart;

sprintf(buff,“Probe.SYS: Entry = %04d, VA = %08x, PHYS = %08x\n”,
Index, (PUCHAR)virtualAddress + Index * PAGE_SIZE,SectionInfo->pPageAddresses[Index]);
ProbeKdPrint((buff));
}
}

}

// good result, need MDL for unlocking
SectionInfo->SectionMdl = pMdl;
return 1;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
ProbeKdPrint((“Probe.SYS: Exception on MmProbeAndLockPages()\n”));
IoFreeMdl( pMdl );
}

}
// bad result here, must cleanup


What happens is that in all cases the lockdown appears to work but
attempts to get physical memory addresses for 4k pages does not work
with as few as 1 to as many as 100’s 4k page address entries returning 0.

I do not get exceptions on actual MmProbeAndLockPages(), possibly as
I have enough PTEs specified in registry.

Another serious symptom is that on occasions the system will BSOD with
paging error, affecting the test app but not exclusively. Sometimes it is
developer studio that is process that gets paging error.
Stack shows file system drivers, never the Probe.sys driver under testing.
Using SoftIce to continue soon results in system freezing.

In cases where IOCTL to lockdown fails to get physical addresses it
is possible to rerun test app and IOCTL succeeds. This behavior appears
as a consequence of system having squeezed most other processes off to
paging file in first failed attempt and second run has a greater chance
of success.

Has anyone got any ideas on this?

Before anyone makes comments about locking down so much memory I will
say that memory must be locked down for subsequent i/o operations that
must be from this locked down pool and i/o operations cannot be delayed
or deferred once started.

Ned Kacavenda - Software Development
Colorbus Pty Ltd
1044 Dandenong Road Carnegie Victoria 3163 Australia
Direct +61 3 8574 8023, Main +61 3 8574 8000
Email: xxxxx@colorbus.com.au
web : http://www.colorbus.com http:</http:>