Unverified Commit 736e30af authored by Li Zhengyu's avatar Li Zhengyu Committed by Palmer Dabbelt
Browse files

RISC-V: Add purgatory



This patch adds purgatory, the name and concept have been taken
from kexec-tools. Purgatory runs between two kernels, and do
verify sha256 hash to ensure the kernel to jump to is fine and
has not been corrupted after loading. Makefile is modified based
on x86 platform.

Signed-off-by: default avatarLi Zhengyu <lizhengyu3@huawei.com>
Link: https://lore.kernel.org/r/20220408100914.150110-6-lizhengyu3@huawei.com


Signed-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 8acea455
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3,5 +3,7 @@
obj-y += kernel/ mm/ net/
obj-$(CONFIG_BUILTIN_DTB) += boot/dts/

obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += purgatory/

# for cleaning
subdir- += boot
+6 −0
Original line number Diff line number Diff line
@@ -397,6 +397,12 @@ config KEXEC_FILE

	  If you don't know what to do here, say Y.

config ARCH_HAS_KEXEC_PURGATORY
	def_bool KEXEC_FILE
	select BUILD_BIN2C
	depends on CRYPTO=y
	depends on CRYPTO_SHA256=y

config CRASH_DUMP
	bool "Build kdump crash kernel"
	help
+4 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0-only
purgatory.chk
purgatory.ro
kexec-purgatory.c
+95 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0
OBJECT_FILES_NON_STANDARD := y

purgatory-y := purgatory.o sha256.o entry.o string.o ctype.o memcpy.o memset.o

targets += $(purgatory-y)
PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))

$(obj)/string.o: $(srctree)/lib/string.c FORCE
	$(call if_changed_rule,cc_o_c)

$(obj)/ctype.o: $(srctree)/lib/ctype.c FORCE
	$(call if_changed_rule,cc_o_c)

$(obj)/memcpy.o: $(srctree)/arch/riscv/lib/memcpy.S FORCE
	$(call if_changed_rule,as_o_S)

$(obj)/memset.o: $(srctree)/arch/riscv/lib/memset.S FORCE
	$(call if_changed_rule,as_o_S)

$(obj)/sha256.o: $(srctree)/lib/crypto/sha256.c FORCE
	$(call if_changed_rule,cc_o_c)

CFLAGS_sha256.o := -D__DISABLE_EXPORTS
CFLAGS_string.o := -D__DISABLE_EXPORTS
CFLAGS_ctype.o := -D__DISABLE_EXPORTS

# When linking purgatory.ro with -r unresolved symbols are not checked,
# also link a purgatory.chk binary without -r to check for unresolved symbols.
PURGATORY_LDFLAGS := -e purgatory_start -z nodefaultlib
LDFLAGS_purgatory.ro := -r $(PURGATORY_LDFLAGS)
LDFLAGS_purgatory.chk := $(PURGATORY_LDFLAGS)
targets += purgatory.ro purgatory.chk

# Sanitizer, etc. runtimes are unavailable and cannot be linked here.
GCOV_PROFILE	:= n
KASAN_SANITIZE	:= n
UBSAN_SANITIZE	:= n
KCSAN_SANITIZE	:= n
KCOV_INSTRUMENT := n

# These are adjustments to the compiler flags used for objects that
# make up the standalone purgatory.ro

PURGATORY_CFLAGS_REMOVE := -mcmodel=kernel
PURGATORY_CFLAGS := -mcmodel=medany -ffreestanding -fno-zero-initialized-in-bss
PURGATORY_CFLAGS += $(DISABLE_STACKLEAK_PLUGIN) -DDISABLE_BRANCH_PROFILING
PURGATORY_CFLAGS += -fno-stack-protector -g0

# Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
# in turn leaves some undefined symbols like __fentry__ in purgatory and not
# sure how to relocate those.
ifdef CONFIG_FUNCTION_TRACER
PURGATORY_CFLAGS_REMOVE		+= $(CC_FLAGS_FTRACE)
endif

ifdef CONFIG_STACKPROTECTOR
PURGATORY_CFLAGS_REMOVE		+= -fstack-protector
endif

ifdef CONFIG_STACKPROTECTOR_STRONG
PURGATORY_CFLAGS_REMOVE		+= -fstack-protector-strong
endif

CFLAGS_REMOVE_purgatory.o	+= $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_purgatory.o		+= $(PURGATORY_CFLAGS)

CFLAGS_REMOVE_sha256.o		+= $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_sha256.o			+= $(PURGATORY_CFLAGS)

CFLAGS_REMOVE_string.o		+= $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_string.o			+= $(PURGATORY_CFLAGS)

CFLAGS_REMOVE_ctype.o		+= $(PURGATORY_CFLAGS_REMOVE)
CFLAGS_ctype.o			+= $(PURGATORY_CFLAGS)

AFLAGS_REMOVE_entry.o		+= -Wa,-gdwarf-2
AFLAGS_REMOVE_memcpy.o		+= -Wa,-gdwarf-2
AFLAGS_REMOVE_memset.o		+= -Wa,-gdwarf-2

$(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
		$(call if_changed,ld)

$(obj)/purgatory.chk: $(obj)/purgatory.ro FORCE
		$(call if_changed,ld)

targets += kexec-purgatory.c

quiet_cmd_bin2c = BIN2C   $@
      cmd_bin2c = $(objtree)/scripts/bin2c kexec_purgatory < $< > $@

$(obj)/kexec-purgatory.c: $(obj)/purgatory.ro $(obj)/purgatory.chk FORCE
	$(call if_changed,bin2c)

obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY)	+= kexec-purgatory.o
+47 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * purgatory: Runs between two kernels
 *
 * Copyright (C) 2022 Huawei Technologies Co, Ltd.
 *
 * Author: Li Zhengyu (lizhengyu3@huawei.com)
 *
 */

.macro	size, sym:req
	.size \sym, . - \sym
.endm

.text

.globl purgatory_start
purgatory_start:

	lla	sp, .Lstack
	mv	s0, a0	/* The hartid of the current hart */
	mv	s1, a1	/* Phys address of the FDT image */

	jal	purgatory

	/* Start new image. */
	mv	a0, s0
	mv	a1, s1
	ld	a2, riscv_kernel_entry
	jr	a2

size purgatory_start

.align 4
	.rept	256
	.quad	0
	.endr
.Lstack:

.data

.globl riscv_kernel_entry
riscv_kernel_entry:
	.quad	0
size riscv_kernel_entry

.end
Loading