Commit c2d94c52 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 fixes and kexec-file-load from Martin Schwidefsky:
 "After the common code kexec patches went in via Andrew we can now push
  the architecture parts to implement the kexec-file-load system call.

  Plus a few more bug fixes and cleanups, this includes an update to the
  default configurations"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/signal: cleanup uapi struct sigaction
  s390: rename default_defconfig to debug_defconfig
  s390: remove gcov defconfig
  s390: update defconfig
  s390: add support for IBM z14 Model ZR1
  s390: remove couple of duplicate includes
  s390/boot: remove unused COMPILE_VERSION and ccflags-y
  s390/nospec: include cpu.h
  s390/decompressor: Ignore file vmlinux.bin.full
  s390/kexec_file: add generated files to .gitignore
  s390/Kconfig: Move kexec config options to "Processor type and features"
  s390/kexec_file: Add ELF loader
  s390/kexec_file: Add crash support to image loader
  s390/kexec_file: Add image loader
  s390/kexec_file: Add kexec_file_load system call
  s390/kexec_file: Add purgatory
  s390/kexec_file: Prepare setup.h for kexec_file_load
  s390/smsgiucv: disable SMSG on module unload
  s390/sclp: avoid potential usage of uninitialized value
parents 87ef1202 fae76491
......@@ -8,3 +8,4 @@ obj-$(CONFIG_APPLDATA_BASE) += appldata/
obj-y += net/
obj-$(CONFIG_PCI) += pci/
obj-$(CONFIG_NUMA) += numa/
obj-$(CONFIG_ARCH_HAS_KEXEC_PURGATORY) += purgatory/
......@@ -47,10 +47,6 @@ config PGSTE
config ARCH_SUPPORTS_DEBUG_PAGEALLOC
def_bool y
config KEXEC
def_bool y
select KEXEC_CORE
config AUDIT_ARCH
def_bool y
......@@ -290,12 +286,12 @@ config MARCH_Z13
older machines.
config MARCH_Z14
bool "IBM z14"
bool "IBM z14 ZR1 and z14"
select HAVE_MARCH_Z14_FEATURES
help
Select this to enable optimizations for IBM z14 (3906 series).
The kernel will be slightly faster but will not work on older
machines.
Select this to enable optimizations for IBM z14 ZR1 and z14 (3907
and 3906 series). The kernel will be slightly faster but will not
work on older machines.
endchoice
......@@ -525,6 +521,26 @@ source kernel/Kconfig.preempt
source kernel/Kconfig.hz
config KEXEC
def_bool y
select KEXEC_CORE
config KEXEC_FILE
bool "kexec file based system call"
select KEXEC_CORE
select BUILD_BIN2C
depends on CRYPTO
depends on CRYPTO_SHA256
depends on CRYPTO_SHA256_S390
help
Enable the kexec file based system call. In contrast to the normal
kexec system call this system call takes file descriptors for the
kernel and initramfs as arguments.
config ARCH_HAS_KEXEC_PURGATORY
def_bool y
depends on KEXEC_FILE
config ARCH_RANDOM
def_bool y
prompt "s390 architectural random number generation API"
......
......@@ -3,12 +3,6 @@
# Makefile for the linux s390-specific parts of the memory manager.
#
COMPILE_VERSION := __linux_compile_version_id__`hostname | \
tr -c '[0-9A-Za-z]' '_'`__`date | \
tr -c '[0-9A-Za-z]' '_'`_t
ccflags-y := -DCOMPILE_VERSION=$(COMPILE_VERSION) -gstabs -I.
targets := image
targets += bzImage
subdir- := compressed
......
sizes.h
vmlinux
vmlinux.lds
vmlinux.bin.full
......@@ -24,13 +24,13 @@ CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BPF_SYSCALL=y
CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set
......@@ -59,10 +59,11 @@ CONFIG_CFQ_GROUP_IOSCHED=y
CONFIG_DEFAULT_DEADLINE=y
CONFIG_LIVEPATCH=y
CONFIG_TUNE_ZEC12=y
CONFIG_NR_CPUS=256
CONFIG_NR_CPUS=512
CONFIG_NUMA=y
CONFIG_PREEMPT=y
CONFIG_HZ_100=y
CONFIG_KEXEC_FILE=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
......@@ -305,7 +306,6 @@ CONFIG_IP6_NF_SECURITY=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NET_SCTPPROBE=m
CONFIG_RDS=m
CONFIG_RDS_RDMA=m
CONFIG_RDS_TCP=m
......@@ -364,11 +364,11 @@ CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_NET_ACT_CSUM=m
CONFIG_DNS_RESOLVER=y
CONFIG_OPENVSWITCH=m
CONFIG_NETLINK_DIAG=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_BPF_JIT=y
CONFIG_NET_PKTGEN=m
CONFIG_NET_TCPPROBE=m
CONFIG_DEVTMPFS=y
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=0
......@@ -380,9 +380,9 @@ CONFIG_BLK_DEV_DRBD=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_RAM_DAX=y
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_RBD=m
CONFIG_BLK_DEV_NVME=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_GENWQE=m
CONFIG_RAID_ATTRS=m
......@@ -461,6 +461,7 @@ CONFIG_PPTP=m
CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
......@@ -474,6 +475,9 @@ CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_DIAG288_WATCHDOG=m
CONFIG_DRM=y
CONFIG_DRM_VIRTIO_GPU=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_INFINIBAND=m
......@@ -482,7 +486,9 @@ CONFIG_MLX4_INFINIBAND=m
CONFIG_MLX5_INFINIBAND=m
CONFIG_VFIO=m
CONFIG_VFIO_PCI=m
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_INPUT=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
......@@ -641,6 +647,8 @@ CONFIG_ATOMIC64_SELFTEST=y
CONFIG_TEST_BPF=m
CONFIG_BUG_ON_DATA_CORRUPTION=y
CONFIG_S390_PTDUMP=y
CONFIG_PERSISTENT_KEYRINGS=y
CONFIG_BIG_KEYS=y
CONFIG_ENCRYPTED_KEYS=m
CONFIG_SECURITY=y
CONFIG_SECURITY_NETWORK=y
......@@ -649,17 +657,20 @@ CONFIG_SECURITY_SELINUX=y
CONFIG_SECURITY_SELINUX_BOOTPARAM=y
CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
CONFIG_IMA=y
CONFIG_IMA_DEFAULT_HASH_SHA256=y
CONFIG_IMA_WRITE_POLICY=y
CONFIG_IMA_APPRAISE=y
CONFIG_CRYPTO_RSA=m
CONFIG_CRYPTO_DH=m
CONFIG_CRYPTO_ECDH=m
CONFIG_CRYPTO_USER=m
# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
CONFIG_CRYPTO_PCRYPT=m
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_MCRYPTD=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_CHACHA20POLY1305=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
......@@ -707,9 +718,8 @@ CONFIG_CRYPTO_DES_S390=m
CONFIG_CRYPTO_AES_S390=m
CONFIG_CRYPTO_GHASH_S390=m
CONFIG_CRYPTO_CRC32_S390=y
CONFIG_ASYMMETRIC_KEY_TYPE=y
CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=m
CONFIG_X509_CERTIFICATE_PARSER=m
CONFIG_PKCS7_MESSAGE_PARSER=y
CONFIG_SYSTEM_TRUSTED_KEYRING=y
CONFIG_CRC7=m
CONFIG_CRC8=m
CONFIG_RANDOM32_SELFTEST=y
......
This diff is collapsed.
......@@ -25,13 +25,13 @@ CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BPF_SYSCALL=y
CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set
......@@ -45,6 +45,8 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_MODULE_SIG=y
CONFIG_MODULE_SIG_SHA256=y
CONFIG_BLK_DEV_INTEGRITY=y
CONFIG_BLK_DEV_THROTTLING=y
CONFIG_BLK_WBT=y
......@@ -62,6 +64,7 @@ CONFIG_TUNE_ZEC12=y
CONFIG_NR_CPUS=512
CONFIG_NUMA=y
CONFIG_HZ_100=y
CONFIG_KEXEC_FILE=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
......@@ -301,7 +304,6 @@ CONFIG_IP6_NF_SECURITY=m
CONFIG_IP6_NF_NAT=m
CONFIG_IP6_NF_TARGET_MASQUERADE=m
CONFIG_NF_TABLES_BRIDGE=m
CONFIG_NET_SCTPPROBE=m
CONFIG_RDS=m
CONFIG_RDS_RDMA=m
CONFIG_RDS_TCP=m
......@@ -359,11 +361,11 @@ CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_NET_ACT_CSUM=m
CONFIG_DNS_RESOLVER=y
CONFIG_OPENVSWITCH=m
CONFIG_NETLINK_DIAG=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_BPF_JIT=y
CONFIG_NET_PKTGEN=m
CONFIG_NET_TCPPROBE=m
CONFIG_DEVTMPFS=y
CONFIG_DMA_CMA=y
CONFIG_CMA_SIZE_MBYTES=0
......@@ -375,8 +377,9 @@ CONFIG_BLK_DEV_DRBD=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_BLK_DEV_RAM_DAX=y
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_RBD=m
CONFIG_BLK_DEV_NVME=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_GENWQE=m
CONFIG_RAID_ATTRS=m
......@@ -455,6 +458,7 @@ CONFIG_PPTP=m
CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_SERIO is not set
......@@ -468,6 +472,9 @@ CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_SOFT_WATCHDOG=m
CONFIG_DIAG288_WATCHDOG=m
CONFIG_DRM=y
CONFIG_DRM_VIRTIO_GPU=y
CONFIG_FRAMEBUFFER_CONSOLE=y
# CONFIG_HID is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_INFINIBAND=m
......@@ -476,7 +483,9 @@ CONFIG_MLX4_INFINIBAND=m
CONFIG_MLX5_INFINIBAND=m
CONFIG_VFIO=m
CONFIG_VFIO_PCI=m
CONFIG_VIRTIO_PCI=m
CONFIG_VIRTIO_BALLOON=m
CONFIG_VIRTIO_INPUT=y
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
......@@ -507,7 +516,6 @@ CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=y
CONFIG_CUSE=m
CONFIG_OVERLAY_FS=m
CONFIG_OVERLAY_FS_REDIRECT_DIR=y
CONFIG_FSCACHE=m
CONFIG_CACHEFILES=m
CONFIG_ISO9660_FS=y
......@@ -592,8 +600,10 @@ CONFIG_SECURITY_SELINUX_DISABLE=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
CONFIG_IMA=y
CONFIG_IMA_DEFAULT_HASH_SHA256=y
CONFIG_IMA_WRITE_POLICY=y
CONFIG_IMA_APPRAISE=y
CONFIG_CRYPTO_FIPS=y
CONFIG_CRYPTO_DH=m
CONFIG_CRYPTO_ECDH=m
CONFIG_CRYPTO_USER=m
......
......@@ -8,6 +8,7 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
# CONFIG_CPU_ISOLATION is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
......@@ -23,12 +24,12 @@ CONFIG_CPUSETS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y
# CONFIG_SYSFS_SYSCALL is not set
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_BPF_SYSCALL=y
CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set
......@@ -47,6 +48,7 @@ CONFIG_LIVEPATCH=y
CONFIG_NR_CPUS=256
CONFIG_NUMA=y
CONFIG_HZ_100=y
CONFIG_KEXEC_FILE=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
CONFIG_KSM=y
......@@ -129,10 +131,13 @@ CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_VIRTIO_NET=y
# CONFIG_NET_VENDOR_ALACRITECH is not set
# CONFIG_NET_VENDOR_CORTINA is not set
# CONFIG_NET_VENDOR_SOLARFLARE is not set
# CONFIG_NET_VENDOR_SOCIONEXT is not set
# CONFIG_NET_VENDOR_SYNOPSYS is not set
# CONFIG_INPUT is not set
# CONFIG_SERIO is not set
# CONFIG_VT is not set
CONFIG_DEVKMEM=y
CONFIG_RAW_DRIVER=m
CONFIG_VIRTIO_BALLOON=y
......@@ -177,13 +182,15 @@ CONFIG_TRACER_SNAPSHOT_PER_CPU_SWAP=y
CONFIG_STACK_TRACER=y
CONFIG_BLK_DEV_IO_TRACE=y
CONFIG_FUNCTION_PROFILER=y
CONFIG_KPROBES_SANITY_TEST=y
# CONFIG_RUNTIME_TESTING_MENU is not set
CONFIG_S390_PTDUMP=y
CONFIG_CRYPTO_CRYPTD=m
CONFIG_CRYPTO_AUTHENC=m
CONFIG_CRYPTO_TEST=m
CONFIG_CRYPTO_CCM=m
CONFIG_CRYPTO_GCM=m
CONFIG_CRYPTO_CBC=y
CONFIG_CRYPTO_CFB=m
CONFIG_CRYPTO_CTS=m
CONFIG_CRYPTO_LRW=m
CONFIG_CRYPTO_PCBC=m
......@@ -213,6 +220,8 @@ CONFIG_CRYPTO_KHAZAD=m
CONFIG_CRYPTO_SALSA20=m
CONFIG_CRYPTO_SEED=m
CONFIG_CRYPTO_SERPENT=m
CONFIG_CRYPTO_SM4=m
CONFIG_CRYPTO_SPECK=m
CONFIG_CRYPTO_TEA=m
CONFIG_CRYPTO_TWOFISH=m
CONFIG_CRYPTO_DEFLATE=m
......
......@@ -46,4 +46,27 @@
static inline void crash_setup_regs(struct pt_regs *newregs,
struct pt_regs *oldregs) { }
struct kimage;
struct s390_load_data {
/* Pointer to the kernel buffer. Used to register cmdline etc.. */
void *kernel_buf;
/* Total size of loaded segments in memory. Used as an offset. */
size_t memsz;
/* Load address of initrd. Used to register INITRD_START in kernel. */
unsigned long initrd_load_addr;
};
int kexec_file_add_purgatory(struct kimage *image,
struct s390_load_data *data);
int kexec_file_add_initrd(struct kimage *image,
struct s390_load_data *data,
char *initrd, unsigned long initrd_len);
int *kexec_file_update_kernel(struct kimage *iamge,
struct s390_load_data *data);
extern const struct kexec_file_ops s390_kexec_image_ops;
extern const struct kexec_file_ops s390_kexec_elf_ops;
#endif /*_S390_KEXEC_H */
/* 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_ */
/* SPDX-License-Identifier: GPL-2.0 */
/*
* S390 version
* Copyright IBM Corp. 1999, 2010
* Copyright IBM Corp. 1999, 2017
*/
#ifndef _ASM_S390_SETUP_H
#define _ASM_S390_SETUP_H
......@@ -37,17 +37,31 @@
#define LPP_MAGIC _BITUL(31)
#define LPP_PID_MASK _AC(0xffffffff, UL)
/* Offsets to entry points in kernel/head.S */
#define STARTUP_NORMAL_OFFSET 0x10000
#define STARTUP_KDUMP_OFFSET 0x10010
/* Offsets to parameters in kernel/head.S */
#define IPL_DEVICE_OFFSET 0x10400
#define INITRD_START_OFFSET 0x10408
#define INITRD_SIZE_OFFSET 0x10410
#define OLDMEM_BASE_OFFSET 0x10418
#define OLDMEM_SIZE_OFFSET 0x10420
#define COMMAND_LINE_OFFSET 0x10480
#ifndef __ASSEMBLY__
#include <asm/lowcore.h>
#include <asm/types.h>
#define IPL_DEVICE (*(unsigned long *) (0x10400))
#define INITRD_START (*(unsigned long *) (0x10408))
#define INITRD_SIZE (*(unsigned long *) (0x10410))
#define OLDMEM_BASE (*(unsigned long *) (0x10418))
#define OLDMEM_SIZE (*(unsigned long *) (0x10420))
#define COMMAND_LINE ((char *) (0x10480))
#define IPL_DEVICE (*(unsigned long *) (IPL_DEVICE_OFFSET))
#define INITRD_START (*(unsigned long *) (INITRD_START_OFFSET))
#define INITRD_SIZE (*(unsigned long *) (INITRD_SIZE_OFFSET))
#define OLDMEM_BASE (*(unsigned long *) (OLDMEM_BASE_OFFSET))
#define OLDMEM_SIZE (*(unsigned long *) (OLDMEM_SIZE_OFFSET))
#define COMMAND_LINE ((char *) (COMMAND_LINE_OFFSET))
extern int memory_end_set;
extern unsigned long memory_end;
......@@ -121,12 +135,12 @@ extern void (*_machine_power_off)(void);
#else /* __ASSEMBLY__ */
#define IPL_DEVICE 0x10400
#define INITRD_START 0x10408
#define INITRD_SIZE 0x10410
#define OLDMEM_BASE 0x10418
#define OLDMEM_SIZE 0x10420
#define COMMAND_LINE 0x10480
#define IPL_DEVICE (IPL_DEVICE_OFFSET)
#define INITRD_START (INITRD_START_OFFSET)
#define INITRD_SIZE (INITRD_SIZE_OFFSET)
#define OLDMEM_BASE (OLDMEM_BASE_OFFSET)
#define OLDMEM_SIZE (OLDMEM_SIZE_OFFSET)
#define COMMAND_LINE (COMMAND_LINE_OFFSET)
#endif /* __ASSEMBLY__ */
#endif /* _ASM_S390_SETUP_H */
......@@ -97,22 +97,31 @@ typedef unsigned long sigset_t;
#include <asm-generic/signal-defs.h>
#ifndef __KERNEL__
/* Here we must cater to libcs that poke about in kernel headers. */
/*
* There are two system calls in regard to sigaction, sys_rt_sigaction
* and sys_sigaction. Internally the kernel uses the struct old_sigaction
* for the older sys_sigaction system call, and the kernel version of the
* struct sigaction for the newer sys_rt_sigaction.
*
* The uapi definition for struct sigaction has made a strange distinction
* between 31-bit and 64-bit in the past. For 64-bit the uapi structure
* looks like the kernel struct sigaction, but for 31-bit it used to
* look like the kernel struct old_sigaction. That practically made the
* structure unusable for either system call. To get around this problem
* the glibc always had its own definitions for the sigaction structures.
*
* The current struct sigaction uapi definition below is suitable for the
* sys_rt_sigaction system call only.
*/
struct sigaction {
union {
__sighandler_t _sa_handler;
void (*_sa_sigaction)(int, struct siginfo *, void *);
} _u;
#ifndef __s390x__ /* lovely */
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
#else /* __s390x__ */
unsigned long sa_flags;
void (*sa_restorer)(void);
sigset_t sa_mask;
#endif /* __s390x__ */
};
#define sa_handler _u._sa_handler
......
......@@ -82,6 +82,9 @@ obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o
obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf.o perf_cpum_sf.o
obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o
......
......@@ -10,6 +10,7 @@
#include <linux/kbuild.h>
#include <linux/kvm_host.h>
#include <linux/sched.h>
#include <linux/purgatory.h>
#include <asm/idle.h>
#include <asm/vdso.h>
#include <asm/pgtable.h>
......@@ -204,5 +205,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;
}
......@@ -182,3 +182,4 @@ COMPAT_SYSCALL_WRAP6(copy_file_range, int, fd_in, loff_t __user *, off_in, int,
COMPAT_SYSCALL_WRAP2(s390_guarded_storage, int, command, struct gs_cb *, gs_cb);
COMPAT_SYSCALL_WRAP5(statx, int, dfd, const char __user *, path, unsigned, flags, unsigned, mask, struct statx __user *, buffer);
COMPAT_SYSCALL_WRAP4(s390_sthyi, unsigned long, code, void __user *, info, u64 __user *, rc, unsigned long, flags);
COMPAT_SYSCALL_WRAP5(kexec_file_load, int, kernel_fd, int, initrd_fd, unsigned long, cmdline_len, const char __user *, cmdline_ptr, unsigned long, flags)
// SPDX-License-Identifier: GPL-2.0
/*
* ELF loader for kexec_file_load system call.
*
* Copyright IBM Corp. 2018
*
* Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
*/
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kexec.h>
#include <asm/setup.h>
static int kexec_file_add_elf_kernel(struct kimage *image,
struct s390_load_data *data,
char *kernel, unsigned long kernel_len)
{
struct kexec_buf buf;
const Elf_Ehdr *ehdr;
const Elf_Phdr *phdr;
int i, ret;
ehdr = (Elf_Ehdr *)kernel;
buf.image = image;
phdr = (void *)ehdr + ehdr->e_phoff;
for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
if (phdr->p_type != PT_LOAD)
continue;
buf.buffer = kernel + phdr->p_offset;
buf.bufsz = phdr->p_filesz;
buf.mem = ALIGN(phdr->p_paddr, phdr->p_align);
buf.memsz = phdr->p_memsz;
if (phdr->p_paddr == 0) {
data->kernel_buf = buf.buffer;
data->memsz += STARTUP_NORMAL_OFFSET;
buf.buffer += STARTUP_NORMAL_OFFSET;
buf.bufsz -= STARTUP_NORMAL_OFFSET;
buf.mem += STARTUP_NORMAL_OFFSET;
buf.memsz -= STARTUP_NORMAL_OFFSET;
}
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
ret = kexec_add_buffer(&buf);
if (ret)
return ret;
data->memsz += buf.memsz;
}
return 0;
}
static void *s390_elf_load(struct kimage *image,
char *kernel, unsigned long kernel_len,
char *initrd, unsigned long initrd_len,
char *cmdline, unsigned long cmdline_len)
{
struct s390_load_data data = {0};
const Elf_Ehdr *ehdr;
const Elf_Phdr *phdr;
size_t size;
int i, ret;
/* image->fobs->probe already checked for valid ELF magic number. */
ehdr = (Elf_Ehdr *)kernel;
if (ehdr->e_type != ET_EXEC ||
ehdr->e_ident[EI_CLASS] != ELFCLASS64 ||
!elf_check_arch(ehdr))
return ERR_PTR(-EINVAL);
if (!ehdr->e_phnum || ehdr->e_phentsize != sizeof(Elf_Phdr))
return ERR_PTR(-EINVAL);
size = ehdr->e_ehsize + ehdr->e_phoff;
size += ehdr->e_phentsize * ehdr->e_phnum;
if (size > kernel_len)
return ERR_PTR(-EINVAL);
phdr = (void *)ehdr + ehdr->e_phoff;
size = ALIGN(size, phdr->p_align);
for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
if (phdr->p_type == PT_INTERP)
return ERR_PTR(-EINVAL);
if (phdr->p_offset > kernel_len)
return ERR_PTR(-EINVAL);
size += ALIGN(phdr->p_filesz, phdr->p_align);
}
if (size > kernel_len)
return ERR_PTR(-EINVAL);
ret = kexec_file_add_elf_kernel(image, &data, kernel, kernel_len);
if (ret)
return ERR_PTR(ret);
if (!data.memsz)
return ERR_PTR(-EINVAL);
if (initrd) {
ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
if (ret)
return ERR_PTR(ret);
}
ret = kexec_file_add_purgatory(image, &data);
if (ret)
return ERR_PTR(ret);
return kexec_file_update_kernel(image, &data);
}
static int s390_elf_probe(const char *buf, unsigned long len)
{
const Elf_Ehdr *ehdr;
if (len < sizeof(Elf_Ehdr))
return -ENOEXEC;
ehdr = (Elf_Ehdr *)buf;
/* Only check the ELF magic number here and do proper validity check
* in the loader. Any check here that fails would send the erroneous
* ELF file to the image loader that does not care what it gets.
* (Most likely) causing behavior not intended by the user.
*/
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0)
return -ENOEXEC;
return 0;
}
const struct kexec_file_ops s390_kexec_elf_ops = {
.probe = s390_elf_probe,
.load = s390_elf_load,
};
// SPDX-License-Identifier: GPL-2.0
/*
* Image loader for kexec_file_load system call.
*
* Copyright IBM Corp. 2018
*
* Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
*/
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kexec.h>
#include <asm/setup.h>
static int kexec_file_add_image_kernel(struct kimage *image,
struct s390_load_data *data,
char *kernel, unsigned long kernel_len)
{
struct kexec_buf buf;
int ret;
buf.image = image;
buf.buffer = kernel + STARTUP_NORMAL_OFFSET;
buf.bufsz = kernel_len - STARTUP_NORMAL_OFFSET;
buf.mem = STARTUP_NORMAL_OFFSET;
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
buf.memsz = buf.bufsz;
ret = kexec_add_buffer(&buf);
data->kernel_buf = kernel;
data->memsz += buf.memsz + STARTUP_NORMAL_OFFSET;
return ret;
}
static void *s390_image_load(struct kimage *image,
char *kernel, unsigned long kernel_len,
char *initrd, unsigned long initrd_len,
char *cmdline, unsigned long cmdline_len)
{
struct s390_load_data data = {0};
int ret;
ret = kexec_file_add_image_kernel(image, &data, kernel, kernel_len);
if (ret)
return ERR_PTR(ret);
if (initrd) {
ret = kexec_file_add_initrd(image, &data, initrd, initrd_len);
if (ret)
return ERR_PTR(ret);
}
ret = kexec_file_add_purgatory(image, &data);
if (ret)
return ERR_PTR(ret);
return kexec_file_update_kernel(image, &data);
}
static int s390_image_probe(const char *buf, unsigned long len)
{
/* Can't reliably tell if an image is valid. Therefore give the
* user whatever he wants.
*/
return 0;
}
const struct kexec_file_ops s390_kexec_image_ops = {
.probe = s390_image_probe,
.load = s390_image_load,
};
// SPDX-License-Identifier: GPL-2.0
/*
* s390 code for kexec_file_load system call
*
* Copyright IBM Corp. 2018
*
* Author(s): Philipp Rudo <prudo@linux.vnet.ibm.com>
*/
#include <linux/elf.h>
#include <linux/kexec.h>
#include <asm/setup.h>
const struct kexec_file_ops * const kexec_file_loaders[] = {
&s390_kexec_elf_ops,
&s390_kexec_image_ops,
NULL,
};
int *kexec_file_update_kernel(struct kimage *image,
struct s390_load_data *data)
{
unsigned long *loc;
if (image->cmdline_buf_len >= ARCH_COMMAND_LINE_SIZE)
return ERR_PTR(-EINVAL);
if (image->cmdline_buf_len)
memcpy(data->kernel_buf + COMMAND_LINE_OFFSET,
image->cmdline_buf, image->cmdline_buf_len);
if (image->type == KEXEC_TYPE_CRASH) {
loc = (unsigned long *)(data->kernel_buf + OLDMEM_BASE_OFFSET);
*loc = crashk_res.start;
loc = (unsigned long *)(data->kernel_buf + OLDMEM_SIZE_OFFSET);
*loc = crashk_res.end - crashk_res.start + 1;
}
if (image->initrd_buf) {
loc = (unsigned long *)(data->kernel_buf + INITRD_START_OFFSET);
*loc = data->initrd_load_addr;
loc = (unsigned long *)(data->kernel_buf + INITRD_SIZE_OFFSET);
*loc = image->initrd_buf_len;
}
return NULL;
}
static int kexec_file_update_purgatory(struct kimage *image)
{
u64 entry, type;
int ret;
if (image->type == KEXEC_TYPE_CRASH) {
entry = STARTUP_KDUMP_OFFSET;
type = KEXEC_TYPE_CRASH;
} else {
entry = STARTUP_NORMAL_OFFSET;
type = KEXEC_TYPE_DEFAULT;
}
ret = kexec_purgatory_get_set_symbol(image, "kernel_entry", &entry,
sizeof(entry), false);
if (ret)
return ret;
ret = kexec_purgatory_get_set_symbol(image, "kernel_type", &type,
sizeof(type), false);
if (ret)
return ret;
if (image->type == KEXEC_TYPE_CRASH) {
u64 crash_size;
ret = kexec_purgatory_get_set_symbol(image, "crash_start",
&crashk_res.start,
sizeof(crashk_res.start),
false);
if (ret)
return ret;
crash_size = crashk_res.end - crashk_res.start + 1;
ret = kexec_purgatory_get_set_symbol(image, "crash_size",
&crash_size,
sizeof(crash_size),
false);
}
return ret;
}
int kexec_file_add_purgatory(struct kimage *image, struct s390_load_data *data)
{
struct kexec_buf buf;
int ret;
buf.image = image;
data->memsz = ALIGN(data->memsz, PAGE_SIZE);
buf.mem = data->memsz;
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
ret = kexec_load_purgatory(image, &buf);
if (ret)
return ret;
ret = kexec_file_update_purgatory(image);
return ret;
}
int kexec_file_add_initrd(struct kimage *image, struct s390_load_data *data,
char *initrd, unsigned long initrd_len)
{
struct kexec_buf buf;
int ret;
buf.image = image;
buf.buffer = initrd;
buf.bufsz = initrd_len;
data->memsz = ALIGN(data->memsz, PAGE_SIZE);
buf.mem = data->memsz;
if (image->type == KEXEC_TYPE_CRASH)
buf.mem += crashk_res.start;
buf.memsz = buf.bufsz;
data->initrd_load_addr = buf.mem;
data->memsz += buf.memsz;
ret = kexec_add_buffer(&buf);
return ret;
}
/*
* The kernel is loaded to a fixed location. Turn off kexec_locate_mem_hole
* and provide kbuf->mem by hand.
*/
int arch_kexec_walk_mem(struct kexec_buf *kbuf,
int (*func)(struct resource *, void *))
{
return 1;
}
int arch_kexec_apply_relocations_add(struct purgatory_info *pi,
Elf_Shdr *section,
const Elf_Shdr *relsec,
const Elf_Shdr *symtab)
{
Elf_Rela *relas;
int i;
relas = (void *)pi->ehdr + relsec->sh_offset;
for (i = 0; i < relsec->sh_size / sizeof(*relas); i++) {
const Elf_Sym *sym; /* symbol to relocate */
unsigned long addr; /* final location after relocation */
unsigned long val; /* relocated symbol value */
void *loc; /* tmp location to modify */
sym = (void *)pi->ehdr + symtab->sh_offset;
sym += ELF64_R_SYM(relas[i].r_info);
if (sym->st_shndx == SHN_UNDEF)
return -ENOEXEC;
if (sym->st_shndx == SHN_COMMON)
return -ENOEXEC;
if (sym->st_shndx >= pi->ehdr->e_shnum &&
sym->st_shndx != SHN_ABS)
return -ENOEXEC;
loc = pi->purgatory_buf;
loc += section->sh_offset;
loc += relas[i].r_offset;
val = sym->st_value;
if (sym->st_shndx != SHN_ABS)
val += pi->sechdrs[sym->st_shndx].sh_addr;
val += relas[i].r_addend;
addr = section->sh_addr + relas[i].r_offset;
switch (ELF64_R_TYPE(relas[i].r_info)) {
case R_390_8: /* Direct 8 bit. */
*(u8 *)loc = val;
break;
case R_390_12: /* Direct 12 bit. */
*(u16 *)loc &= 0xf000;
*(u16 *)loc |= val & 0xfff;
break;
case R_390_16: /* Direct 16 bit. */
*(u16 *)loc = val;
break;
case R_390_20: /* Direct 20 bit. */
*(u32 *)loc &= 0xf00000ff;
*(u32 *)loc |= (val & 0xfff) << 16; /* DL */
*(u32 *)loc |= (val & 0xff000) >> 4; /* DH */
break;
case R_390_32: /* Direct 32 bit. */
*(u32 *)loc = val;
break;
case R_390_64: /* Direct 64 bit. */
*(u64 *)loc = val;
break;
case R_390_PC16: /* PC relative 16 bit. */
*(u16 *)loc = (val - addr);
break;
case R_390_PC16DBL: /* PC relative 16 bit shifted by 1. */
*(u16 *)loc = (val - addr) >> 1;
break;
case R_390_PC32DBL: /* PC relative 32 bit shifted by 1. */
*(u32 *)loc = (val - addr) >> 1;
break;
case R_390_PC32: /* PC relative 32 bit. */
*(u32 *)loc = (val - addr);
break;
case R_390_PC64: /* PC relative 64 bit. */
*(u64 *)loc = (val - addr);
break;
default:
break;
}
}
return 0;
}
int arch_kexec_kernel_image_probe(struct kimage *image, void *buf,
unsigned long buf_len)
{
/* A kernel must be at least large enough to contain head.S. During
* load memory in head.S will be accessed, e.g. to register the next
* command line. If the next kernel were smaller the current kernel
* will panic at load.
*
* 0x11000 = sizeof(head.S)
*/
if (buf_len < 0x11000)
return -ENOEXEC;
return kexec_image_probe_default(image, buf, buf_len);
}
// SPDX-License-Identifier: GPL-2.0
#include <linux/module.h>
#include <linux/device.h>
#include <linux/cpu.h>
#include <asm/nospec-branch.h>
static int __init nobp_setup_early(char *str)
......
......@@ -583,6 +583,7 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
model = cpumcf_z13_pmu_event_attr;
break;
case 0x3906:
case 0x3907:
model = cpumcf_z14_pmu_event_attr;
break;
default:
......
......@@ -821,6 +821,7 @@ static int __init setup_hwcaps(void)
strcpy(elf_platform, "z13");
break;
case 0x3906:
case 0x3907:
strcpy(elf_platform, "z14");
break;
}
......
......@@ -388,3 +388,4 @@
378 common s390_guarded_storage sys_s390_guarded_storage compat_sys_s390_guarded_storage
379 common statx sys_statx compat_sys_statx
380 common s390_sthyi sys_s390_sthyi compat_sys_s390_sthyi
381 common kexec_file_load sys_kexec_file_load compat_sys_kexec_file_load
kexec-purgatory.c
purgatory.ro
# 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
/* 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.
*
* If the next kernel is a crash kernel there are some peculiarities to
* consider:
*
* First the purgatory is called twice. Once only to verify the
* sha digest. So if the crash kernel got corrupted the old kernel can try
* to trigger a stand-alone dumper. And once to actually load the crash kernel.
*
* Second the purgatory also has to swap the crash memory region with its
* destination at address 0. As the purgatory is part of crash memory this
* requires some finesse. The tactic here is that the purgatory first copies
* itself to the end of the destination and then swaps the rest of the
* memory running from there.
*/
#define bufsz purgatory_end-stack
.macro MEMCPY dst,src,len
lgr %r0,\dst
lgr %r1,\len
lgr %r2,\src
lgr %r3,\len
20: mvcle %r0,%r2,0
jo 20b
.endm
.macro MEMSWAP dst,src,buf,len
10: cghi \len,bufsz
jh 11f
lgr %r4,\len
j 12f
11: lghi %r4,bufsz
12: MEMCPY \buf,\dst,%r4
MEMCPY \dst,\src,%r4
MEMCPY \src,\buf,%r4
agr \dst,%r4
agr \src,%r4
sgr \len,%r4
cghi \len,0
jh 10b
.endm
.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
/* If the next kernel is KEXEC_TYPE_CRASH the purgatory is called
* directly with a flag passed in %r2 whether the purgatory shall do
* checksum verification only (%r2 = 0 -> verification only).
*
* Check now and preserve over C function call by storing in
* %r10 whith
* 1 -> checksum verification only
* 0 -> load new kernel
*/
lghi %r10,0
lg %r11,kernel_type-.base_crash(%r13)
cghi %r11,1 /* KEXEC_TYPE_CRASH */
jne .do_checksum_verification
cghi %r2,0 /* checksum verification only */
jne .do_checksum_verification
lghi %r10,1
.do_checksum_verification:
brasl %r14,verify_sha256_digest
cghi %r10,1 /* checksum verification only */
je .return_old_kernel
cghi %r2,0 /* checksum match */
jne .disabled_wait
/* If the next kernel is a crash kernel the purgatory has to swap
* the mem regions first.
*/
cghi %r11,1 /* KEXEC_TYPE_CRASH */
je .start_crash_kernel
/* start normal kernel */
START_NEXT_KERNEL .base_crash
.return_old_kernel:
lmg %r6,%r15,gprregs-.base_crash(%r13)
br %r14
.disabled_wait:
lpswe disabled_wait_psw-.base_crash(%r13)
.start_crash_kernel:
/* Location of purgatory_start in crash memory */
lgr %r8,%r13
aghi %r8,-(.base_crash-purgatory_start)
/* Destination for this code i.e. end of memory to be swapped. */
lg %r9,crash_size-.base_crash(%r13)
aghi %r9,-(purgatory_end-purgatory_start)
/* Destination in crash memory, i.e. same as r9 but in crash memory. */
lg %r10,crash_start-.base_crash(%r13)
agr %r10,%r9
/* Buffer location (in crash memory) and size. As the purgatory is
* behind the point of no return it can re-use the stack as buffer.
*/
lghi %r11,bufsz
larl %r12,stack
MEMCPY %r12,%r9,%r11 /* dst -> (crash) buf */
MEMCPY %r9,%r8,%r11 /* self -> dst */
/* Jump to new location. */
lgr %r7,%r9
aghi %r7,.jump_to_dst-purgatory_start
br %r7
.jump_to_dst:
basr %r13,0
.base_dst:
/* clear buffer */
MEMCPY %r12,%r10,%r11 /* (crash) buf -> (crash) dst */
/* Load new buffer location after jump */
larl %r7,stack
aghi %r10,stack-purgatory_start
MEMCPY %r10,%r7,%r11 /* (new) buf -> (crash) buf */
/* Now the code is set up to run from its designated location. Start
* swapping the rest of crash memory now.
*
* The registers will be used as follow:
*
* %r0-%r4 reserved for macros defined above
* %r5-%r6 tmp registers
* %r7 pointer to current struct sha region
* %r8 index to iterate over all sha regions
* %r9 pointer in crash memory
* %r10 pointer in old kernel
* %r11 total size (still) to be moved
* %r12 pointer to buffer
*/
lgr %r12,%r7
lgr %r11,%r9
lghi %r10,0
lg %r9,crash_start-.base_dst(%r13)
lghi %r8,16 /* KEXEC_SEGMENTS_MAX */
larl %r7,purgatory_sha_regions
j .loop_first
/* Loop over all purgatory_sha_regions. */
.loop_next:
aghi %r8,-1
cghi %r8,0
je .loop_out
aghi %r7,__KEXEC_SHA_REGION_SIZE
.loop_first:
lg %r5,__KEXEC_SHA_REGION_START(%r7)
cghi %r5,0
je .loop_next
/* Copy [end last sha region, start current sha region) */
/* Note: kexec_sha_region->start points in crash memory */
sgr %r5,%r9
MEMCPY %r9,%r10,%r5
agr %r9,%r5
agr %r10,%r5
sgr %r11,%r5
/* Swap sha region */
lg %r6,__KEXEC_SHA_REGION_LEN(%r7)
MEMSWAP %r9,%r10,%r12,%r6
sg %r11,__KEXEC_SHA_REGION_LEN(%r7)
j .loop_next
.loop_out:
/* Copy rest of crash memory */
MEMCPY %r9,%r10,%r11
/* start crash kernel */
START_NEXT_KERNEL .base_dst
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
kernel_type:
.global kernel_type
.quad 0
crash_start:
.global crash_start
.quad 0
crash_size:
.global crash_size
.quad 0
.align PAGE_SIZE
stack:
/* The buffer to move this code must be as big as the code. */
.skip stack-purgatory_start
.align PAGE_SIZE
purgatory_end:
// 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;
u64 kernel_type;
u64 crash_start;
u64 crash_size;
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;
}
......@@ -27,7 +27,6 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/vtoc.h>
#include <asm/diag.h>
#include "dasd_int.h"
#include "dasd_diag.h"
......
......@@ -18,7 +18,7 @@ int sclp_init_state __section(.data) = sclp_init_state_uninitialized;
* Used to keep track of the size of the event masks. Qemu until version 2.11
* only supports 4 and needs a workaround.
*/
bool sclp_mask_compat_mode;
bool sclp_mask_compat_mode __section(.data);
void sclp_early_wait_irq(void)
{
......
......@@ -21,7 +21,6 @@
#include <linux/list.h>
#include <linux/hash.h>
#include <linux/hashtable.h>
#include <linux/string.h>
#include <asm/setup.h>
#include "qeth_core.h"
#include "qeth_l2.h"
......
......@@ -176,7 +176,7 @@ static struct device_driver smsg_driver = {
static void __exit smsg_exit(void)
{
cpcmd("SET SMSG IUCV", NULL, 0, NULL);
cpcmd("SET SMSG OFF", NULL, 0, NULL);
device_unregister(smsg_dev);
iucv_unregister(&smsg_handler, 1);
driver_unregister(&smsg_driver);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment