I’m working on an XP ‘development’ driver as a means of performing HW validation on a new HW graphics device. While I’m not focused on created production quality drivers, I do care that I’m not ‘hacking’ a solution.
The graphics device is part of a UMA style SOC and has no dedicated graphics memory, rather the device addresses the same system RAM as the CPU. The device has a 4Gb address range with a PT/PD based MMU so the device is not dependent on physically contiguous memory.
There is a kernel driver to manage the device as well as the memory to be addressed by it. More specifically, I need to be able to allocate nonpaged, uncached memory in kernelmode which can then be arbitrarily mapped to N usermode process address spaces. I know the nonpagedpool is a scarce resource in XP-32bit and would ideally prefer to allocate from the pagedpool, probe/locking the pages first. Unfortunately, I haven’t had any success changing the cachetype to uncached (MmMapLockedPagesSpecifyCache) so opted to explicitly allocate noncached, nonpaged memory via the DDI, MmAllocateNonCachedMemory. Here’s the sequence:
pvLinAddrKM = MmAllocateNonCachedMemory(uiSize)
psKernelMDL = IoAllocateMdl(pvLinAddrKM, ui32Size, IMG_FALSE, IMG_FALSE, IMG_NULL)
MmBuildMdlForNonPagedPool(psKernelMDL)
The physical pages backing the MDL are programmed into the device’s MMU PTEs and the device’s driver may access the memory via the uncached CPU virtual addresss.
Subsequently, one or more usermode client processes will request a mapping to the original kernel MDL allocation. I’ve assumed I need to create a new MDL for each process mapping of the original kernel MDL. Here’s the sequence:
psProcessMDL = IoAllocateMdl(pvLinAddrKM, ui32Size, IMG_FALSE, IMG_FALSE, IMG_NULL)
MmBuildMdlForNonPagedPool(psProcessMDL)
__try
{
pvLinAddrUM = MmMapLockedPagesSpecifyCache(psMapping->psMDL, UserMode, MmNonCached, NULL, FALSE, NormalPagePriority)
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
goto cleanup_mdl;
}
I’m pretty sure I don’t need to probe/lock pages as the allocation was from the nonpagedpool. From what I’ve read I think I need the call to MmBuildMdlForNonPagedPool as it’s a new MDL for each process and I need to call MmMapLockedPagesSpecifyCache() to ensure the mapping is uncached.
I have two questions:
- is it possible to achieve what I’ve described in XP using MDLs to create 1 Kernel mapping and N concurrent usermode MDL mappings of the same underlying physical memory (where the memory is allocated from the paged or nonpagepools)?
- If the answer to 1) is yes, is the code I’ve provided look OK and, if not, could anyone provide guidance towards a sensible solution?
regards
Dave