forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 <prudo@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
- Loading branch information
Philipp Rudo
authored and
Martin Schwidefsky
committed
Apr 16, 2018
1 parent
15ceb8c
commit 840798a
Showing
7 changed files
with
198 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Copyright IBM Corp. 2018 | ||
* | ||
* Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | ||
*/ | ||
|
||
#ifndef _S390_PURGATORY_H_ | ||
#define _S390_PURGATORY_H_ | ||
#ifndef __ASSEMBLY__ | ||
|
||
#include <linux/purgatory.h> | ||
|
||
int verify_sha256_digest(void); | ||
|
||
#endif /* __ASSEMBLY__ */ | ||
#endif /* _S390_PURGATORY_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += kexec-purgatory.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* SPDX-License-Identifier: GPL-2.0 */ | ||
/* | ||
* Purgatory setup code | ||
* | ||
* Copyright IBM Corp. 2018 | ||
* | ||
* Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | ||
*/ | ||
|
||
#include <linux/linkage.h> | ||
#include <asm/asm-offsets.h> | ||
#include <asm/page.h> | ||
#include <asm/sigp.h> | ||
|
||
/* 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: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* | ||
* Purgatory code running between two kernels. | ||
* | ||
* Copyright IBM Corp. 2018 | ||
* | ||
* Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com> | ||
*/ | ||
|
||
#include <linux/kexec.h> | ||
#include <linux/sha256.h> | ||
#include <linux/string.h> | ||
#include <asm/purgatory.h> | ||
|
||
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; | ||
} |