summaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/vmlinux.lds.S
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2014-04-04 02:28:11 +0200
committerKees Cook <keescook@chromium.org>2014-10-16 23:38:54 +0200
commit1e6b48116a95046ec51f3d40f83aff8b006674d7 (patch)
tree1c18e08416613ef84513cb2cd52679e7af6d4d7c /arch/arm/kernel/vmlinux.lds.S
parentarm: kgdb: Handle read-only text / modules (diff)
downloadlinux-1e6b48116a95046ec51f3d40f83aff8b006674d7.tar.xz
linux-1e6b48116a95046ec51f3d40f83aff8b006674d7.zip
ARM: mm: allow non-text sections to be non-executable
Adds CONFIG_ARM_KERNMEM_PERMS to separate the kernel memory regions into section-sized areas that can have different permisions. Performs the NX permission changes during free_initmem, so that init memory can be reclaimed. This uses section size instead of PMD size to reduce memory lost to padding on non-LPAE systems. Based on work by Brad Spengler, Larry Bassel, and Laura Abbott. Signed-off-by: Kees Cook <keescook@chromium.org> Tested-by: Laura Abbott <lauraa@codeaurora.org> Acked-by: Nicolas Pitre <nico@linaro.org>
Diffstat (limited to 'arch/arm/kernel/vmlinux.lds.S')
-rw-r--r--arch/arm/kernel/vmlinux.lds.S16
1 files changed, 16 insertions, 0 deletions
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 6f57cb94367f..18fd68a295ea 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -8,6 +8,9 @@
#include <asm/thread_info.h>
#include <asm/memory.h>
#include <asm/page.h>
+#ifdef CONFIG_ARM_KERNMEM_PERMS
+#include <asm/pgtable.h>
+#endif
#define PROC_INFO \
. = ALIGN(4); \
@@ -90,6 +93,11 @@ SECTIONS
_text = .;
HEAD_TEXT
}
+
+#ifdef CONFIG_ARM_KERNMEM_PERMS
+ . = ALIGN(1<<SECTION_SHIFT);
+#endif
+
.text : { /* Real text segment */
_stext = .; /* Text and read-only data */
__exception_text_start = .;
@@ -145,7 +153,11 @@ SECTIONS
_etext = .; /* End of text and rodata section */
#ifndef CONFIG_XIP_KERNEL
+# ifdef CONFIG_ARM_KERNMEM_PERMS
+ . = ALIGN(1<<SECTION_SHIFT);
+# else
. = ALIGN(PAGE_SIZE);
+# endif
__init_begin = .;
#endif
/*
@@ -220,7 +232,11 @@ SECTIONS
. = PAGE_OFFSET + TEXT_OFFSET;
#else
__init_end = .;
+#ifdef CONFIG_ARM_KERNMEM_PERMS
+ . = ALIGN(1<<SECTION_SHIFT);
+#else
. = ALIGN(THREAD_SIZE);
+#endif
__data_loc = .;
#endif