aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/i386/kernel/vmlinux.lds.S4
-rw-r--r--arch/i386/mm/init.c25
-rw-r--r--arch/x86_64/kernel/head.S1
-rw-r--r--arch/x86_64/kernel/vmlinux.lds.S5
-rw-r--r--arch/x86_64/mm/init.c25
-rw-r--r--include/linux/poison.h3
6 files changed, 40 insertions, 23 deletions
diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S
index 6f38f818380b..f4ec72231835 100644
--- a/arch/i386/kernel/vmlinux.lds.S
+++ b/arch/i386/kernel/vmlinux.lds.S
@@ -61,8 +61,6 @@ SECTIONS
61 __stop___ex_table = .; 61 __stop___ex_table = .;
62 } 62 }
63 63
64 RODATA
65
66 BUG_TABLE 64 BUG_TABLE
67 65
68 . = ALIGN(4); 66 . = ALIGN(4);
@@ -72,6 +70,8 @@ SECTIONS
72 __tracedata_end = .; 70 __tracedata_end = .;
73 } 71 }
74 72
73 RODATA
74
75 /* writeable */ 75 /* writeable */
76 . = ALIGN(4096); 76 . = ALIGN(4096);
77 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */ 77 .data : AT(ADDR(.data) - LOAD_OFFSET) { /* Data */
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 23be1b0aafa4..bd5ef3718504 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -22,6 +22,7 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/highmem.h> 23#include <linux/highmem.h>
24#include <linux/pagemap.h> 24#include <linux/pagemap.h>
25#include <linux/pfn.h>
25#include <linux/poison.h> 26#include <linux/poison.h>
26#include <linux/bootmem.h> 27#include <linux/bootmem.h>
27#include <linux/slab.h> 28#include <linux/slab.h>
@@ -751,13 +752,25 @@ static int noinline do_test_wp_bit(void)
751 752
752void mark_rodata_ro(void) 753void mark_rodata_ro(void)
753{ 754{
754 unsigned long addr = (unsigned long)__start_rodata; 755 unsigned long start = PFN_ALIGN(_text);
756 unsigned long size = PFN_ALIGN(_etext) - start;
755 757
756 for (; addr < (unsigned long)__end_rodata; addr += PAGE_SIZE) 758#ifdef CONFIG_HOTPLUG_CPU
757 change_page_attr(virt_to_page(addr), 1, PAGE_KERNEL_RO); 759 /* It must still be possible to apply SMP alternatives. */
760 if (num_possible_cpus() <= 1)
761#endif
762 {
763 change_page_attr(virt_to_page(start),
764 size >> PAGE_SHIFT, PAGE_KERNEL_RX);
765 printk("Write protecting the kernel text: %luk\n", size >> 10);
766 }
758 767
759 printk("Write protecting the kernel read-only data: %uk\n", 768 start += size;
760 (__end_rodata - __start_rodata) >> 10); 769 size = (unsigned long)__end_rodata - start;
770 change_page_attr(virt_to_page(start),
771 size >> PAGE_SHIFT, PAGE_KERNEL_RO);
772 printk("Write protecting the kernel read-only data: %luk\n",
773 size >> 10);
761 774
762 /* 775 /*
763 * change_page_attr() requires a global_flush_tlb() call after it. 776 * change_page_attr() requires a global_flush_tlb() call after it.
@@ -781,7 +794,7 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
781 __free_page(page); 794 __free_page(page);
782 totalram_pages++; 795 totalram_pages++;
783 } 796 }
784 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); 797 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
785} 798}
786 799
787void free_initmem(void) 800void free_initmem(void)
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index 36aa98a6d15c..fd9fdfdd143e 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -280,7 +280,6 @@ early_idt_ripmsg:
280 280
281.balign PAGE_SIZE 281.balign PAGE_SIZE
282ENTRY(stext) 282ENTRY(stext)
283ENTRY(_stext)
284 283
285#define NEXT_PAGE(name) \ 284#define NEXT_PAGE(name) \
286 .balign PAGE_SIZE; \ 285 .balign PAGE_SIZE; \
diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S
index 5176ecf006ee..3bdeb88d28f4 100644
--- a/arch/x86_64/kernel/vmlinux.lds.S
+++ b/arch/x86_64/kernel/vmlinux.lds.S
@@ -29,6 +29,7 @@ SECTIONS
29 .text : AT(ADDR(.text) - LOAD_OFFSET) { 29 .text : AT(ADDR(.text) - LOAD_OFFSET) {
30 /* First the code that has to be first for bootstrapping */ 30 /* First the code that has to be first for bootstrapping */
31 *(.bootstrap.text) 31 *(.bootstrap.text)
32 _stext = .;
32 /* Then all the functions that are "hot" in profiles, to group them 33 /* Then all the functions that are "hot" in profiles, to group them
33 onto the same hugetlb entry */ 34 onto the same hugetlb entry */
34 #include "functionlist" 35 #include "functionlist"
@@ -50,10 +51,10 @@ SECTIONS
50 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) } 51 __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
51 __stop___ex_table = .; 52 __stop___ex_table = .;
52 53
53 RODATA
54
55 BUG_TABLE 54 BUG_TABLE
56 55
56 RODATA
57
57 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ 58 . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */
58 /* Data */ 59 /* Data */
59 .data : AT(ADDR(.data) - LOAD_OFFSET) { 60 .data : AT(ADDR(.data) - LOAD_OFFSET) {
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 69e22d3c9238..e3134bc9a4fc 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -22,6 +22,7 @@
22#include <linux/bootmem.h> 22#include <linux/bootmem.h>
23#include <linux/proc_fs.h> 23#include <linux/proc_fs.h>
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/pfn.h>
25#include <linux/poison.h> 26#include <linux/poison.h>
26#include <linux/dma-mapping.h> 27#include <linux/dma-mapping.h>
27#include <linux/module.h> 28#include <linux/module.h>
@@ -563,21 +564,23 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
563 if (begin >= end) 564 if (begin >= end)
564 return; 565 return;
565 566
566 printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); 567 printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
567 for (addr = begin; addr < end; addr += PAGE_SIZE) { 568 for (addr = begin; addr < end; addr += PAGE_SIZE) {
568 struct page *page = pfn_to_page(addr >> PAGE_SHIFT); 569 struct page *page = pfn_to_page(addr >> PAGE_SHIFT);
569 ClearPageReserved(page); 570 ClearPageReserved(page);
570 init_page_count(page); 571 init_page_count(page);
571 memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE); 572 memset(page_address(page), POISON_FREE_INITMEM, PAGE_SIZE);
573 if (addr >= __START_KERNEL_map)
574 change_page_attr_addr(addr, 1, __pgprot(0));
572 __free_page(page); 575 __free_page(page);
573 totalram_pages++; 576 totalram_pages++;
574 } 577 }
578 if (addr > __START_KERNEL_map)
579 global_flush_tlb();
575} 580}
576 581
577void free_initmem(void) 582void free_initmem(void)
578{ 583{
579 memset(__initdata_begin, POISON_FREE_INITDATA,
580 __initdata_end - __initdata_begin);
581 free_init_pages("unused kernel memory", 584 free_init_pages("unused kernel memory",
582 __pa_symbol(&__init_begin), 585 __pa_symbol(&__init_begin),
583 __pa_symbol(&__init_end)); 586 __pa_symbol(&__init_end));
@@ -587,14 +590,18 @@ void free_initmem(void)
587 590
588void mark_rodata_ro(void) 591void mark_rodata_ro(void)
589{ 592{
590 unsigned long addr = (unsigned long)__va(__pa_symbol(&__start_rodata)); 593 unsigned long start = PFN_ALIGN(__va(__pa_symbol(&_stext))), size;
591 unsigned long end = (unsigned long)__va(__pa_symbol(&__end_rodata));
592 594
593 for (; addr < end; addr += PAGE_SIZE) 595#ifdef CONFIG_HOTPLUG_CPU
594 change_page_attr_addr(addr, 1, PAGE_KERNEL_RO); 596 /* It must still be possible to apply SMP alternatives. */
597 if (num_possible_cpus() > 1)
598 start = PFN_ALIGN(__va(__pa_symbol(&_etext)));
599#endif
600 size = (unsigned long)__va(__pa_symbol(&__end_rodata)) - start;
601 change_page_attr_addr(start, size >> PAGE_SHIFT, PAGE_KERNEL_RO);
595 602
596 printk ("Write protecting the kernel read-only data: %luk\n", 603 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
597 (__end_rodata - __start_rodata) >> 10); 604 size >> 10);
598 605
599 /* 606 /*
600 * change_page_attr_addr() requires a global_flush_tlb() call after it. 607 * change_page_attr_addr() requires a global_flush_tlb() call after it.
diff --git a/include/linux/poison.h b/include/linux/poison.h
index 3e628f990fdf..89580b764959 100644
--- a/include/linux/poison.h
+++ b/include/linux/poison.h
@@ -26,9 +26,6 @@
26/********** arch/$ARCH/mm/init.c **********/ 26/********** arch/$ARCH/mm/init.c **********/
27#define POISON_FREE_INITMEM 0xcc 27#define POISON_FREE_INITMEM 0xcc
28 28
29/********** arch/x86_64/mm/init.c **********/
30#define POISON_FREE_INITDATA 0xba
31
32/********** arch/ia64/hp/common/sba_iommu.c **********/ 29/********** arch/ia64/hp/common/sba_iommu.c **********/
33/* 30/*
34 * arch/ia64/hp/common/sba_iommu.c uses a 16-byte poison string with a 31 * arch/ia64/hp/common/sba_iommu.c uses a 16-byte poison string with a