Received: by 10.223.185.116 with SMTP id b49csp2109003wrg; Mon, 12 Feb 2018 04:34:45 -0800 (PST) X-Google-Smtp-Source: AH8x224MQo9ioXBF2rfxGzi3KLm5KcUcepQP0OFygP1yi5mbGzrCyOeDPYAHG219Gfj/wEl41UJc X-Received: by 2002:a17:902:8607:: with SMTP id f7-v6mr10695592plo.273.1518438884976; Mon, 12 Feb 2018 04:34:44 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518438884; cv=none; d=google.com; s=arc-20160816; b=xgyfimdXoxjW4x1CL29kb79tEFWFAP2XEbVj3c73moVmf2oMmkRnC8gefzKkXFGqyH KHZ4YGeUfAp8l89CGKhm8T0SpiKqby5gSviuUar3WlP+wQgeYU219CYo0TOOw84mO6rc CtVHFzJUWI7UNlsDICGCn1B6C7ajBj2Su+E7A7eQITjUebxIsUlbMxCbZFNRNP8ApGsm //u9TraXKzwVrtiZqJ4pRoQPT0DCjvSUShsWweGkunzv7XpiF5YTMBTB1hQW81iPs669 01njcmFgbHvtYkSGypZDtVBnFXpQeZ7KicA9k2Prp+It2iPzKXcSfJSr7ORhD0fTzoCX Pklg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:references:in-reply-to:date :subject:cc:to:from:arc-authentication-results; bh=+wraSUE3QqSy0r51XHCdelpSWrE26ig+OMAMZhrbP3I=; b=yCoifxMEpsJRHXLMfcuKktTBbk1wzRkLtK2fuWwpXR1+b8WMEJmAWneubix8xTjUGR LZjEV2k5DSrsxqVHSQeyRTk3epGIJJPtTLiSjVxPIt5yHbKWs1GgQVEBqx0BhZkxhXnO w5UOLQA8wQbWcZ6zXH8N8oO7v5JLGmHXm6dUAT5nnbGYPG3d6UombJnhefi0GmEmlODA Vn5byHZidvyjrgknnQGTFD8NGGt/bEj4H7ty4BGNks7H0Ke5Wsx1q++TR9egHYZeQ2dx sQpFNtUR9sNV1TYU0pumcQxujumb3/YOb4HIOXL/PvVvigVGAlpDk/yE4llszzV60Ess Kw4A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p1-v6si5787737plo.170.2018.02.12.04.34.31; Mon, 12 Feb 2018 04:34:44 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=ibm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933564AbeBLKIZ (ORCPT + 99 others); Mon, 12 Feb 2018 05:08:25 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:49466 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933542AbeBLKIT (ORCPT ); Mon, 12 Feb 2018 05:08:19 -0500 Received: from pps.filterd (m0098399.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w1CA7c69103054 for ; Mon, 12 Feb 2018 05:08:18 -0500 Received: from e06smtp14.uk.ibm.com (e06smtp14.uk.ibm.com [195.75.94.110]) by mx0a-001b2d01.pphosted.com with ESMTP id 2g30fv88tm-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Mon, 12 Feb 2018 05:08:18 -0500 Received: from localhost by e06smtp14.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 12 Feb 2018 10:08:16 -0000 Received: from b06cxnps4075.portsmouth.uk.ibm.com (9.149.109.197) by e06smtp14.uk.ibm.com (192.168.101.144) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Mon, 12 Feb 2018 10:08:13 -0000 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps4075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w1CA8DIB36831324; Mon, 12 Feb 2018 10:08:13 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DA244AE053; Mon, 12 Feb 2018 09:59:18 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 81224AE056; Mon, 12 Feb 2018 09:59:18 +0000 (GMT) Received: from tuxmaker.boeblingen.de.ibm.com (unknown [9.152.85.9]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTPS; Mon, 12 Feb 2018 09:59:18 +0000 (GMT) From: Philipp Rudo To: kexec@lists.infradead.org, linux-s390@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Eric Biederman , Vivek Goyal , Michael Ellerman , Thiago Jung Bauermann , Martin Schwidefsky , Heiko Carstens , Andrew Morton , x86@kernel.org Subject: [PATCH 13/17] s390/kexec_file: Add purgatory Date: Mon, 12 Feb 2018 11:07:50 +0100 X-Mailer: git-send-email 2.13.5 In-Reply-To: <20180212100754.55121-1-prudo@linux.vnet.ibm.com> References: <20180212100754.55121-1-prudo@linux.vnet.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18021210-0016-0000-0000-00000521D431 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18021210-0017-0000-0000-0000285E9619 Message-Id: <20180212100754.55121-14-prudo@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2018-02-12_05:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=0 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1802120131 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The common code expects the architecture to have a purgatory that runs between the two kernels. Add it now. For simplicity first skip crash support. Signed-off-by: Philipp Rudo --- arch/s390/Kbuild | 1 + arch/s390/include/asm/purgatory.h | 17 +++++++ arch/s390/kernel/asm-offsets.c | 5 ++ arch/s390/purgatory/Makefile | 37 +++++++++++++++ arch/s390/purgatory/head.S | 96 +++++++++++++++++++++++++++++++++++++++ arch/s390/purgatory/purgatory.c | 38 ++++++++++++++++ 6 files changed, 194 insertions(+) create mode 100644 arch/s390/include/asm/purgatory.h create mode 100644 arch/s390/purgatory/Makefile create mode 100644 arch/s390/purgatory/head.S create mode 100644 arch/s390/purgatory/purgatory.c diff --git a/arch/s390/Kbuild b/arch/s390/Kbuild index 9fdff3fe1a42..091f14bc9af0 100644 --- a/arch/s390/Kbuild +++ b/arch/s390/Kbuild @@ -8,3 +8,4 @@ obj-$(CONFIG_APPLDATA_BASE) += appldata/ obj-y += net/ obj-$(CONFIG_PCI) += pci/ obj-$(CONFIG_NUMA) += numa/ +obj-y += purgatory/ diff --git a/arch/s390/include/asm/purgatory.h b/arch/s390/include/asm/purgatory.h new file mode 100644 index 000000000000..e297bcfc476f --- /dev/null +++ b/arch/s390/include/asm/purgatory.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright IBM Corp. 2018 + * + * Author(s): Philipp Rudo + */ + +#ifndef _S390_PURGATORY_H_ +#define _S390_PURGATORY_H_ +#ifndef __ASSEMBLY__ + +#include + +int verify_sha256_digest(void); + +#endif /* __ASSEMBLY__ */ +#endif /* _S390_PURGATORY_H_ */ diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 587b195b588d..a22b478de567 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -203,5 +204,9 @@ int main(void) OFFSET(__GMAP_ASCE, gmap, asce); OFFSET(__SIE_PROG0C, kvm_s390_sie_block, prog0c); OFFSET(__SIE_PROG20, kvm_s390_sie_block, prog20); + /* kexec_sha_region */ + OFFSET(__KEXEC_SHA_REGION_START, kexec_sha_region, start); + OFFSET(__KEXEC_SHA_REGION_LEN, kexec_sha_region, len); + DEFINE(__KEXEC_SHA_REGION_SIZE, sizeof(struct kexec_sha_region)); return 0; } diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile new file mode 100644 index 000000000000..c4b405d9c713 --- /dev/null +++ b/arch/s390/purgatory/Makefile @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0 + +OBJECT_FILES_NON_STANDARD := y + +purgatory-y := head.o purgatory.o string.o sha256.o mem.o + +targets += $(purgatory-y) purgatory.ro kexec-purgatory.c +PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y)) + +$(obj)/sha256.o: $(srctree)/lib/sha256.c + $(call if_changed_rule,cc_o_c) + +$(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S + $(call if_changed_rule,as_o_S) + +$(obj)/string.o: $(srctree)/arch/s390/lib/string.c + $(call if_changed_rule,cc_o_c) + +LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib +LDFLAGS_purgatory.ro += -z nodefaultlib +KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes +KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare +KBUILD_CFLAGS += -fno-zero-initialized-in-bss -fno-builtin -ffreestanding +KBUILD_CFLAGS += -c -MD -Os -m64 +KBUILD_CFLAGS += $(call cc-option,-fno-PIE) + +$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE + $(call if_changed,ld) + +CMD_BIN2C = $(objtree)/scripts/basic/bin2c +quiet_cmd_bin2c = BIN2C $@ + cmd_bin2c = $(CMD_BIN2C) kexec_purgatory < $< > $@ + +$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro FORCE + $(call if_changed,bin2c) + +obj-y += kexec-purgatory.o diff --git a/arch/s390/purgatory/head.S b/arch/s390/purgatory/head.S new file mode 100644 index 000000000000..8735409d0280 --- /dev/null +++ b/arch/s390/purgatory/head.S @@ -0,0 +1,96 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Purgatory setup code + * + * Copyright IBM Corp. 2018 + * + * Author(s): Philipp Rudo + */ + +#include +#include +#include +#include + +/* The purgatory is the code running between two kernels. It's main purpose + * is to verify that the next kernel was not corrupted after load and to + * start it. + */ + +.macro START_NEXT_KERNEL base + lg %r4,kernel_entry-\base(%r13) + lg %r5,load_psw_mask-\base(%r13) + ogr %r4,%r5 + stg %r4,0(%r0) + + xgr %r0,%r0 + diag %r0,%r0,0x308 +.endm + +.text +.align PAGE_SIZE +ENTRY(purgatory_start) + /* The purgatory might be called after a diag308 so better set + * architecture and addressing mode. + */ + lhi %r1,1 + sigp %r1,%r0,SIGP_SET_ARCHITECTURE + sam64 + + larl %r5,gprregs + stmg %r6,%r15,0(%r5) + + basr %r13,0 +.base_crash: + + /* Setup stack */ + larl %r15,purgatory_end + aghi %r15,-160 + +.do_checksum_verification: + brasl %r14,verify_sha256_digest + + cghi %r2,0 /* checksum match */ + jne .disabled_wait + + /* start normal kernel */ + START_NEXT_KERNEL .base_crash + +.disabled_wait: + lpswe disabled_wait_psw-.base_crash(%r13) + + +load_psw_mask: + .long 0x00080000,0x80000000 + + .align 8 +disabled_wait_psw: + .quad 0x0002000180000000 + .quad 0x0000000000000000 + .do_checksum_verification + +gprregs: + .rept 10 + .quad 0 + .endr + +purgatory_sha256_digest: + .global purgatory_sha256_digest + .rept 32 /* SHA256_DIGEST_SIZE */ + .byte 0 + .endr + +purgatory_sha_regions: + .global purgatory_sha_regions + .rept 16 * __KEXEC_SHA_REGION_SIZE /* KEXEC_SEGMENTS_MAX */ + .byte 0 + .endr + +kernel_entry: + .global kernel_entry + .quad 0 + + .align PAGE_SIZE +stack: + .skip PAGE_SIZE + .align PAGE_SIZE +purgatory_end: diff --git a/arch/s390/purgatory/purgatory.c b/arch/s390/purgatory/purgatory.c new file mode 100644 index 000000000000..fec67b58b8be --- /dev/null +++ b/arch/s390/purgatory/purgatory.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Purgatory code running between two kernels. + * + * Copyright IBM Corp. 2018 + * + * Author(s): Philipp Rudo + */ + +#include +#include +#include +#include + +struct kexec_sha_region purgatory_sha_regions[KEXEC_SEGMENT_MAX]; +u8 purgatory_sha256_digest[SHA256_DIGEST_SIZE]; + +u64 kernel_entry; + +int verify_sha256_digest(void) +{ + struct kexec_sha_region *ptr, *end; + u8 digest[SHA256_DIGEST_SIZE]; + struct sha256_state sctx; + + sha256_init(&sctx); + end = purgatory_sha_regions + ARRAY_SIZE(purgatory_sha_regions); + + for (ptr = purgatory_sha_regions; ptr < end; ptr++) + sha256_update(&sctx, (uint8_t *)(ptr->start), ptr->len); + + sha256_final(&sctx, digest); + + if (memcmp(digest, purgatory_sha256_digest, sizeof(digest))) + return 1; + + return 0; +} -- 2.13.5