aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/pageattr.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-03-15 10:27:06 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-03-15 10:27:06 -0400
commit2d3b5fa3a39d16c880bda3cf2bd9dd6ed5a01f74 (patch)
treee20283fe2ed46aa35c8ca5fc1724ba067cd2e2f8 /arch/x86/mm/pageattr.c
parent3f17522ce461a31e7ced6311b28fcf5b8a763316 (diff)
parent7278a22143b003e9af7b9ca1b5f1c40ae4b55d98 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/lethal/genesis-2.6
Diffstat (limited to 'arch/x86/mm/pageattr.c')
-rw-r--r--arch/x86/mm/pageattr.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index 1d4eb93d333c..cf07c26d9a4a 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -291,8 +291,29 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address,
291 */ 291 */
292 if (kernel_set_to_readonly && 292 if (kernel_set_to_readonly &&
293 within(address, (unsigned long)_text, 293 within(address, (unsigned long)_text,
294 (unsigned long)__end_rodata_hpage_align)) 294 (unsigned long)__end_rodata_hpage_align)) {
295 pgprot_val(forbidden) |= _PAGE_RW; 295 unsigned int level;
296
297 /*
298 * Don't enforce the !RW mapping for the kernel text mapping,
299 * if the current mapping is already using small page mapping.
300 * No need to work hard to preserve large page mappings in this
301 * case.
302 *
303 * This also fixes the Linux Xen paravirt guest boot failure
304 * (because of unexpected read-only mappings for kernel identity
305 * mappings). In this paravirt guest case, the kernel text
306 * mapping and the kernel identity mapping share the same
307 * page-table pages. Thus we can't really use different
308 * protections for the kernel text and identity mappings. Also,
309 * these shared mappings are made of small page mappings.
310 * Thus this don't enforce !RW mapping for small page kernel
311 * text mapping logic will help Linux Xen parvirt guest boot
312 * aswell.
313 */
314 if (lookup_address(address, &level) && (level != PG_LEVEL_4K))
315 pgprot_val(forbidden) |= _PAGE_RW;
316 }
296#endif 317#endif
297 318
298 prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden)); 319 prot = __pgprot(pgprot_val(prot) & ~pgprot_val(forbidden));