aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/mm
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2016-06-07 04:12:55 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-06-13 09:58:23 -0400
commitd07a980c1b8d7ac18854bae94a4e7aeabce933b8 (patch)
tree80f32e86c81aa68b12944c0534938c758d7e405d /arch/s390/mm
parent32fb2fc5c357fb99616bbe100dbcb27bc7f5d045 (diff)
s390: add proper __ro_after_init support
On s390 __ro_after_init is currently mapped to __read_mostly which means that data marked as __ro_after_init will not be protected. Reason for this is that the common code __ro_after_init implementation is x86 centric: the ro_after_init data section was added to rodata, since x86 enables write protection to kernel text and rodata very late. On s390 we have write protection for these sections enabled with the initial page tables. So adding the ro_after_init data section to rodata does not work on s390. In order to make __ro_after_init work properly on s390 move the ro_after_init data, right behind rodata. Unlike the rodata section it will be marked read-only later after all init calls happened. This s390 specific implementation adds new __start_ro_after_init and __end_ro_after_init labels. Everything in between will be marked read-only after the init calls happened. In addition to the __ro_after_init data move also the exception table there, since from a practical point of view it fits the __ro_after_init requirements. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Kees Cook <keescook@chromium.org> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r--arch/s390/mm/init.c7
-rw-r--r--arch/s390/mm/vmem.c7
2 files changed, 7 insertions, 7 deletions
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index de2cdf4fbb9a..f56a39bd8ba6 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -111,9 +111,10 @@ void __init paging_init(void)
111 111
112void mark_rodata_ro(void) 112void mark_rodata_ro(void)
113{ 113{
114 /* Text and rodata are already protected. Nothing to do here. */ 114 unsigned long size = __end_ro_after_init - __start_ro_after_init;
115 pr_info("Write protecting the kernel read-only data: %luk\n", 115
116 ((unsigned long)&_eshared - (unsigned long)&_stext) >> 10); 116 set_memory_ro((unsigned long)__start_ro_after_init, size >> PAGE_SHIFT);
117 pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
117} 118}
118 119
119void __init mem_init(void) 120void __init mem_init(void)
diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c
index a1e7c0b207e6..1848292766ef 100644
--- a/arch/s390/mm/vmem.c
+++ b/arch/s390/mm/vmem.c
@@ -373,14 +373,13 @@ out:
373 */ 373 */
374void __init vmem_map_init(void) 374void __init vmem_map_init(void)
375{ 375{
376 unsigned long ro_start, ro_end; 376 unsigned long size = _eshared - _stext;
377 struct memblock_region *reg; 377 struct memblock_region *reg;
378 378
379 for_each_memblock(memory, reg) 379 for_each_memblock(memory, reg)
380 vmem_add_mem(reg->base, reg->size); 380 vmem_add_mem(reg->base, reg->size);
381 ro_start = PFN_ALIGN((unsigned long)&_stext); 381 set_memory_ro((unsigned long)_stext, size >> PAGE_SHIFT);
382 ro_end = (unsigned long)&_eshared & PAGE_MASK; 382 pr_info("Write protected kernel read-only data: %luk\n", size >> 10);
383 set_memory_ro(ro_start, (ro_end - ro_start) >> PAGE_SHIFT);
384} 383}
385 384
386/* 385/*