This change protects the kernel text, data, and BSS by setting the RW/NX bits correctly for the data contained on each memory page.
This change is not comprehensive:
- It doesn't do anything for modules.
- It doesn't do anything for kernel memory allocated after the kernel starts running.
- In order to avoid excessive memory inefficiency, it may let multiple types of data share a 2M page, and assigns the most permissions needed for data on that page.
There are several components to this change:
- Restore the binutils' LLD default for page sizes. This helps nudge the R/W segment to start on a 2M page.
- Add a variable to indicate the start of the R/W portion of the initial memory.
- A kernel option to set the default state of the feature, and a tunable to modify that default at boot-time.
- Stop detecting NX bit support for each AP. Instead, use the value from the BSP and, if supported, activate the feature on the other APs just before loading the correct page table. (Functionally, we already assumed that the BSP and all APs had the same support/non-support for the NX bit.)
- If the feature is activated, set the RW and NX bits correctly for the kernel text, data, and BSS (subject to the above caveats).
This may need to be documented someplace better than sys/amd64/conf/NOTES; however, I couldn't find an obvious place with the little searching I did.