aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64')
-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
3 files changed, 19 insertions, 12 deletions
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.