Tech Support > Microsoft Windows > Drivers > Mapping memory to 32-bit user-mode with 64-bit driver
Mapping memory to 32-bit user-mode with 64-bit driver
Posted by E. Nelson on August 27th, 2003



Greets all,

I've been working on porting our drivers to 64-bit, and came across a
problem I'm not sure can be solved. We have a few kernel memory
regions, such as a large contiguous video buffer, that we map into
user-mode. All access is handled within the DLLs. (I imagine this
might be frowned upon, but it's legacy code, and rewriting it will
take far longer.)

Now, the driver is responsible for generating the user-mode pointer,
and providing it to the caller. The question is, if the caller is
32-bit, how can I restrict the mapping to remain within 32-bit address
space?

-EN

Posted by E. Nelson on August 27th, 2003


PeterGV wrote:

Let me clarify. My concern is with moving to 64-bit Windows, such as
on an AMD Athlon64 (or whatever), which mandates 64-bit drivers, but
allows 32-bit applications. The driver has no knowledge of what kind
of client is using it.

The driver performs, say, MmMapLockedPages(mdl, UserMode), which
returns a PVOID. Now, the driver, being 64-bit, could presumably
return a pointer anywhere within the 64-bit address space. However,
the calling app, which may still be 32-bit, might not be able to
utilize that pointer.

I was wondering if there was some sort of kernel-mode magic that would
restrict the MmMapLockedPages() call to 32-bit limitations, when
appropriate.

To answer your question, Peter, I haven't actually tried it (as I
don't have a 64-bit machine yet), but I don't see how the PVOID return
pointer could be anything but 64-bit, since it was generated within
the 64-bit driver. Perhaps my assumption that 64-bit Windows will
allow 32-bit apps to run is incorrect? As I understand it, there's a
WOW64 emulation mode for IA-32 apps to run on Itanium, though, so I
expect an Athlon64, which natively allows 32-bit code, would also be
supported.

All ideas appreciated!
-EN


Posted by Tim Roberts on August 28th, 2003


no.email@use.net (E. Nelson) wrote:

I don't think so. I suspect Peter is exactly correct. The whole reason
for passing "UserMode" to MmMapLockedPages is to force it to return
something that is valid for the current process. Since it will certainly
know that the current user-mode process is 32-bit, I would be very
surprised if it dod not return a virtual address within the 32-bit address
space.

....but it was generated by a system API that has access to the current
process information.
--
- Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Posted by Peter Viscarola on August 28th, 2003



"E. Nelson" <no.email@use.net> wrote in message
news:3f4d20be.167968@news.east.earthlink.net...
Well, that's not really correct. On receipt of an IRP, your driver can find
out if it was called by a 32-bit client using the function
IoIs32BitProcess(Irp).

It COULD, but I *suspect* (and this is only a guess, OK?) that the memory
manager is smarter than that.

Oh, no! You're assumtion is absolutely correct. In fact, the AMD64 runs
native 32 bit apps natively (and at cutting edge speed), without any nasty
emulation... just thunking 32 to 64 bit pointers. Check out the article
that discusses this at http://www.osronline.com/article.cfm?id=243 (you
have to be a subscriber to The NT Insider to read the article, but the
subscription is totally free).

You raise a good question... Tell you what. We'll give it a try this
afternoon and let you know what we find.

Peter
OSR
http://www.osronline.com



Posted by Peter Viscarola on August 28th, 2003



"E. Nelson" <no.email@use.net> wrote in message
news:3f4dc6d0.23780046@news.east.earthlink.net...
OK... We tried this here on our AMD64 (a solo, in case it matters to
anyone).

We (well, actually SNoone, cuz who else could we convince to write code on
demand to test something like this) wrote a driver that, on receipt of a
specific IOCTL, mapped a hunk of pages from non-paged pool back into user
space (DO NOT DO THIS: This can create a nasty security loophole. This was
a TEST, OK??). We checked the returned user VA from
MmMapLockedPagesSpecifyCache(...) to ensure that it was less than
0x80000000. We built the driver for the AMD-64 and installed it.

We wrote a user-mode program, compiled 32 bit, and ran it on the AMD64
system, talking to the driver, issuing the IOCTL. It worked. The pool
block was mapped into the low 2GB of user virtual address space.

One trial does not a proof make. So, for yet more fun, we changed the
driver so that it never unlocked the pages that were mapped. We then changed
the app to HAMMER the driver, by issuing the IOCTL repeatedly until it died.

And Hoo Ha! As we expected, the program craps out after addresses in the
upper 0x70000000 are returned. We never see the block mapped to an address
out of the user app's virual address range.

So, this ain't exactly a verification by review of the source code, but I
think it's a pretty safe indication that my first inclination (and Tim's)
was correct. The Memory Manager "does the right thing."

We'll post the code on www.osronline.com for those who are interested.

Peter
OSR
http://www.osronline.com




Posted by E. Nelson on August 28th, 2003


Wow, that was generous! My thanks to the tester for going to the
effort. The results certainly make sense; I just made a bad guess
that the process was opaque to the driver, oblivious to the kernel
memory manager being used by the kernel API's.

That alleviates my concern about smoothly making the transition for
that portion of code.
-EN


Posted by Peter Viscarola on August 29th, 2003



"E. Nelson" <no.email@use.net> wrote in message
news:3f4e8964.73592562@news.east.earthlink.net...
No problem. I'm a big fan of the AMD64, and I figured we should be able to
say with authority that this does or doesn't work the way we hypothesized.

Peter
OSR
http://www.osronline.com