diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-06 15:59:59 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-06 15:59:59 -0500 |
commit | ccf18968b1bbc2fb117190a1984ac2a826dac228 (patch) | |
tree | 7bc8fbf5722aecf1e84fa50c31c657864cba1daa /arch/x86_64/mm | |
parent | e91c021c487110386a07facd0396e6c3b7cf9c1f (diff) | |
parent | d99cf9d679a520d67f81d805b7cb91c68e1847f0 (diff) |
Merge ../torvalds-2.6/
Diffstat (limited to 'arch/x86_64/mm')
-rw-r--r-- | arch/x86_64/mm/init.c | 23 | ||||
-rw-r--r-- | arch/x86_64/mm/pageattr.c | 9 |
2 files changed, 30 insertions, 2 deletions
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index c016dfe84784..1faae5fc1c01 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -498,6 +498,29 @@ void free_initmem(void) | |||
498 | printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10); | 498 | printk ("Freeing unused kernel memory: %luk freed\n", (__init_end - __init_begin) >> 10); |
499 | } | 499 | } |
500 | 500 | ||
501 | #ifdef CONFIG_DEBUG_RODATA | ||
502 | |||
503 | extern char __start_rodata, __end_rodata; | ||
504 | void mark_rodata_ro(void) | ||
505 | { | ||
506 | unsigned long addr = (unsigned long)&__start_rodata; | ||
507 | |||
508 | for (; addr < (unsigned long)&__end_rodata; addr += PAGE_SIZE) | ||
509 | change_page_attr_addr(addr, 1, PAGE_KERNEL_RO); | ||
510 | |||
511 | printk ("Write protecting the kernel read-only data: %luk\n", | ||
512 | (&__end_rodata - &__start_rodata) >> 10); | ||
513 | |||
514 | /* | ||
515 | * change_page_attr_addr() requires a global_flush_tlb() call after it. | ||
516 | * We do this after the printk so that if something went wrong in the | ||
517 | * change, the printk gets out at least to give a better debug hint | ||
518 | * of who is the culprit. | ||
519 | */ | ||
520 | global_flush_tlb(); | ||
521 | } | ||
522 | #endif | ||
523 | |||
501 | #ifdef CONFIG_BLK_DEV_INITRD | 524 | #ifdef CONFIG_BLK_DEV_INITRD |
502 | void free_initrd_mem(unsigned long start, unsigned long end) | 525 | void free_initrd_mem(unsigned long start, unsigned long end) |
503 | { | 526 | { |
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c index b90e8fe9eeb0..35f1f1aab063 100644 --- a/arch/x86_64/mm/pageattr.c +++ b/arch/x86_64/mm/pageattr.c | |||
@@ -128,6 +128,7 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, | |||
128 | pte_t *kpte; | 128 | pte_t *kpte; |
129 | struct page *kpte_page; | 129 | struct page *kpte_page; |
130 | unsigned kpte_flags; | 130 | unsigned kpte_flags; |
131 | pgprot_t ref_prot2; | ||
131 | kpte = lookup_address(address); | 132 | kpte = lookup_address(address); |
132 | if (!kpte) return 0; | 133 | if (!kpte) return 0; |
133 | kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); | 134 | kpte_page = virt_to_page(((unsigned long)kpte) & PAGE_MASK); |
@@ -140,10 +141,14 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot, | |||
140 | * split_large_page will take the reference for this change_page_attr | 141 | * split_large_page will take the reference for this change_page_attr |
141 | * on the split page. | 142 | * on the split page. |
142 | */ | 143 | */ |
143 | struct page *split = split_large_page(address, prot, ref_prot); | 144 | |
145 | struct page *split; | ||
146 | ref_prot2 = __pgprot(pgprot_val(pte_pgprot(*lookup_address(address))) & ~(1<<_PAGE_BIT_PSE)); | ||
147 | |||
148 | split = split_large_page(address, prot, ref_prot2); | ||
144 | if (!split) | 149 | if (!split) |
145 | return -ENOMEM; | 150 | return -ENOMEM; |
146 | set_pte(kpte,mk_pte(split, ref_prot)); | 151 | set_pte(kpte,mk_pte(split, ref_prot2)); |
147 | kpte_page = split; | 152 | kpte_page = split; |
148 | } | 153 | } |
149 | get_page(kpte_page); | 154 | get_page(kpte_page); |