From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755441AbcFGMHX (ORCPT ); Tue, 7 Jun 2016 08:07:23 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:58382 "EHLO mx0b-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1754551AbcFGMHQ (ORCPT ); Tue, 7 Jun 2016 08:07:16 -0400 Message-Id: <201606071207.u57C5RhP032778@mx0a-001b2d01.pphosted.com> X-IBM-Helo: d06dlp01.portsmouth.uk.ibm.com X-IBM-MailFrom: heiko.carstens@de.ibm.com X-IBM-RcptTo: linux-kernel@vger.kernel.org From: Heiko Carstens To: Kees Cook , Ingo Molnar Cc: Martin Schwidefsky , linux-kernel@vger.kernel.org Subject: [PATCH 2/2] s390/mm: add proper __ro_after_init support Date: Tue, 7 Jun 2016 14:07:01 +0200 X-Mailer: git-send-email 2.6.6 In-Reply-To: <1465301221-18583-1-git-send-email-heiko.carstens@de.ibm.com> References: <1465301221-18583-1-git-send-email-heiko.carstens@de.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16060712-0016-0000-0000-000001F2A7FD X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16060712-0017-0000-0000-000021D118E8 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-06-07_07:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=8 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606070140 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- arch/s390/include/asm/cache.h | 3 --- arch/s390/include/asm/sections.h | 1 + arch/s390/kernel/vmlinux.lds.S | 12 +++++++++++- arch/s390/mm/init.c | 7 ++++--- arch/s390/mm/vmem.c | 7 +++---- 5 files changed, 19 insertions(+), 11 deletions(-) diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h index 22da3b34c655..4d7ccac5fd1d 100644 --- a/arch/s390/include/asm/cache.h +++ b/arch/s390/include/asm/cache.h @@ -15,7 +15,4 @@ #define __read_mostly __attribute__((__section__(".data..read_mostly"))) -/* Read-only memory is marked before mark_rodata_ro() is called. */ -#define __ro_after_init __read_mostly - #endif diff --git a/arch/s390/include/asm/sections.h b/arch/s390/include/asm/sections.h index fbd9116eb17b..5ce29fe100ba 100644 --- a/arch/s390/include/asm/sections.h +++ b/arch/s390/include/asm/sections.h @@ -4,5 +4,6 @@ #include extern char _eshared[], _ehead[]; +extern char __start_ro_after_init[], __end_ro_after_init[]; #endif diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 0656f7cc7fb4..429bfd111961 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -11,6 +11,9 @@ */ #define BSS_FIRST_SECTIONS *(.bss..swapper_pg_dir) +/* Handle ro_after_init data on our own. */ +#define RO_AFTER_INIT_DATA + #include OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390") @@ -56,7 +59,14 @@ SECTIONS _eshared = .; /* End of shareable data */ _sdata = .; /* Start of data section */ - EXCEPTION_TABLE(16) :data + . = ALIGN(PAGE_SIZE); + __start_ro_after_init = .; + .data..ro_after_init : { + *(.data..ro_after_init) + } + EXCEPTION_TABLE(16) + . = ALIGN(PAGE_SIZE); + __end_ro_after_init = .; RW_DATA_SECTION(0x100, PAGE_SIZE, THREAD_SIZE) diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 44db60d9e519..c1402b7d2103 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -111,9 +111,10 @@ void __init paging_init(void) void mark_rodata_ro(void) { - /* Text and rodata are already protected. Nothing to do here. */ - pr_info("Write protecting the kernel read-only data: %luk\n", - ((unsigned long)&_eshared - (unsigned long)&_stext) >> 10); + unsigned long size = __end_ro_after_init - __start_ro_after_init; + + set_memory_ro((unsigned long)__start_ro_after_init, size >> PAGE_SHIFT); + pr_info("Write protected read-only-after-init data: %luk\n", size >> 10); } void __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: */ void __init vmem_map_init(void) { - unsigned long ro_start, ro_end; + unsigned long size = _eshared - _stext; struct memblock_region *reg; for_each_memblock(memory, reg) vmem_add_mem(reg->base, reg->size); - ro_start = PFN_ALIGN((unsigned long)&_stext); - ro_end = (unsigned long)&_eshared & PAGE_MASK; - set_memory_ro(ro_start, (ro_end - ro_start) >> PAGE_SHIFT); + set_memory_ro((unsigned long)_stext, size >> PAGE_SHIFT); + pr_info("Write protected kernel read-only data: %luk\n", size >> 10); } /* -- 2.6.6