aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/include/asm/cacheflush.h5
-rw-r--r--arch/x86/kernel/ftrace.c13
-rw-r--r--arch/x86/mm/init_32.c35
-rw-r--r--arch/x86/mm/init_64.c37
4 files changed, 82 insertions, 8 deletions
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h
index 2f8466540fb5..6145063cfe0e 100644
--- a/arch/x86/include/asm/cacheflush.h
+++ b/arch/x86/include/asm/cacheflush.h
@@ -104,6 +104,11 @@ void clflush_cache_range(void *addr, unsigned int size);
104#ifdef CONFIG_DEBUG_RODATA 104#ifdef CONFIG_DEBUG_RODATA
105void mark_rodata_ro(void); 105void mark_rodata_ro(void);
106extern const int rodata_test_data; 106extern const int rodata_test_data;
107void set_kernel_text_rw(void);
108void set_kernel_text_ro(void);
109#else
110static inline void set_kernel_text_rw(void) { }
111static inline void set_kernel_text_ro(void) { }
107#endif 112#endif
108 113
109#ifdef CONFIG_DEBUG_RODATA_TEST 114#ifdef CONFIG_DEBUG_RODATA_TEST
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 231bdd3c5b1c..77857d4f7d0f 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -18,6 +18,7 @@
18#include <linux/init.h> 18#include <linux/init.h>
19#include <linux/list.h> 19#include <linux/list.h>
20 20
21#include <asm/cacheflush.h>
21#include <asm/ftrace.h> 22#include <asm/ftrace.h>
22#include <linux/ftrace.h> 23#include <linux/ftrace.h>
23#include <asm/nops.h> 24#include <asm/nops.h>
@@ -26,6 +27,18 @@
26 27
27#ifdef CONFIG_DYNAMIC_FTRACE 28#ifdef CONFIG_DYNAMIC_FTRACE
28 29
30int ftrace_arch_code_modify_prepare(void)
31{
32 set_kernel_text_rw();
33 return 0;
34}
35
36int ftrace_arch_code_modify_post_process(void)
37{
38 set_kernel_text_ro();
39 return 0;
40}
41
29union ftrace_code_union { 42union ftrace_code_union {
30 char code[MCOUNT_INSN_SIZE]; 43 char code[MCOUNT_INSN_SIZE];
31 struct { 44 struct {
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 2cef05074413..3eb2ed188a4c 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -1155,17 +1155,47 @@ static noinline int do_test_wp_bit(void)
1155const int rodata_test_data = 0xC3; 1155const int rodata_test_data = 0xC3;
1156EXPORT_SYMBOL_GPL(rodata_test_data); 1156EXPORT_SYMBOL_GPL(rodata_test_data);
1157 1157
1158static int kernel_set_to_readonly;
1159
1160void set_kernel_text_rw(void)
1161{
1162 unsigned long start = PFN_ALIGN(_text);
1163 unsigned long size = PFN_ALIGN(_etext) - start;
1164
1165 if (!kernel_set_to_readonly)
1166 return;
1167
1168 pr_debug("Set kernel text: %lx - %lx for read write\n",
1169 start, start+size);
1170
1171 set_pages_rw(virt_to_page(start), size >> PAGE_SHIFT);
1172}
1173
1174void set_kernel_text_ro(void)
1175{
1176 unsigned long start = PFN_ALIGN(_text);
1177 unsigned long size = PFN_ALIGN(_etext) - start;
1178
1179 if (!kernel_set_to_readonly)
1180 return;
1181
1182 pr_debug("Set kernel text: %lx - %lx for read only\n",
1183 start, start+size);
1184
1185 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
1186}
1187
1158void mark_rodata_ro(void) 1188void mark_rodata_ro(void)
1159{ 1189{
1160 unsigned long start = PFN_ALIGN(_text); 1190 unsigned long start = PFN_ALIGN(_text);
1161 unsigned long size = PFN_ALIGN(_etext) - start; 1191 unsigned long size = PFN_ALIGN(_etext) - start;
1162 1192
1163#ifndef CONFIG_DYNAMIC_FTRACE
1164 /* Dynamic tracing modifies the kernel text section */
1165 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT); 1193 set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
1166 printk(KERN_INFO "Write protecting the kernel text: %luk\n", 1194 printk(KERN_INFO "Write protecting the kernel text: %luk\n",
1167 size >> 10); 1195 size >> 10);
1168 1196
1197 kernel_set_to_readonly = 1;
1198
1169#ifdef CONFIG_CPA_DEBUG 1199#ifdef CONFIG_CPA_DEBUG
1170 printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n", 1200 printk(KERN_INFO "Testing CPA: Reverting %lx-%lx\n",
1171 start, start+size); 1201 start, start+size);
@@ -1174,7 +1204,6 @@ void mark_rodata_ro(void)
1174 printk(KERN_INFO "Testing CPA: write protecting again\n"); 1204 printk(KERN_INFO "Testing CPA: write protecting again\n");
1175 set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT); 1205 set_pages_ro(virt_to_page(start), size>>PAGE_SHIFT);
1176#endif 1206#endif
1177#endif /* CONFIG_DYNAMIC_FTRACE */
1178 1207
1179 start += size; 1208 start += size;
1180 size = (unsigned long)__end_rodata - start; 1209 size = (unsigned long)__end_rodata - start;
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index e6d36b490250..63fdc531601d 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -986,21 +986,48 @@ void free_initmem(void)
986const int rodata_test_data = 0xC3; 986const int rodata_test_data = 0xC3;
987EXPORT_SYMBOL_GPL(rodata_test_data); 987EXPORT_SYMBOL_GPL(rodata_test_data);
988 988
989static int kernel_set_to_readonly;
990
991void set_kernel_text_rw(void)
992{
993 unsigned long start = PFN_ALIGN(_stext);
994 unsigned long end = PFN_ALIGN(__start_rodata);
995
996 if (!kernel_set_to_readonly)
997 return;
998
999 pr_debug("Set kernel text: %lx - %lx for read write\n",
1000 start, end);
1001
1002 set_memory_rw(start, (end - start) >> PAGE_SHIFT);
1003}
1004
1005void set_kernel_text_ro(void)
1006{
1007 unsigned long start = PFN_ALIGN(_stext);
1008 unsigned long end = PFN_ALIGN(__start_rodata);
1009
1010 if (!kernel_set_to_readonly)
1011 return;
1012
1013 pr_debug("Set kernel text: %lx - %lx for read only\n",
1014 start, end);
1015
1016 set_memory_ro(start, (end - start) >> PAGE_SHIFT);
1017}
1018
989void mark_rodata_ro(void) 1019void mark_rodata_ro(void)
990{ 1020{
991 unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata); 1021 unsigned long start = PFN_ALIGN(_stext), end = PFN_ALIGN(__end_rodata);
992 unsigned long rodata_start = 1022 unsigned long rodata_start =
993 ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK; 1023 ((unsigned long)__start_rodata + PAGE_SIZE - 1) & PAGE_MASK;
994 1024
995#ifdef CONFIG_DYNAMIC_FTRACE
996 /* Dynamic tracing modifies the kernel text section */
997 start = rodata_start;
998#endif
999
1000 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n", 1025 printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
1001 (end - start) >> 10); 1026 (end - start) >> 10);
1002 set_memory_ro(start, (end - start) >> PAGE_SHIFT); 1027 set_memory_ro(start, (end - start) >> PAGE_SHIFT);
1003 1028
1029 kernel_set_to_readonly = 1;
1030
1004 /* 1031 /*
1005 * The rodata section (but not the kernel text!) should also be 1032 * The rodata section (but not the kernel text!) should also be
1006 * not-executable. 1033 * not-executable.