Execution protection (NX) and PAE


A comment from the earlier memory management entry posed a good question.  How does PAE factor into the new No Execute (NX) mechanism enabled by the Opteron, Athlon64, and new Prescott-based Xeon?



In Windows XP SP2 and Server 2003 SP1, the two are inexorably linked.  The two level address translation scheme used by the non-PAE kernel does not have enough room to accommodate any further descriptive information about individual pages of memory.  The three-level scheme that PAE necessitates allows the new NX attribute to be used.  (It is simply a bit in the Page Table Entry (PTE) that indicates the memory in this location is not allowed to be referenced by the instruction pointer.  “Do Not Run Under Penalty of Death”.)




When you use the /NoExecute switch on these OS’s, ntldr now loads the PAE kernel, but in a special mode.  You don’t get access to over 4GB of RAM, and more importantly, your drivers don’t get physical addresses over the 4GB mark either.  This is important because we’ve found that many devices and device drivers, especially in the consumer space, happily assume they’ll never have to address memory at an address over the 4GB boundary.




While you may only get to use a total of 4GB RAM in XP, that doesn’t mean that some of it can’t have a physical address above the 4GB boundary.  The BIOS or devices may re-map memory up there with the assumption that it won’t be seen or used.  When the PAE kernel starts handing out addresses to those pages of memory, things can get ugly.  The easiest way to ensure everything works like it did in the past, while allowing the new feature, is to make sure we don’t hand out any addresses over that boundary. 




If you add the /PAE switch, you get the normal PAE behavior, and all bets are off.  Of course, this is exactly what you want in the server space; after all, you got that extra RAM for a reason, right?  Also note that the properties aren’t transitive.  While both /PAE and /NoExecute use the same kernel file (ntkrnlpa.exe or ntkrpamp.exe) and address translation mechanism, you need both switches in place to enable both features.


[Added 8/6/2004 @ 2:56PM, thanks to Adam]


Note that the above information applies only to NX on processors in x86 mode.  The IA-64 and the x64 platforms natively support NX, which is being enabled for the first time with the release of Server 2003 and XP for 64bit.  Those platforms both already use a 3-level address translation scheme, but they’re not related to PAE in any way.  They address 64bits natively, and the memory structures have room to include the NX information.  We just needed to add the support to the OS.

Comments (10)

  1. Mike Dimmick says:

    Cunning – but unfortunate that you had to take this step rather than getting the driver writers to fix their code. It’s not as if PAE systems are new, nor is (for example) 64-bit PCI.

    I suppose some users would just have installed the drivers off the CD which came with the device, rather than checking for updated ones – and this kind of problem would require resolution by

    Tying up two threads – what effect does running /PAE (and/or /NoExecute) have on running /3GB (which Raymond Chen is currently writing about)? I know that the PAE mode uses 64 bits per PTE/PDE rather than 32, so you get half as many PTEs into a given virtual address space. I’ll have to confess that I don’t know whether the system address space contains all page tables for all running processes, or whether a different set of mappings is used for each process.

  2. Mike: That ties in with my first entry on memory management. Using them together means you need twice as much memory to keep track of your memory, but conversely, the kernel has half the memory to work with. In extreme situations, you can exhaust nonpaged pool, and once you do, your system is dead.

    That’s why we cap the memory limit at 16GB when using both. If you had say 24GB, used both /PAE and /3GB, the kernel would only have enough RAM to boot, and keep track of memory. Not a very useful system. 🙂

  3. Mike Dimmick says:

    Sorry, I noticed that on your earlier entry only after posting.

    I’ll admit to being a bit concerned that Exchange Information Store seems to require /3GB and /USERVA if you have more than 1GB of RAM – apparently to solve memory fragmentation problems according to http://support.microsoft.com/default.aspx?kbid=823440. That sounds more like Exchange has memory management design problems – which is a little concerning because the post-2003 version of Exchange, code-named Kodiak, has apparently been cancelled. Our server only has 768MB of RAM, so I don’t need to worry about this one at the moment.

    I’m rapidly coming to the conclusion that /3GB is only useful in very rare situations.

  4. scotts says:

    I updated my xp sp1 32 bit with the final msdn version of xp sp2 and on reboot I get a stop 0xFC error every time it mentions no execute in the text.

    I do have an AMD 64 3200 chip any idea and how to get SP2 working?

  5. Scotts, you can figure out which driver is causing the system to stop with that error and remove it, or edit your boot.ini to remove the /noexecute switch.

    I’d suggest the first option, since chances are the driver is doing other things that are just generally a bad idea.

  6. Mike,

    Exchange has a severe memory fragmentation issue, but if you’re running Exchange on a machine with only 768M of RAM, then it’s unlikely you’re servicing enough users to see the problem (it starts showing up with several (3-5) thousand users, and I doubt you could support several thousand users on a machine with that little RAM (maybe you could, I don’t know)).

    The base of the problem is the way that the default NT heap’s sections grow – by default, the NT heap grows in powers of two, which means that you start trying to allocate 128M virtual addresses pretty quickly (after 8 segments). Exchange fixes that by using multiple fixed sized heaps, but even that’s not necessarily enough, when you factor in system threads etc.

    That’s why /3G helps – it increases the amount of virtual address space available to be fragmented 🙂

  7. Does this apply to XP as well? If so, what settings in boot.ini are required to make this work properly?

    Installing SP2 took my machine from showing 4GB of memory to showing 3.18GB of memory.

    No combination of /PAE and /NoExecute=xxx retreived the memory. From a workstation perspective, the difference between 3GB and 4GB of memory is trivial, and SP2 has yet to show any other problems.