|
@@ -22,6 +22,7 @@
|
|
|
#include <linux/bootmem.h>
|
|
|
#include <linux/proc_fs.h>
|
|
|
#include <linux/pci.h>
|
|
|
+#include <linux/pfn.h>
|
|
|
#include <linux/poison.h>
|
|
|
#include <linux/dma-mapping.h>
|
|
|
#include <linux/module.h>
|
|
@@ -563,21 +564,23 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
|
|
|
if (begin >= end)
|
|
|
return;
|
|
|
|
|
|
- printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
|
|
|
+ printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
|
|
|
for (addr = begin; addr < end; addr += PAGE_SIZE) {
|
|
|
struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
|
|
|
ClearPageReserved(page);
|
|
|
init_page_count(page);
|
|
|
memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE);
|
|
|
+ if (addr >= __START_KERNEL_map)
|
|
|
+ change_page_attr_addr(addr, 1, __pgprot(0));
|
|
|
__free_page(page);
|
|
|
totalram_pages++;
|
|
|
}
|
|
|
+ if (addr > __START_KERNEL_map)
|
|
|
+ global_flush_tlb();
|
|
|
}
|
|
|
|
|
|
void free_initmem(void)
|
|
|
{
|
|
|
- memset(__initdata_begin, POISON_FREE_INITDATA,
|
|
|
- __initdata_end - __initdata_begin);
|
|
|
free_init_pages("unused kernel memory",
|
|
|
__pa_symbol(&__init_begin),
|
|
|
__pa_symbol(&__init_end));
|
|
@@ -587,14 +590,18 @@ void free_initmem(void)
|
|
|
|
|
|
void mark_rodata_ro(void)
|
|
|
{
|
|
|
- unsigned long addr = (unsigned long)__va(__pa_symbol(&__start_rodata));
|
|
|
- unsigned long end = (unsigned long)__va(__pa_symbol(&__end_rodata));
|
|
|
+ unsigned long start = PFN_ALIGN(__va(__pa_symbol(&_stext))), size;
|
|
|
|
|
|
- for (; addr < end; addr += PAGE_SIZE)
|
|
|
- change_page_attr_addr(addr, 1, PAGE_KERNEL_RO);
|
|
|
+#ifdef CONFIG_HOTPLUG_CPU
|
|
|
+ /* It must still be possible to apply SMP alternatives. */
|
|
|
+ if (num_possible_cpus() > 1)
|
|
|
+ start = PFN_ALIGN(__va(__pa_symbol(&_etext)));
|
|
|
+#endif
|
|
|
+ size = (unsigned long)__va(__pa_symbol(&__end_rodata)) - start;
|
|
|
+ change_page_attr_addr(start, size >> PAGE_SHIFT, PAGE_KERNEL_RO);
|
|
|
|
|
|
- printk ("Write protecting the kernel read-only data: %luk\n",
|
|
|
- (__end_rodata - __start_rodata) >> 10);
|
|
|
+ printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
|
|
|
+ size >> 10);
|
|
|
|
|
|
/*
|
|
|
* change_page_attr_addr() requires a global_flush_tlb() call after it.
|