]> Pileus Git - ~andy/linux/blobdiff - arch/x86/kernel/vmlinux.lds.S
x86-64: add comment for RODATA large page retainment
[~andy/linux] / arch / x86 / kernel / vmlinux.lds.S
index a46acccec38a55cab91b69fdfd9cdf2dfc54a345..fd2dabec1dffd982a22f16a13b34a39734546e8f 100644 (file)
@@ -41,6 +41,32 @@ 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 */
@@ -65,17 +91,11 @@ SECTIONS
 #endif
 
        /* Text and read-only data */
-
-       /* bootstrapping code */
-       .text.head : AT(ADDR(.text.head) - LOAD_OFFSET) {
-               _text = .;
-               *(.text.head)
-       } :text = 0x9090
-
-       /* The rest of the text */
        .text :  AT(ADDR(.text) - LOAD_OFFSET) {
+               _text = .;
+               /* bootstrapping code */
+               HEAD_TEXT
 #ifdef CONFIG_X86_32
-               /* not really needed, already page aligned */
                . = ALIGN(PAGE_SIZE);
                *(.text.page_aligned)
 #endif
@@ -94,15 +114,11 @@ SECTIONS
 
        NOTES :text :note
 
-       /* Exception table */
-       . = ALIGN(16);
-       __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) {
-               __start___ex_table = .;
-               *(__ex_table)
-               __stop___ex_table = .;
-       } :text = 0x9090
+       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) {
@@ -118,7 +134,6 @@ SECTIONS
 #endif
 
                PAGE_ALIGNED_DATA(PAGE_SIZE)
-               *(.data.idt)
 
                CACHELINE_ALIGNED_DATA(CONFIG_X86_L1_CACHE_BYTES)
 
@@ -135,24 +150,21 @@ SECTIONS
 #ifdef CONFIG_X86_64
 
 #define VSYSCALL_ADDR (-10*1024*1024)
-#define VSYSCALL_PHYS_ADDR ((LOADADDR(.data) + SIZEOF(.data) + \
-                            PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
-#define VSYSCALL_VIRT_ADDR ((ADDR(.data) + SIZEOF(.data) + \
-                            PAGE_SIZE - 1) & ~(PAGE_SIZE - 1))
 
-#define VLOAD_OFFSET (VSYSCALL_ADDR - VSYSCALL_PHYS_ADDR)
+#define VLOAD_OFFSET (VSYSCALL_ADDR - __vsyscall_0 + LOAD_OFFSET)
 #define VLOAD(x) (ADDR(x) - VLOAD_OFFSET)
 
-#define VVIRT_OFFSET (VSYSCALL_ADDR - VSYSCALL_VIRT_ADDR)
+#define VVIRT_OFFSET (VSYSCALL_ADDR - __vsyscall_0)
 #define VVIRT(x) (ADDR(x) - VVIRT_OFFSET)
 
+       . = ALIGN(4096);
+       __vsyscall_0 = .;
+
        . = VSYSCALL_ADDR;
-       .vsyscall_0 : AT(VSYSCALL_PHYS_ADDR) {
+       .vsyscall_0 : AT(VLOAD(.vsyscall_0)) {
                *(.vsyscall_0)
        } :user
 
-       __vsyscall_0 = VSYSCALL_VIRT_ADDR;
-
        . = ALIGN(CONFIG_X86_L1_CACHE_BYTES);
        .vsyscall_fn : AT(VLOAD(.vsyscall_fn)) {
                *(.vsyscall_fn)
@@ -192,11 +204,9 @@ SECTIONS
                *(.vsyscall_3)
        }
 
-       . = VSYSCALL_VIRT_ADDR + PAGE_SIZE;
+       . = __vsyscall_0 + PAGE_SIZE;
 
 #undef VSYSCALL_ADDR
-#undef VSYSCALL_PHYS_ADDR
-#undef VSYSCALL_VIRT_ADDR
 #undef VLOAD_OFFSET
 #undef VLOAD
 #undef VVIRT_OFFSET
@@ -219,36 +229,12 @@ SECTIONS
        PERCPU_VADDR(0, :percpu)
 #endif
 
-       .init.text : AT(ADDR(.init.text) - LOAD_OFFSET) {
-               _sinittext = .;
-               INIT_TEXT
-               _einittext = .;
-       }
+       INIT_TEXT_SECTION(PAGE_SIZE)
 #ifdef CONFIG_X86_64
        :init
 #endif
 
-       .init.data : AT(ADDR(.init.data) - LOAD_OFFSET) {
-               INIT_DATA
-       }
-
-       . = ALIGN(16);
-       .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) {
-               __setup_start = .;
-               *(.init.setup)
-               __setup_end = .;
-       }
-       .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
-               __initcall_start = .;
-               INITCALLS
-               __initcall_end = .;
-       }
-
-       .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
-               __con_initcall_start = .;
-               *(.con_initcall.init)
-               __con_initcall_end = .;
-       }
+       INIT_DATA_SECTION(16)
 
        .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
                __x86_cpu_dev_start = .;
@@ -256,8 +242,6 @@ SECTIONS
                __x86_cpu_dev_end = .;
        }
 
-       SECURITY_INIT
-
        . = ALIGN(8);
        .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
                __parainstructions = .;
@@ -288,15 +272,6 @@ SECTIONS
                EXIT_DATA
        }
 
-#ifdef CONFIG_BLK_DEV_INITRD
-       . = ALIGN(PAGE_SIZE);
-       .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) {
-               __initramfs_start = .;
-               *(.init.ramfs)
-               __initramfs_end = .;
-       }
-#endif
-
 #if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
        PERCPU(PAGE_SIZE)
 #endif