Merge branch 'for-35' of git://repo.or.cz/linux-kbuild
[safe/jmp/linux-2.6] / arch / x86 / kernel / vmlinux.lds.S
index 8d2d0a2..d0bb522 100644 (file)
@@ -41,13 +41,39 @@ ENTRY(phys_startup_64)
 jiffies_64 = jiffies;
 #endif
 
+#if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA)
+/*
+ * On 64-bit, align RODATA to 2MB so that even with CONFIG_DEBUG_RODATA
+ * we retain large page mappings for boundaries spanning kernel text, rodata
+ * and data sections.
+ *
+ * However, kernel identity mappings will have different RWX permissions
+ * to the pages mapping to text and to the pages padding (which are freed) the
+ * text section. Hence kernel identity mappings will be broken to smaller
+ * pages. For 64-bit, kernel text and kernel identity mappings are different,
+ * so we can enable protection checks that come with CONFIG_DEBUG_RODATA,
+ * as well as retain 2MB large page mappings for kernel text.
+ */
+#define X64_ALIGN_DEBUG_RODATA_BEGIN   . = ALIGN(HPAGE_SIZE);
+
+#define X64_ALIGN_DEBUG_RODATA_END                             \
+               . = ALIGN(HPAGE_SIZE);                          \
+               __end_rodata_hpage_align = .;
+
+#else
+
+#define X64_ALIGN_DEBUG_RODATA_BEGIN
+#define X64_ALIGN_DEBUG_RODATA_END
+
+#endif
+
 PHDRS {
        text PT_LOAD FLAGS(5);          /* R_E */
        data PT_LOAD FLAGS(7);          /* RWE */
 #ifdef CONFIG_X86_64
-       user PT_LOAD FLAGS(7);          /* RWE */
+       user PT_LOAD FLAGS(5);          /* R_E */
 #ifdef CONFIG_SMP
-       percpu PT_LOAD FLAGS(7);        /* RWE */
+       percpu PT_LOAD FLAGS(6);        /* RW_ */
 #endif
        init PT_LOAD FLAGS(7);          /* RWE */
 #endif
@@ -71,7 +97,7 @@ SECTIONS
                HEAD_TEXT
 #ifdef CONFIG_X86_32
                . = ALIGN(PAGE_SIZE);
-               *(.text.page_aligned)
+               *(.text..page_aligned)
 #endif
                . = ALIGN(8);
                _stext = .;
@@ -90,7 +116,9 @@ SECTIONS
 
        EXCEPTION_TABLE(16) :text = 0x9090
 
+       X64_ALIGN_DEBUG_RODATA_BEGIN
        RO_DATA(PAGE_SIZE)
+       X64_ALIGN_DEBUG_RODATA_END
 
        /* Data */
        .data : AT(ADDR(.data) - LOAD_OFFSET) {
@@ -107,13 +135,13 @@ SECTIONS
 
                PAGE_ALIGNED_DATA(PAGE_SIZE)
 
-               CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES)
+               CACHELINE_ALIGNED_DATA(L1_CACHE_BYTES)
 
                DATA_DATA
                CONSTRUCTORS
 
                /* rarely changed data like cpu maps */
-               READ_MOSTLY_DATA(CONFIG_X86_INTERNODE_CACHE_BYTES)
+               READ_MOSTLY_DATA(INTERNODE_CACHE_BYTES)
 
                /* End of data section */
                _edata = .;
@@ -137,12 +165,12 @@ SECTIONS
                *(.vsyscall_0)
        } :user
 
-       . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+       . = ALIGN(L1_CACHE_BYTES);
        .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) {
                *(.vsyscall_fn)
        }
 
-       . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+       . = ALIGN(L1_CACHE_BYTES);
        .vsyscall_gtod_data : AT(VLOAD(.vsyscall_gtod_data)) {
                *(.vsyscall_gtod_data)
        }
@@ -166,7 +194,7 @@ SECTIONS
        }
        vgetcpu_mode = VVIRT(.vgetcpu_mode);
 
-       . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
+       . = ALIGN(L1_CACHE_BYTES);
        .jiffies : AT(VLOAD(.jiffies)) {
                *(.jiffies)
        }
@@ -263,8 +291,8 @@ SECTIONS
        .smp_locks : AT(ADDR(.smp_locks) - LOAD_OFFSET) {
                __smp_locks = .;
                *(.smp_locks)
-               __smp_locks_end = .;
                . = ALIGN(PAGE_SIZE);
+               __smp_locks_end = .;
        }
 
 #ifdef CONFIG_X86_64
@@ -277,7 +305,7 @@ SECTIONS
        . = ALIGN(PAGE_SIZE);
        .bss : AT(ADDR(.bss) - LOAD_OFFSET) {
                __bss_start = .;
-               *(.bss.page_aligned)
+               *(.bss..page_aligned)
                *(.bss)
                . = ALIGN(4);
                __bss_stop = .;
@@ -291,9 +319,7 @@ SECTIONS
                __brk_limit = .;
        }
 
-       .end : AT(ADDR(.end) - LOAD_OFFSET) {
-               _end = .;
-       }
+       _end = .;
 
         STABS_DEBUG
         DWARF_DEBUG
@@ -305,6 +331,9 @@ SECTIONS
 
 
 #ifdef CONFIG_X86_32
+/*
+ * The ASSERT() sink to . is intentional, for binutils 2.14 compatibility:
+ */
 . = ASSERT((_end - LOAD_OFFSET <= KERNEL_IMAGE_SIZE),
           "kernel image bigger than KERNEL_IMAGE_SIZE");
 #else
@@ -312,7 +341,7 @@ SECTIONS
  * Per-cpu symbols which need to be offset from __per_cpu_load
  * for the boot processor.
  */
-#define INIT_PER_CPU(x) init_per_cpu__##x = per_cpu__##x + __per_cpu_load
+#define INIT_PER_CPU(x) init_per_cpu__##x = x + __per_cpu_load
 INIT_PER_CPU(gdt_page);
 INIT_PER_CPU(irq_stack_union);
 
@@ -323,7 +352,7 @@ INIT_PER_CPU(irq_stack_union);
           "kernel image bigger than KERNEL_IMAGE_SIZE");
 
 #ifdef CONFIG_SMP
-. = ASSERT((per_cpu__irq_stack_union == 0),
+. = ASSERT((irq_stack_union == 0),
            "irq_stack_union is not at start of per-cpu area");
 #endif