3
votes

I'm writing a kernel mode driver in Windows 10 (64-bit), whose main purpose is to read from a DMA, and I was wondering if instead of copying blocks of memory from the kernel space to buffers allocated in the user space, I could somehow expose an address to the user space (of course not the physical address), and save on the memory copy operation.

Perhaps something like this:

  1. Allocating a block of continuous physical memory (and mapping the physical address to a virtual address in the kernel space).

  2. Mapping the virtual address in the kernel space to a virtual address in the user space.

By the way, since there's only one kernel space, and as many user spaces as there are processes running in the system (is that correct?), I would have to use some kind of a handle to the calling process, in order to get the virtual address in the appropriate process...

Thanks for your time!

1
Why not let kernel to work with userspace buffer from the start?Eugene Sh.
As I understand it, if I allocate a buffer in the user space, there's no guarantee that it would be continuous in the physical memory (only in the virtual memory of the current process), and I need to reveal an address to a device located on the PCIe slot, from which it can start writing continuously.Jones
perhaps this will be useful: stackoverflow.com/questions/7089735/… , although on the surface it looks like that's just dealing with files.yano
Have the user process give the userspace virtual address [and length] to your kernel driver. Your driver can/should decide if it can bypass intermediate buffers [or not]. The driver could suspend the process, lock the pages, determine the I/O space physical addresses, and generate a scatter/gather DMA operation [possibly using the I/O MMU]. The key point is that the driver is [probably] better suited to handle all this. You could have the user process request that the driver does the buffer allocation [from contiguous memory] and pass that back to the process.Craig Estey
will you not have a multi-process conflicts on a single kernel space if you mange to expose it (without copying)?Serge

1 Answers

1
votes

For your (2), how about MmMapLockedPagesSpecifyCache() with AccessMode = UserMode. Note the important caveat, "The routine returns a user address that is valid in the context of the process in which the driver is running," so you'll need to ensure the driver is running in your user-mode app's process when you perform the mapping, i.e. by doing the mapping in the driver code that directly handles a call from the user-mode code, e.g. DeviceIoControl(). Also note, to use this function, you need to supply an MDL describing the physical pages, and those pages must be locked down.