diff options
author | Kees Cook <keescook@chromium.org> | 2016-02-17 17:41:14 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-02-22 02:51:38 -0500 |
commit | 9ccaf77cf05915f51231d158abfd5448aedde758 (patch) | |
tree | d6cd4476921b59c2e20773ea585792a867dc328b | |
parent | d2aa1acad22f1bdd0cfa67b3861800e392254454 (diff) |
x86/mm: Always enable CONFIG_DEBUG_RODATA and remove the Kconfig option
This removes the CONFIG_DEBUG_RODATA option and makes it always enabled.
This simplifies the code and also makes it clearer that read-only mapped
memory is just as fundamental a security feature in kernel-space as it is
in user-space.
Suggested-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Brown <david.brown@linaro.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Emese Revfy <re.emese@gmail.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mathias Krause <minipli@googlemail.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: PaX Team <pageexec@freemail.hu>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: kernel-hardening@lists.openwall.com
Cc: linux-arch <linux-arch@vger.kernel.org>
Link: http://lkml.kernel.org/r/1455748879-21872-4-git-send-email-keescook@chromium.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/Kconfig | 3 | ||||
-rw-r--r-- | arch/x86/Kconfig.debug | 18 | ||||
-rw-r--r-- | arch/x86/include/asm/cacheflush.h | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/kvm_para.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/sections.h | 2 | ||||
-rw-r--r-- | arch/x86/kernel/ftrace.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/kgdb.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/test_nx.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/test_rodata.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/vmlinux.lds.S | 25 | ||||
-rw-r--r-- | arch/x86/mm/init_32.c | 3 | ||||
-rw-r--r-- | arch/x86/mm/init_64.c | 3 | ||||
-rw-r--r-- | arch/x86/mm/pageattr.c | 2 |
13 files changed, 25 insertions, 61 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c46662f64c39..b1051057e5b0 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -303,6 +303,9 @@ config ARCH_SUPPORTS_UPROBES | |||
303 | config FIX_EARLYCON_MEM | 303 | config FIX_EARLYCON_MEM |
304 | def_bool y | 304 | def_bool y |
305 | 305 | ||
306 | config DEBUG_RODATA | ||
307 | def_bool y | ||
308 | |||
306 | config PGTABLE_LEVELS | 309 | config PGTABLE_LEVELS |
307 | int | 310 | int |
308 | default 4 if X86_64 | 311 | default 4 if X86_64 |
diff --git a/arch/x86/Kconfig.debug b/arch/x86/Kconfig.debug index 9b18ed97a8a2..7816b7b276f4 100644 --- a/arch/x86/Kconfig.debug +++ b/arch/x86/Kconfig.debug | |||
@@ -74,28 +74,16 @@ config EFI_PGT_DUMP | |||
74 | issues with the mapping of the EFI runtime regions into that | 74 | issues with the mapping of the EFI runtime regions into that |
75 | table. | 75 | table. |
76 | 76 | ||
77 | config DEBUG_RODATA | ||
78 | bool "Write protect kernel read-only data structures" | ||
79 | default y | ||
80 | depends on DEBUG_KERNEL | ||
81 | ---help--- | ||
82 | Mark the kernel read-only data as write-protected in the pagetables, | ||
83 | in order to catch accidental (and incorrect) writes to such const | ||
84 | data. This is recommended so that we can catch kernel bugs sooner. | ||
85 | If in doubt, say "Y". | ||
86 | |||
87 | config DEBUG_RODATA_TEST | 77 | config DEBUG_RODATA_TEST |
88 | bool "Testcase for the DEBUG_RODATA feature" | 78 | bool "Testcase for the marking rodata read-only" |
89 | depends on DEBUG_RODATA | ||
90 | default y | 79 | default y |
91 | ---help--- | 80 | ---help--- |
92 | This option enables a testcase for the DEBUG_RODATA | 81 | This option enables a testcase for the setting rodata read-only |
93 | feature as well as for the change_page_attr() infrastructure. | 82 | as well as for the change_page_attr() infrastructure. |
94 | If in doubt, say "N" | 83 | If in doubt, say "N" |
95 | 84 | ||
96 | config DEBUG_WX | 85 | config DEBUG_WX |
97 | bool "Warn on W+X mappings at boot" | 86 | bool "Warn on W+X mappings at boot" |
98 | depends on DEBUG_RODATA | ||
99 | select X86_PTDUMP_CORE | 87 | select X86_PTDUMP_CORE |
100 | ---help--- | 88 | ---help--- |
101 | Generate a warning if any W+X mappings are found at boot. | 89 | Generate a warning if any W+X mappings are found at boot. |
diff --git a/arch/x86/include/asm/cacheflush.h b/arch/x86/include/asm/cacheflush.h index c8cff75c5b21..61518cf79437 100644 --- a/arch/x86/include/asm/cacheflush.h +++ b/arch/x86/include/asm/cacheflush.h | |||
@@ -91,15 +91,10 @@ void clflush_cache_range(void *addr, unsigned int size); | |||
91 | 91 | ||
92 | #define mmio_flush_range(addr, size) clflush_cache_range(addr, size) | 92 | #define mmio_flush_range(addr, size) clflush_cache_range(addr, size) |
93 | 93 | ||
94 | #ifdef CONFIG_DEBUG_RODATA | ||
95 | extern const int rodata_test_data; | 94 | extern const int rodata_test_data; |
96 | extern int kernel_set_to_readonly; | 95 | extern int kernel_set_to_readonly; |
97 | void set_kernel_text_rw(void); | 96 | void set_kernel_text_rw(void); |
98 | void set_kernel_text_ro(void); | 97 | void set_kernel_text_ro(void); |
99 | #else | ||
100 | static inline void set_kernel_text_rw(void) { } | ||
101 | static inline void set_kernel_text_ro(void) { } | ||
102 | #endif | ||
103 | 98 | ||
104 | #ifdef CONFIG_DEBUG_RODATA_TEST | 99 | #ifdef CONFIG_DEBUG_RODATA_TEST |
105 | int rodata_test(void); | 100 | int rodata_test(void); |
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h index c1adf33fdd0d..bc62e7cbf1b1 100644 --- a/arch/x86/include/asm/kvm_para.h +++ b/arch/x86/include/asm/kvm_para.h | |||
@@ -17,15 +17,8 @@ static inline bool kvm_check_and_clear_guest_paused(void) | |||
17 | } | 17 | } |
18 | #endif /* CONFIG_KVM_GUEST */ | 18 | #endif /* CONFIG_KVM_GUEST */ |
19 | 19 | ||
20 | #ifdef CONFIG_DEBUG_RODATA | ||
21 | #define KVM_HYPERCALL \ | 20 | #define KVM_HYPERCALL \ |
22 | ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9", X86_FEATURE_VMMCALL) | 21 | ALTERNATIVE(".byte 0x0f,0x01,0xc1", ".byte 0x0f,0x01,0xd9", X86_FEATURE_VMMCALL) |
23 | #else | ||
24 | /* On AMD processors, vmcall will generate a trap that we will | ||
25 | * then rewrite to the appropriate instruction. | ||
26 | */ | ||
27 | #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1" | ||
28 | #endif | ||
29 | 22 | ||
30 | /* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall | 23 | /* For KVM hypercalls, a three-byte sequence of either the vmcall or the vmmcall |
31 | * instruction. The hypervisor may replace it with something else but only the | 24 | * instruction. The hypervisor may replace it with something else but only the |
diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h index 0a5242428659..13b6cdd0af57 100644 --- a/arch/x86/include/asm/sections.h +++ b/arch/x86/include/asm/sections.h | |||
@@ -7,7 +7,7 @@ | |||
7 | extern char __brk_base[], __brk_limit[]; | 7 | extern char __brk_base[], __brk_limit[]; |
8 | extern struct exception_table_entry __stop___ex_table[]; | 8 | extern struct exception_table_entry __stop___ex_table[]; |
9 | 9 | ||
10 | #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) | 10 | #if defined(CONFIG_X86_64) |
11 | extern char __end_rodata_hpage_align[]; | 11 | extern char __end_rodata_hpage_align[]; |
12 | #endif | 12 | #endif |
13 | 13 | ||
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 29408d6d6626..05c9e3f5b6d7 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c | |||
@@ -81,9 +81,9 @@ within(unsigned long addr, unsigned long start, unsigned long end) | |||
81 | static unsigned long text_ip_addr(unsigned long ip) | 81 | static unsigned long text_ip_addr(unsigned long ip) |
82 | { | 82 | { |
83 | /* | 83 | /* |
84 | * On x86_64, kernel text mappings are mapped read-only with | 84 | * On x86_64, kernel text mappings are mapped read-only, so we use |
85 | * CONFIG_DEBUG_RODATA. So we use the kernel identity mapping instead | 85 | * the kernel identity mapping instead of the kernel text mapping |
86 | * of the kernel text mapping to modify the kernel text. | 86 | * to modify the kernel text. |
87 | * | 87 | * |
88 | * For 32bit kernels, these mappings are same and we can use | 88 | * For 32bit kernels, these mappings are same and we can use |
89 | * kernel identity mapping to modify code. | 89 | * kernel identity mapping to modify code. |
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 44256a62702b..ed15cd486d06 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -750,9 +750,7 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip) | |||
750 | int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) | 750 | int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) |
751 | { | 751 | { |
752 | int err; | 752 | int err; |
753 | #ifdef CONFIG_DEBUG_RODATA | ||
754 | char opc[BREAK_INSTR_SIZE]; | 753 | char opc[BREAK_INSTR_SIZE]; |
755 | #endif /* CONFIG_DEBUG_RODATA */ | ||
756 | 754 | ||
757 | bpt->type = BP_BREAKPOINT; | 755 | bpt->type = BP_BREAKPOINT; |
758 | err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, | 756 | err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr, |
@@ -761,7 +759,6 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) | |||
761 | return err; | 759 | return err; |
762 | err = probe_kernel_write((char *)bpt->bpt_addr, | 760 | err = probe_kernel_write((char *)bpt->bpt_addr, |
763 | arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); | 761 | arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE); |
764 | #ifdef CONFIG_DEBUG_RODATA | ||
765 | if (!err) | 762 | if (!err) |
766 | return err; | 763 | return err; |
767 | /* | 764 | /* |
@@ -778,13 +775,12 @@ int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt) | |||
778 | if (memcmp(opc, arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE)) | 775 | if (memcmp(opc, arch_kgdb_ops.gdb_bpt_instr, BREAK_INSTR_SIZE)) |
779 | return -EINVAL; | 776 | return -EINVAL; |
780 | bpt->type = BP_POKE_BREAKPOINT; | 777 | bpt->type = BP_POKE_BREAKPOINT; |
781 | #endif /* CONFIG_DEBUG_RODATA */ | 778 | |
782 | return err; | 779 | return err; |
783 | } | 780 | } |
784 | 781 | ||
785 | int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) | 782 | int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) |
786 | { | 783 | { |
787 | #ifdef CONFIG_DEBUG_RODATA | ||
788 | int err; | 784 | int err; |
789 | char opc[BREAK_INSTR_SIZE]; | 785 | char opc[BREAK_INSTR_SIZE]; |
790 | 786 | ||
@@ -801,8 +797,8 @@ int kgdb_arch_remove_breakpoint(struct kgdb_bkpt *bpt) | |||
801 | if (err || memcmp(opc, bpt->saved_instr, BREAK_INSTR_SIZE)) | 797 | if (err || memcmp(opc, bpt->saved_instr, BREAK_INSTR_SIZE)) |
802 | goto knl_write; | 798 | goto knl_write; |
803 | return err; | 799 | return err; |
800 | |||
804 | knl_write: | 801 | knl_write: |
805 | #endif /* CONFIG_DEBUG_RODATA */ | ||
806 | return probe_kernel_write((char *)bpt->bpt_addr, | 802 | return probe_kernel_write((char *)bpt->bpt_addr, |
807 | (char *)bpt->saved_instr, BREAK_INSTR_SIZE); | 803 | (char *)bpt->saved_instr, BREAK_INSTR_SIZE); |
808 | } | 804 | } |
diff --git a/arch/x86/kernel/test_nx.c b/arch/x86/kernel/test_nx.c index 3f92ce07e525..27538f183c3b 100644 --- a/arch/x86/kernel/test_nx.c +++ b/arch/x86/kernel/test_nx.c | |||
@@ -142,7 +142,6 @@ static int test_NX(void) | |||
142 | * by the error message | 142 | * by the error message |
143 | */ | 143 | */ |
144 | 144 | ||
145 | #ifdef CONFIG_DEBUG_RODATA | ||
146 | /* Test 3: Check if the .rodata section is executable */ | 145 | /* Test 3: Check if the .rodata section is executable */ |
147 | if (rodata_test_data != 0xC3) { | 146 | if (rodata_test_data != 0xC3) { |
148 | printk(KERN_ERR "test_nx: .rodata marker has invalid value\n"); | 147 | printk(KERN_ERR "test_nx: .rodata marker has invalid value\n"); |
@@ -151,7 +150,6 @@ static int test_NX(void) | |||
151 | printk(KERN_ERR "test_nx: .rodata section is executable\n"); | 150 | printk(KERN_ERR "test_nx: .rodata section is executable\n"); |
152 | ret = -ENODEV; | 151 | ret = -ENODEV; |
153 | } | 152 | } |
154 | #endif | ||
155 | 153 | ||
156 | #if 0 | 154 | #if 0 |
157 | /* Test 4: Check if the .data section of a module is executable */ | 155 | /* Test 4: Check if the .data section of a module is executable */ |
diff --git a/arch/x86/kernel/test_rodata.c b/arch/x86/kernel/test_rodata.c index 5ecbfe5099da..cb4a01b41e27 100644 --- a/arch/x86/kernel/test_rodata.c +++ b/arch/x86/kernel/test_rodata.c | |||
@@ -76,5 +76,5 @@ int rodata_test(void) | |||
76 | } | 76 | } |
77 | 77 | ||
78 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
79 | MODULE_DESCRIPTION("Testcase for the DEBUG_RODATA infrastructure"); | 79 | MODULE_DESCRIPTION("Testcase for marking rodata as read-only"); |
80 | MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); | 80 | MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); |
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S index 74e4bf11f562..fe133b710bef 100644 --- a/arch/x86/kernel/vmlinux.lds.S +++ b/arch/x86/kernel/vmlinux.lds.S | |||
@@ -41,29 +41,28 @@ ENTRY(phys_startup_64) | |||
41 | jiffies_64 = jiffies; | 41 | jiffies_64 = jiffies; |
42 | #endif | 42 | #endif |
43 | 43 | ||
44 | #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) | 44 | #if defined(CONFIG_X86_64) |
45 | /* | 45 | /* |
46 | * On 64-bit, align RODATA to 2MB so that even with CONFIG_DEBUG_RODATA | 46 | * On 64-bit, align RODATA to 2MB so we retain large page mappings for |
47 | * we retain large page mappings for boundaries spanning kernel text, rodata | 47 | * boundaries spanning kernel text, rodata and data sections. |
48 | * and data sections. | ||
49 | * | 48 | * |
50 | * However, kernel identity mappings will have different RWX permissions | 49 | * However, kernel identity mappings will have different RWX permissions |
51 | * to the pages mapping to text and to the pages padding (which are freed) the | 50 | * to the pages mapping to text and to the pages padding (which are freed) the |
52 | * text section. Hence kernel identity mappings will be broken to smaller | 51 | * text section. Hence kernel identity mappings will be broken to smaller |
53 | * pages. For 64-bit, kernel text and kernel identity mappings are different, | 52 | * pages. For 64-bit, kernel text and kernel identity mappings are different, |
54 | * so we can enable protection checks that come with CONFIG_DEBUG_RODATA, | 53 | * so we can enable protection checks as well as retain 2MB large page |
55 | * as well as retain 2MB large page mappings for kernel text. | 54 | * mappings for kernel text. |
56 | */ | 55 | */ |
57 | #define X64_ALIGN_DEBUG_RODATA_BEGIN . = ALIGN(HPAGE_SIZE); | 56 | #define X64_ALIGN_RODATA_BEGIN . = ALIGN(HPAGE_SIZE); |
58 | 57 | ||
59 | #define X64_ALIGN_DEBUG_RODATA_END \ | 58 | #define X64_ALIGN_RODATA_END \ |
60 | . = ALIGN(HPAGE_SIZE); \ | 59 | . = ALIGN(HPAGE_SIZE); \ |
61 | __end_rodata_hpage_align = .; | 60 | __end_rodata_hpage_align = .; |
62 | 61 | ||
63 | #else | 62 | #else |
64 | 63 | ||
65 | #define X64_ALIGN_DEBUG_RODATA_BEGIN | 64 | #define X64_ALIGN_RODATA_BEGIN |
66 | #define X64_ALIGN_DEBUG_RODATA_END | 65 | #define X64_ALIGN_RODATA_END |
67 | 66 | ||
68 | #endif | 67 | #endif |
69 | 68 | ||
@@ -112,13 +111,11 @@ SECTIONS | |||
112 | 111 | ||
113 | EXCEPTION_TABLE(16) :text = 0x9090 | 112 | EXCEPTION_TABLE(16) :text = 0x9090 |
114 | 113 | ||
115 | #if defined(CONFIG_DEBUG_RODATA) | ||
116 | /* .text should occupy whole number of pages */ | 114 | /* .text should occupy whole number of pages */ |
117 | . = ALIGN(PAGE_SIZE); | 115 | . = ALIGN(PAGE_SIZE); |
118 | #endif | 116 | X64_ALIGN_RODATA_BEGIN |
119 | X64_ALIGN_DEBUG_RODATA_BEGIN | ||
120 | RO_DATA(PAGE_SIZE) | 117 | RO_DATA(PAGE_SIZE) |
121 | X64_ALIGN_DEBUG_RODATA_END | 118 | X64_ALIGN_RODATA_END |
122 | 119 | ||
123 | /* Data */ | 120 | /* Data */ |
124 | .data : AT(ADDR(.data) - LOAD_OFFSET) { | 121 | .data : AT(ADDR(.data) - LOAD_OFFSET) { |
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index cb4ef3de61f9..2ebfbaf61142 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c | |||
@@ -871,7 +871,6 @@ static noinline int do_test_wp_bit(void) | |||
871 | return flag; | 871 | return flag; |
872 | } | 872 | } |
873 | 873 | ||
874 | #ifdef CONFIG_DEBUG_RODATA | ||
875 | const int rodata_test_data = 0xC3; | 874 | const int rodata_test_data = 0xC3; |
876 | EXPORT_SYMBOL_GPL(rodata_test_data); | 875 | EXPORT_SYMBOL_GPL(rodata_test_data); |
877 | 876 | ||
@@ -960,5 +959,3 @@ void mark_rodata_ro(void) | |||
960 | if (__supported_pte_mask & _PAGE_NX) | 959 | if (__supported_pte_mask & _PAGE_NX) |
961 | debug_checkwx(); | 960 | debug_checkwx(); |
962 | } | 961 | } |
963 | #endif | ||
964 | |||
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 5488d21123bd..a40b755c67e3 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -1074,7 +1074,6 @@ void __init mem_init(void) | |||
1074 | mem_init_print_info(NULL); | 1074 | mem_init_print_info(NULL); |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | #ifdef CONFIG_DEBUG_RODATA | ||
1078 | const int rodata_test_data = 0xC3; | 1077 | const int rodata_test_data = 0xC3; |
1079 | EXPORT_SYMBOL_GPL(rodata_test_data); | 1078 | EXPORT_SYMBOL_GPL(rodata_test_data); |
1080 | 1079 | ||
@@ -1166,8 +1165,6 @@ void mark_rodata_ro(void) | |||
1166 | debug_checkwx(); | 1165 | debug_checkwx(); |
1167 | } | 1166 | } |
1168 | 1167 | ||
1169 | #endif | ||
1170 | |||
1171 | int kern_addr_valid(unsigned long addr) | 1168 | int kern_addr_valid(unsigned long addr) |
1172 | { | 1169 | { |
1173 | unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT; | 1170 | unsigned long above = ((long)addr) >> __VIRTUAL_MASK_SHIFT; |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 2440814b0069..2450488f39ef 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -283,7 +283,7 @@ static inline pgprot_t static_protections(pgprot_t prot, unsigned long address, | |||
283 | __pa_symbol(__end_rodata) >> PAGE_SHIFT)) | 283 | __pa_symbol(__end_rodata) >> PAGE_SHIFT)) |
284 | pgprot_val(forbidden) |= _PAGE_RW; | 284 | pgprot_val(forbidden) |= _PAGE_RW; |
285 | 285 | ||
286 | #if defined(CONFIG_X86_64) && defined(CONFIG_DEBUG_RODATA) | 286 | #if defined(CONFIG_X86_64) |
287 | /* | 287 | /* |
288 | * Once the kernel maps the text as RO (kernel_set_to_readonly is set), | 288 | * Once the kernel maps the text as RO (kernel_set_to_readonly is set), |
289 | * kernel text mappings for the large page aligned text, rodata sections | 289 | * kernel text mappings for the large page aligned text, rodata sections |