mapping large userspace buffers from a driver

I want to be able to map large (~1MB) buffers to Xen (Dom0, strictly
speaking, for anyone who knows a bit about Xen), which is also
accessible via userspace under windows. Because of the overheads of
granting access to Xen to access memory owned by VM, I want to do the
mapping when the windows application starts, and unmap it when the
application ends.

From what I understand of memory sharing between userspace and kernel
space, I believe that the userspace application should allocate the
memory then give it to the driver which does the appropriate locking and
then makes the pfn’s accessible to Xen. I believe the opposite (allocate
the memory in the driver and give it to userspace) is either not
possible or not recommended.

Because the buffer remains mapped, I want the driver to give the
application a handle to that memory (just a counter starting at 1 or
something like that) and then use that handle to tell the driver when
there is new information in that buffer which in turn signals xen.

So the process from the userspace applications point of view would go:

  1. allocate a buffer
  2. open the driver
  3. tell the driver to map the buffer (via IOCTL presumably). Store the
    returned handle (eg 1)
  4. load the buffer with data
  5. tell the driver that the buffer identified by handle (eg 1) contains
    data (again, via IOCTL)
  6. when the call completes, xen is finished with the buffer
  7. repeat
  8. unmap the buffer at the end (IOCTL)

Does that sound like an even remotely sensible way to approach this? if
there weren’t any overheads in mapping the buffers to xen then I’d just
go with plain IOCTL’s and have done with it.

It seems that in order to make use of the input (for passing the address
and size of the buffer to be mapped) and output (for returning my
handle) parameters in the DeviceIoControl call, I need to use “neither
buffered nor direct i/o”, but the docs say that “only highest-level
drivers” can do that as they must be executing in the context of the
calling thread. Does my driver qualify if it is being directly called by
the userspace application? Is there another channel I could use to
return the handle, eg the lpBytesReturned parameter? Or is that strictly
for indicating the length?

I believe I can prevent the userspace application from releasing the
buffer by using MmSecureVirtualMemory. The docs seem to discourage the
use of that function though… or maybe they are discouraging scenarios
which would lead to requiring the use of that function…

All comments and suggestions appreciated?

Thanks

James

Yes, MmSecureVirtualMemory is generally discouraged from the standpoint of using it to avoid try/except usage across accesses to the VA region in question. For example, a malicious application could hand you back a VA range that corresponds to a memory mapped file view backed by a network file, and accesses to that VA range may still fault if the network connection were to go away, MmSecureVirtualMemory or not. Consequently, there aren’t very many scenarios where MmSecureVirtualMemory is really all that useful to begin with.

Please also note that MmSecureVirtualMemory has nothing to do with locking pages down such that they aren’t pageable (it only deals with the virtual mapping itself), so it would be an error to assume that you can save away the apparent backing physical address of a region that has just been MmSecureVirtualMemory’d only. This would likely yield random memory corruption when those pages are outpaged and the physical addresses in question are repurposed for some other use.

If you need to lock the physical pages down of a user mode allocation, you should use the standard MmProbeAndLockPages approach. Note also that you will need to remember to unlock the pages when the process goes away (one way to do this might be to tie the lifetime of the locked pages to a pending I/O request).

It sounds to me like you aren’t even going to use the user VA mapping from anywhere other than the user app though (if I understand you correctly), so I’m not sure why you why you would be looking at MmSecureVirtualMemory.

  • S

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of James Harper
Sent: Monday, November 22, 2010 5:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] mapping large userspace buffers from a driver

I want to be able to map large (~1MB) buffers to Xen (Dom0, strictly speaking, for anyone who knows a bit about Xen), which is also accessible via userspace under windows. Because of the overheads of granting access to Xen to access memory owned by VM, I want to do the mapping when the windows application starts, and unmap it when the application ends.

From what I understand of memory sharing between userspace and kernel space, I believe that the userspace application should allocate the memory then give it to the driver which does the appropriate locking and then makes the pfn’s accessible to Xen. I believe the opposite (allocate the memory in the driver and give it to userspace) is either not possible or not recommended.

Because the buffer remains mapped, I want the driver to give the application a handle to that memory (just a counter starting at 1 or something like that) and then use that handle to tell the driver when there is new information in that buffer which in turn signals xen.

So the process from the userspace applications point of view would go:

  1. allocate a buffer
  2. open the driver
  3. tell the driver to map the buffer (via IOCTL presumably). Store the returned handle (eg 1) 4. load the buffer with data 5. tell the driver that the buffer identified by handle (eg 1) contains data (again, via IOCTL) 6. when the call completes, xen is finished with the buffer 7. repeat 8. unmap the buffer at the end (IOCTL)

Does that sound like an even remotely sensible way to approach this? if there weren’t any overheads in mapping the buffers to xen then I’d just go with plain IOCTL’s and have done with it.

It seems that in order to make use of the input (for passing the address and size of the buffer to be mapped) and output (for returning my
handle) parameters in the DeviceIoControl call, I need to use “neither buffered nor direct i/o”, but the docs say that “only highest-level drivers” can do that as they must be executing in the context of the calling thread. Does my driver qualify if it is being directly called by the userspace application? Is there another channel I could use to return the handle, eg the lpBytesReturned parameter? Or is that strictly for indicating the length?

I believe I can prevent the userspace application from releasing the buffer by using MmSecureVirtualMemory. The docs seem to discourage the use of that function though… or maybe they are discouraging scenarios which would lead to requiring the use of that function…

All comments and suggestions appreciated?

Thanks

James


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

James,

You might want to read this thread, if you haven’t already:
https://www.osronline.com/showthread.cfm?link=168385

Paul

On 23 November 2010 01:06, James Harper wrote:
> I want to be able to map large (~1MB) buffers to Xen (Dom0, strictly
> speaking, for anyone who knows a bit about Xen), which is also
> accessible via userspace under windows. Because of the overheads of
> granting access to Xen to access memory owned by VM, I want to do the
> mapping when the windows application starts, and unmap it when the
> application ends.
>
> From what I understand of memory sharing between userspace and kernel
> space, I believe that the userspace application should allocate the
> memory then give it to the driver which does the appropriate locking and
> then makes the pfn’s accessible to Xen. I believe the opposite (allocate
> the memory in the driver and give it to userspace) is either not
> possible or not recommended.
>
> Because the buffer remains mapped, I want the driver to give the
> application a handle to that memory (just a counter starting at 1 or
> something like that) and then use that handle to tell the driver when
> there is new information in that buffer which in turn signals xen.
>
> So the process from the userspace applications point of view would go:
>
> 1. allocate a buffer
> 2. open the driver
> 3. tell the driver to map the buffer (via IOCTL presumably). Store the
> returned handle (eg 1)
> 4. load the buffer with data
> 5. tell the driver that the buffer identified by handle (eg 1) contains
> data (again, via IOCTL)
> 6. when the call completes, xen is finished with the buffer
> 7. repeat
> 8. unmap the buffer at the end (IOCTL)
>
> Does that sound like an even remotely sensible way to approach this? if
> there weren’t any overheads in mapping the buffers to xen then I’d just
> go with plain IOCTL’s and have done with it.
>
> It seems that in order to make use of the input (for passing the address
> and size of the buffer to be mapped) and output (for returning my
> handle) parameters in the DeviceIoControl call, I need to use “neither
> buffered nor direct i/o”, but the docs say that “only highest-level
> drivers” can do that as they must be executing in the context of the
> calling thread. Does my driver qualify if it is being directly called by
> the userspace application? Is there another channel I could use to
> return the handle, eg the lpBytesReturned parameter? Or is that strictly
> for indicating the length?
>
> I believe I can prevent the userspace application from releasing the
> buffer by using MmSecureVirtualMemory. The docs seem to discourage the
> use of that function though… or maybe they are discouraging scenarios
> which would lead to requiring the use of that function…
>
> All comments and suggestions appreciated?
>
> Thanks
>
> James
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>


Paul Durrant
http://www.linkedin.com/in/pdurrant

Seems like the simplest thing would be the best. Use a METHOD_IN_DIRECT (so
the buffer is writable) IOCTL and just pass the locked buffer to Xen. If
you do that in a KMDF driver, you only have to put it in a WDFQUEUE that has
a EvtIoCanceledOnQueue routine, and basically forget about it. When the app
cancels the request, ask Xen to stop using the buffer.

Phil

Philip D. Barila??? (303) 776-1264

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Skywing
Sent: Monday, November 22, 2010 7:20 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] mapping large userspace buffers from a driver

Yes, MmSecureVirtualMemory is generally discouraged from the standpoint of
using it to avoid try/except usage across accesses to the VA region in
question. For example, a malicious application could hand you back a VA
range that corresponds to a memory mapped file view backed by a network
file, and accesses to that VA range may still fault if the network
connection were to go away, MmSecureVirtualMemory or not. Consequently,
there aren’t very many scenarios where MmSecureVirtualMemory is really all
that useful to begin with.

Please also note that MmSecureVirtualMemory has nothing to do with locking
pages down such that they aren’t pageable (it only deals with the virtual
mapping itself), so it would be an error to assume that you can save away
the apparent backing physical address of a region that has just been
MmSecureVirtualMemory’d only. This would likely yield random memory
corruption when those pages are outpaged and the physical addresses in
question are repurposed for some other use.

If you need to lock the physical pages down of a user mode allocation, you
should use the standard MmProbeAndLockPages approach. Note also that you
will need to remember to unlock the pages when the process goes away (one
way to do this might be to tie the lifetime of the locked pages to a pending
I/O request).

It sounds to me like you aren’t even going to use the user VA mapping from
anywhere other than the user app though (if I understand you correctly), so
I’m not sure why you why you would be looking at MmSecureVirtualMemory.

  • S

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of James Harper
Sent: Monday, November 22, 2010 5:06 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] mapping large userspace buffers from a driver

I want to be able to map large (~1MB) buffers to Xen (Dom0, strictly
speaking, for anyone who knows a bit about Xen), which is also accessible
via userspace under windows. Because of the overheads of granting access to
Xen to access memory owned by VM, I want to do the mapping when the windows
application starts, and unmap it when the application ends.

From what I understand of memory sharing between userspace and kernel space,
I believe that the userspace application should allocate the memory then
give it to the driver which does the appropriate locking and then makes the
pfn’s accessible to Xen. I believe the opposite (allocate the memory in the
driver and give it to userspace) is either not possible or not recommended.

Because the buffer remains mapped, I want the driver to give the application
a handle to that memory (just a counter starting at 1 or something like
that) and then use that handle to tell the driver when there is new
information in that buffer which in turn signals xen.

So the process from the userspace applications point of view would go:

  1. allocate a buffer
  2. open the driver
  3. tell the driver to map the buffer (via IOCTL presumably). Store the
    returned handle (eg 1) 4. load the buffer with data 5. tell the driver that
    the buffer identified by handle (eg 1) contains data (again, via IOCTL) 6.
    when the call completes, xen is finished with the buffer 7. repeat 8. unmap
    the buffer at the end (IOCTL)

Does that sound like an even remotely sensible way to approach this? if
there weren’t any overheads in mapping the buffers to xen then I’d just go
with plain IOCTL’s and have done with it.

It seems that in order to make use of the input (for passing the address and
size of the buffer to be mapped) and output (for returning my
handle) parameters in the DeviceIoControl call, I need to use “neither
buffered nor direct i/o”, but the docs say that “only highest-level drivers”
can do that as they must be executing in the context of the calling thread.
Does my driver qualify if it is being directly called by the userspace
application? Is there another channel I could use to return the handle, eg
the lpBytesReturned parameter? Or is that strictly for indicating the
length?

I believe I can prevent the userspace application from releasing the buffer
by using MmSecureVirtualMemory. The docs seem to discourage the use of that
function though… or maybe they are discouraging scenarios which would lead
to requiring the use of that function…

All comments and suggestions appreciated?

Thanks

James


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

I assume that you are creating a kernel thread or work item to process the
user land buffer. In that case why would you use an event object, or an
event pair, together with the counter to synchronize access to the buffer.

This does seem like a potential attack vector so it would be a good idea to
think this out thoroughly. You wouldn’t want your “customers” to end up
like this guy:

http://www.kernelmode.info/forum/viewtopic.php?f=16&t=474.

>

Seems like the simplest thing would be the best. Use a
METHOD_IN_DIRECT (so
the buffer is writable) IOCTL and just pass the locked buffer to Xen.
If
you do that in a KMDF driver, you only have to put it in a WDFQUEUE
that has
a EvtIoCanceledOnQueue routine, and basically forget about it. When
the app
cancels the request, ask Xen to stop using the buffer.

This is pretty much implemented now, except that once userspace gives
the buffer to my driver, userspace can no longer write to it. I
understand that this is a very good limitation in the normal case, but I
need this buffer to continue to be writable from userspace. How can I
make it so?

Thanks

James

> >

> Seems like the simplest thing would be the best. Use a
METHOD_IN_DIRECT (so
> the buffer is writable) IOCTL and just pass the locked buffer to
Xen.
If
> you do that in a KMDF driver, you only have to put it in a WDFQUEUE
that has
> a EvtIoCanceledOnQueue routine, and basically forget about it. When
the app
> cancels the request, ask Xen to stop using the buffer.
>

This is pretty much implemented now, except that once userspace gives
the buffer to my driver, userspace can no longer write to it. I
understand that this is a very good limitation in the normal case, but
I
need this buffer to continue to be writable from userspace. How can I
make it so?

Reading a bit more… do I need to use METHOD_NEITHER and map the buffer
to meet my specifications?

Thanks

James

Why do you think the buffer is no longer writable after mapping it with an MDL?
Mark Roddy

On Mon, Dec 6, 2010 at 5:58 AM, James Harper
wrote:
>> >
>> > Seems like the simplest thing would be the best. ?Use a
>> METHOD_IN_DIRECT (so
>> > the buffer is writable) IOCTL and just pass the locked buffer to
> Xen.
>> If
>> > you do that in a KMDF driver, you only have to put it in a WDFQUEUE
>> that has
>> > a EvtIoCanceledOnQueue routine, and basically forget about it. ?When
>> the app
>> > cancels the request, ask Xen to stop using the buffer.
>> >
>>
>> This is pretty much implemented now, except that once userspace gives
>> the buffer to my driver, userspace can no longer write to it. I
>> understand that this is a very good limitation in the normal case, but
> I
>> need this buffer to continue to be writable from userspace. How can I
>> make it so?
>>
>
> Reading a bit more… do I need to use METHOD_NEITHER and map the buffer
> to meet my specifications?
>
> Thanks
>
> James
>
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer
>

>

Why do you think the buffer is no longer writable after mapping it
with an
MDL?

My userspace order of execution goes like this:

Allocate buffer
Copy dataset 1 to buffer
Submit buffer via IOCTL (METHOD_IN_DIRECT) to driver (overlapped, driver
never completes by design until cancelled)
Notify driver via IOCTL that new data is ready
(xen application shows dataset 1 in buffer)
Copy dataset 2 to buffer
Notify driver via IOCTL that new data is ready
(xen application shows dataset 1 is still in buffer, not dataset 2)

My IOCTL is defined as CTL_CODE(FILE_DEVICE_UNKNOWN, 0x880,
METHOD_IN_DIRECT, FILE_WRITE_DATA)

It would make sense to me that for regular METHOD_IN_DIRECT IOCTL’s,
protecting the buffer from userspace modification would be a good thing.
It’s just not what I want.

Do you think that the buffer does not get protected from userspace
modification? If so, maybe I made a mistake somewhere else and I’ll
revisit…

James

The buffer definitely does not get protected. I’ve used buffer’s like
this as shared memory spaces where both the kernel and the user are
updating the buffer (with appropriate synchronization).

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“James Harper” wrote in message
news:xxxxx@ntdev:

> >
> > Why do you think the buffer is no longer writable after mapping it
> with an
> > MDL?
>
> My userspace order of execution goes like this:
>
> Allocate buffer
> Copy dataset 1 to buffer
> Submit buffer via IOCTL (METHOD_IN_DIRECT) to driver (overlapped, driver
> never completes by design until cancelled)
> Notify driver via IOCTL that new data is ready
> (xen application shows dataset 1 in buffer)
> Copy dataset 2 to buffer
> Notify driver via IOCTL that new data is ready
> (xen application shows dataset 1 is still in buffer, not dataset 2)
>
> My IOCTL is defined as CTL_CODE(FILE_DEVICE_UNKNOWN, 0x880,
> METHOD_IN_DIRECT, FILE_WRITE_DATA)
>
> It would make sense to me that for regular METHOD_IN_DIRECT IOCTL’s,
> protecting the buffer from userspace modification would be a good thing.
> It’s just not what I want.
>
> Do you think that the buffer does not get protected from userspace
> modification? If so, maybe I made a mistake somewhere else and I’ll
> revisit…
>
> James

>

The buffer definitely does not get protected. I’ve used buffer’s like
this as shared memory spaces where both the kernel and the user are
updating the buffer (with appropriate synchronization).

Thanks for the clarification - I’ll go looking elsewhere for my bug :slight_smile:

James

>

>
> The buffer definitely does not get protected. I’ve used buffer’s
like
> this as shared memory spaces where both the kernel and the user are
> updating the buffer (with appropriate synchronization).
>

Thanks for the clarification - I’ll go looking elsewhere for my bug :slight_smile:

I’d assumed that METHOD_IN_DIRECT mapped the buffer straight through
from userspace to kernel space (well… same underlying pfns at least).
Is this not correct?

If I use METHOD_NEITHER and map the buffer myself then it all works
perfectly, but with METHOD_IN_DIRECT, the lower 12 bits of the address
are different (aligned to a page boundary in kernel, not aligned to a
page boundary in user), indicating that some double buffering is going
on.

Any suggestions? Is there something I could be doing incorrectly under
WDF and WDF is double buffering it for me?

Thanks

James

How are you getting the kernel address? This should be as you expected
a straight mapping of the pages.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“James Harper” wrote in message
news:xxxxx@ntdev:

> >
> > >
> > > The buffer definitely does not get protected. I’ve used buffer’s
> like
> > > this as shared memory spaces where both the kernel and the user are
> > > updating the buffer (with appropriate synchronization).
> > >
> >
> > Thanks for the clarification - I’ll go looking elsewhere for my bug :slight_smile:
> >
>
> I’d assumed that METHOD_IN_DIRECT mapped the buffer straight through
> from userspace to kernel space (well… same underlying pfns at least).
> Is this not correct?
>
> If I use METHOD_NEITHER and map the buffer myself then it all works
> perfectly, but with METHOD_IN_DIRECT, the lower 12 bits of the address
> are different (aligned to a page boundary in kernel, not aligned to a
> page boundary in user), indicating that some double buffering is going
> on.
>
> Any suggestions? Is there something I could be doing incorrectly under
> WDF and WDF is double buffering it for me?
>
> Thanks
>
> James

>

How are you getting the kernel address? This should be as you
expected
a straight mapping of the pages.

status = WdfRequestRetrieveInputWdmMdl(request, &mdl);

I never actually map it to kernel spaces, I give xen the pfns (via the
xen grant table abstraction) and xen is showing me what’s in the buffer.

When I use METHOD_IN_DIRECT it shows what was in the buffer at the time
it was mapped, but not any subsequent changes. I have since confirmed
that the pages aren’t write protected like I first thought - userspace
correctly shows the modified buffer.

When I use METHOD_NEITHER it does exactly what I expect - all buffer
modifications are mapped through to xen.

I must be doing something dumb, but it’s 12:42 am so I’m only going to
get dumber until I get some sleep, so I’d better call it a day!

Thanks

James

You need to use MmGetMdlByteOffset to get the initial offset in the
first page, and MmGetMdlByteCount to get the length. Since you are
already digging things out of the MDL you could use ByteOffset and
ByteCount fields.

Don Burn (MVP, Windows DKD)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“James Harper” wrote in message
news:xxxxx@ntdev:

> >
> > How are you getting the kernel address? This should be as you
> expected
> > a straight mapping of the pages.
> >
>
> status = WdfRequestRetrieveInputWdmMdl(request, &mdl);
>
> I never actually map it to kernel spaces, I give xen the pfns (via the
> xen grant table abstraction) and xen is showing me what’s in the buffer.
>
> When I use METHOD_IN_DIRECT it shows what was in the buffer at the time
> it was mapped, but not any subsequent changes. I have since confirmed
> that the pages aren’t write protected like I first thought - userspace
> correctly shows the modified buffer.
>
> When I use METHOD_NEITHER it does exactly what I expect - all buffer
> modifications are mapped through to xen.
>
> I must be doing something dumb, but it’s 12:42 am so I’m only going to
> get dumber until I get some sleep, so I’d better call it a day!
>
> Thanks
>
> James

On Mon, Dec 6, 2010 at 7:58 AM, James Harper
wrote:
> It would make sense to me that for regular METHOD_IN_DIRECT IOCTL’s,
> protecting the buffer from userspace modification would be a good thing.
> It’s just not what I want.

That might make sense but it doesn’t happen. The user mode VAs remain writable.

Mark Roddy

Note that this provision (protecting the user mode buffer) would, in the general sense, prove unenforceable. For example, there is no general requirement that all buffers passing through the I/O system must be multiples of the native page size, or even page aligned, etc (which would make page protection insufficiently granular for enforcing such a scheme).

  • S

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of James Harper
Sent: Monday, December 06, 2010 4:59 AM
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] mapping large userspace buffers from a driver

Why do you think the buffer is no longer writable after mapping it
with an
MDL?

My userspace order of execution goes like this:

Allocate buffer
Copy dataset 1 to buffer
Submit buffer via IOCTL (METHOD_IN_DIRECT) to driver (overlapped, driver never completes by design until cancelled) Notify driver via IOCTL that new data is ready (xen application shows dataset 1 in buffer) Copy dataset 2 to buffer Notify driver via IOCTL that new data is ready (xen application shows dataset 1 is still in buffer, not dataset 2)

My IOCTL is defined as CTL_CODE(FILE_DEVICE_UNKNOWN, 0x880, METHOD_IN_DIRECT, FILE_WRITE_DATA)

It would make sense to me that for regular METHOD_IN_DIRECT IOCTL’s, protecting the buffer from userspace modification would be a good thing.
It’s just not what I want.

Do you think that the buffer does not get protected from userspace modification? If so, maybe I made a mistake somewhere else and I’ll revisit…

James


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

To further prolong the diversion, protecting the buffer from user-space modifications during an I/O operation wouldn’t even be desirable, given Windows’ architecture.

There’s nothing inherent in Windows architecture that forces the contract between an application and a driver to mean that ONE request will only result on ONE device operation. Maybe, for your device, your METHOD_ID_DIRECT IOCTL causes the buffer contents to be written to your device once a second, with your application providing periodic updates to the buffer’s contents.

One could certainly invent an operating system where the data buffer is immutable, or is “captured” by the OS, or is off-limits in some way to the user once an I/O operation using the buffer has been issued. But that OS wouldn’t be Windows as currently designed.

Peter
OSR

Is the OP using verifier’s DMA checking, by any chance? That would cause
double-buffering that wouldn’t otherwise occur.

Phil

Philip D. Barila??? (303) 776-1264

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@osr.com
Sent: Monday, December 06, 2010 11:46 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] mapping large userspace buffers from a driver

To further prolong the diversion, protecting the buffer from user-space
modifications during an I/O operation wouldn’t even be desirable, given
Windows’ architecture.

There’s nothing inherent in Windows architecture that forces the contract
between an application and a driver to mean that ONE request will only
result on ONE device operation. Maybe, for your device, your
METHOD_ID_DIRECT IOCTL causes the buffer contents to be written to your
device once a second, with your application providing periodic updates to
the buffer’s contents.

One could certainly invent an operating system where the data buffer is
immutable, or is “captured” by the OS, or is off-limits in some way to the
user once an I/O operation using the buffer has been issued. But that OS
wouldn’t be Windows as currently designed.

Peter
OSR


NTDEV is sponsored by OSR

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

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

“Is the OP using verifier’s DMA checking, by any chance? That would cause
double-buffering that wouldn’t otherwise occur.”

Double buffering only occurs after GetScatterGatherlist call.