Commit 95fbef17 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 's390-5.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux

Pull s390 updates from Heiko Carstens:

 - Make use of the IBM z16 processor activity instrumentation facility
   to count cryptography operations: add a new PMU device driver so that
   perf can make use of this.

 - Add new IBM z16 extended counter set to cpumf support.

 - Add vdso randomization support.

 - Add missing KCSAN instrumentation to barriers and spinlocks, which
   should make s390's KCSAN support complete.

 - Add support for IPL-complete-control facility: notify the hypervisor
   that kexec finished work and the kernel starts.

 - Improve error logging for PCI.

 - Various small changes to workaround llvm's integrated assembler
   limitations, and one bug, to make it finally possible to compile the
   kernel with llvm's integrated assembler. This also requires to raise
   the minimum clang version to 14.0.0.

 - Various other small enhancements, bug fixes, and cleanups all over
   the place.

* tag 's390-5.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (48 commits)
  s390/head: get rid of 31 bit leftovers
  scripts/min-tool-version.sh: raise minimum clang version to 14.0.0 for s390
  s390/boot: do not emit debug info for assembly with llvm's IAS
  s390/boot: workaround llvm IAS bug
  s390/purgatory: workaround llvm's IAS limitations
  s390/entry: workaround llvm's IAS limitations
  s390/alternatives: remove padding generation code
  s390/alternatives: provide identical sized orginal/alternative sequences
  s390/cpumf: add new extended counter set for IBM z16
  s390/preempt: disable __preempt_count_add() optimization for PROFILE_ALL_BRANCHES
  s390/stp: clock_delta should be signed
  s390/stp: fix todoff size
  s390/pai: add support for cryptography counters
  entry: Rename arch_check_user_regs() to arch_enter_from_user_mode()
  s390/compat: cleanup compat_linux.h header file
  s390/entry: remove broken and not needed code
  s390/boot: convert parmarea to C
  s390/boot: convert initial lowcore to C
  s390/ptrace: move short psw definitions to ptrace header file
  s390/head: initialize all new psws
  ...
parents 67c642e0 94d34778
......@@ -20,7 +20,9 @@ LDFLAGS_vmlinux := -pie
endif
aflags_dwarf := -Wa,-gdwarf-2
KBUILD_AFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -D__ASSEMBLY__
ifndef CONFIG_AS_IS_LLVM
KBUILD_AFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO),$(aflags_dwarf))
endif
KBUILD_CFLAGS_DECOMPRESSOR := $(CLANG_FLAGS) -m64 -O2 -mpacked-stack
KBUILD_CFLAGS_DECOMPRESSOR += -DDISABLE_BRANCH_PROFILING -D__NO_FORTIFY
KBUILD_CFLAGS_DECOMPRESSOR += -fno-delete-null-pointer-checks -msoft-float -mbackchain
......
......@@ -2,3 +2,6 @@
image
bzImage
section_cmp.*
vmlinux
vmlinux.lds
vmlinux.syms
......@@ -37,14 +37,21 @@ CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
obj-y := head.o als.o startup.o mem_detect.o ipl_parm.o ipl_report.o
obj-y += string.o ebcdic.o sclp_early_core.o mem.o ipl_vmparm.o cmdline.o
obj-y += version.o pgm_check_info.o ctype.o
obj-y += version.o pgm_check_info.o ctype.o ipl_data.o
obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o
obj-$(CONFIG_RELOCATABLE) += machine_kexec_reloc.o
obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
targets := bzImage startup.a section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
subdir- := compressed
obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
obj-all := $(obj-y) piggy.o syms.o
targets := bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
targets += vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
targets += vmlinux.bin.zst info.bin syms.bin vmlinux.syms $(obj-all)
OBJECTS := $(addprefix $(obj)/,$(obj-y))
OBJECTS_ALL := $(addprefix $(obj)/,$(obj-all))
quiet_cmd_section_cmp = SECTCMP $*
define cmd_section_cmp
......@@ -59,14 +66,67 @@ define cmd_section_cmp
touch $@
endef
$(obj)/bzImage: $(obj)/compressed/vmlinux $(obj)/section_cmp.boot.data $(obj)/section_cmp.boot.preserved.data FORCE
$(obj)/bzImage: $(obj)/vmlinux $(obj)/section_cmp.boot.data $(obj)/section_cmp.boot.preserved.data FORCE
$(call if_changed,objcopy)
$(obj)/section_cmp%: vmlinux $(obj)/compressed/vmlinux FORCE
$(obj)/section_cmp%: vmlinux $(obj)/vmlinux FORCE
$(call if_changed,section_cmp)
$(obj)/compressed/vmlinux: $(obj)/startup.a FORCE
$(Q)$(MAKE) $(build)=$(obj)/compressed $@
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup --build-id=sha1 -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(OBJECTS_ALL) FORCE
$(call if_changed,ld)
LDFLAGS_vmlinux.syms := --oformat $(LD_BFD) -e startup -T
$(obj)/vmlinux.syms: $(obj)/vmlinux.lds $(OBJECTS) FORCE
$(call if_changed,ld)
quiet_cmd_dumpsyms = DUMPSYMS $<
define cmd_dumpsyms
$(NM) -n -S --format=bsd "$<" | sed -nE 's/^0*([0-9a-fA-F]+) 0*([0-9a-fA-F]+) [tT] ([^ ]*)$$/\1 \2 \3/p' | tr '\n' '\0' > "$@"
endef
$(obj)/syms.bin: $(obj)/vmlinux.syms FORCE
$(call if_changed,dumpsyms)
OBJCOPYFLAGS_syms.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.decompressor.syms
$(obj)/syms.o: $(obj)/syms.bin FORCE
$(call if_changed,objcopy)
OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info --set-section-flags .vmlinux.info=load
$(obj)/info.bin: vmlinux FORCE
$(call if_changed,objcopy)
OBJCOPYFLAGS_info.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.vmlinux.info
$(obj)/info.o: $(obj)/info.bin FORCE
$(call if_changed,objcopy)
OBJCOPYFLAGS_vmlinux.bin := -O binary --remove-section=.comment --remove-section=.vmlinux.info -S
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
suffix-$(CONFIG_KERNEL_GZIP) := .gz
suffix-$(CONFIG_KERNEL_BZIP2) := .bz2
suffix-$(CONFIG_KERNEL_LZ4) := .lz4
suffix-$(CONFIG_KERNEL_LZMA) := .lzma
suffix-$(CONFIG_KERNEL_LZO) := .lzo
suffix-$(CONFIG_KERNEL_XZ) := .xz
suffix-$(CONFIG_KERNEL_ZSTD) := .zst
$(obj)/startup.a: $(OBJECTS) FORCE
$(call if_changed,ar)
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
$(call if_changed,bzip2_with_size)
$(obj)/vmlinux.bin.lz4: $(obj)/vmlinux.bin FORCE
$(call if_changed,lz4_with_size)
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzma_with_size)
$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzo_with_size)
$(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
$(call if_changed,xzkern_with_size)
$(obj)/vmlinux.bin.zst: $(obj)/vmlinux.bin FORCE
$(call if_changed,zstd22_with_size)
OBJCOPYFLAGS_piggy.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.vmlinux.bin.compressed
$(obj)/piggy.o: $(obj)/vmlinux.bin$(suffix-y) FORCE
$(call if_changed,objcopy)
......@@ -2,9 +2,12 @@
#ifndef BOOT_BOOT_H
#define BOOT_BOOT_H
#include <asm/extable.h>
#include <linux/types.h>
#define IPL_START 0x200
#ifndef __ASSEMBLY__
void startup_kernel(void);
unsigned long detect_memory(void);
bool is_ipl_block_dump(void);
......@@ -31,4 +34,5 @@ extern char _stack_start[], _stack_end[];
unsigned long read_ipl_report(unsigned long safe_offset);
#endif /* __ASSEMBLY__ */
#endif /* BOOT_BOOT_H */
# SPDX-License-Identifier: GPL-2.0-only
vmlinux
vmlinux.lds
vmlinux.syms
# SPDX-License-Identifier: GPL-2.0
#
# linux/arch/s390/boot/compressed/Makefile
#
# create a compressed vmlinux image from the original vmlinux
#
KCOV_INSTRUMENT := n
GCOV_PROFILE := n
UBSAN_SANITIZE := n
KASAN_SANITIZE := n
KCSAN_SANITIZE := n
obj-y := $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
obj-all := $(obj-y) piggy.o syms.o
targets := vmlinux.lds vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2
targets += vmlinux.bin.xz vmlinux.bin.lzma vmlinux.bin.lzo vmlinux.bin.lz4
targets += vmlinux.bin.zst
targets += info.bin syms.bin vmlinux.syms $(obj-all)
KBUILD_AFLAGS := $(KBUILD_AFLAGS_DECOMPRESSOR)
KBUILD_CFLAGS := $(KBUILD_CFLAGS_DECOMPRESSOR)
OBJCOPYFLAGS :=
OBJECTS := $(addprefix $(obj)/,$(obj-y))
OBJECTS_ALL := $(addprefix $(obj)/,$(obj-all))
LDFLAGS_vmlinux := --oformat $(LD_BFD) -e startup --build-id=sha1 -T
$(obj)/vmlinux: $(obj)/vmlinux.lds $(objtree)/arch/s390/boot/startup.a $(OBJECTS_ALL) FORCE
$(call if_changed,ld)
LDFLAGS_vmlinux.syms := --oformat $(LD_BFD) -e startup -T
$(obj)/vmlinux.syms: $(obj)/vmlinux.lds $(objtree)/arch/s390/boot/startup.a $(OBJECTS) FORCE
$(call if_changed,ld)
quiet_cmd_dumpsyms = DUMPSYMS $<
define cmd_dumpsyms
$(NM) -n -S --format=bsd "$<" | sed -nE 's/^0*([0-9a-fA-F]+) 0*([0-9a-fA-F]+) [tT] ([^ ]*)$$/\1 \2 \3/p' | tr '\n' '\0' > "$@"
endef
$(obj)/syms.bin: $(obj)/vmlinux.syms FORCE
$(call if_changed,dumpsyms)
OBJCOPYFLAGS_syms.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.decompressor.syms
$(obj)/syms.o: $(obj)/syms.bin FORCE
$(call if_changed,objcopy)
OBJCOPYFLAGS_info.bin := -O binary --only-section=.vmlinux.info --set-section-flags .vmlinux.info=load
$(obj)/info.bin: vmlinux FORCE
$(call if_changed,objcopy)
OBJCOPYFLAGS_info.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.vmlinux.info
$(obj)/info.o: $(obj)/info.bin FORCE
$(call if_changed,objcopy)
OBJCOPYFLAGS_vmlinux.bin := -O binary --remove-section=.comment --remove-section=.vmlinux.info -S
$(obj)/vmlinux.bin: vmlinux FORCE
$(call if_changed,objcopy)
suffix-$(CONFIG_KERNEL_GZIP) := .gz
suffix-$(CONFIG_KERNEL_BZIP2) := .bz2
suffix-$(CONFIG_KERNEL_LZ4) := .lz4
suffix-$(CONFIG_KERNEL_LZMA) := .lzma
suffix-$(CONFIG_KERNEL_LZO) := .lzo
suffix-$(CONFIG_KERNEL_XZ) := .xz
suffix-$(CONFIG_KERNEL_ZSTD) := .zst
$(obj)/vmlinux.bin.gz: $(obj)/vmlinux.bin FORCE
$(call if_changed,gzip)
$(obj)/vmlinux.bin.bz2: $(obj)/vmlinux.bin FORCE
$(call if_changed,bzip2_with_size)
$(obj)/vmlinux.bin.lz4: $(obj)/vmlinux.bin FORCE
$(call if_changed,lz4_with_size)
$(obj)/vmlinux.bin.lzma: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzma_with_size)
$(obj)/vmlinux.bin.lzo: $(obj)/vmlinux.bin FORCE
$(call if_changed,lzo_with_size)
$(obj)/vmlinux.bin.xz: $(obj)/vmlinux.bin FORCE
$(call if_changed,xzkern_with_size)
$(obj)/vmlinux.bin.zst: $(obj)/vmlinux.bin FORCE
$(call if_changed,zstd22_with_size)
OBJCOPYFLAGS_piggy.o := -I binary -O elf64-s390 -B s390:64-bit --rename-section .data=.vmlinux.bin.compressed
$(obj)/piggy.o: $(obj)/vmlinux.bin$(suffix-y) FORCE
$(call if_changed,objcopy)
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
#include <linux/compat.h>
#include <linux/ptrace.h>
#include <asm/cio.h>
#include <asm/asm-offsets.h>
#include "boot.h"
#define CCW0(cmd, addr, cnt, flg) \
{ .cmd_code = cmd, .cda = addr, .count = cnt, .flags = flg, }
#define PSW_MASK_DISABLED (PSW_MASK_WAIT | PSW_MASK_EA | PSW_MASK_BA)
struct ipl_lowcore {
psw_t32 ipl_psw; /* 0x0000 */
struct ccw0 ccwpgm[2]; /* 0x0008 */
u8 fill[56]; /* 0x0018 */
struct ccw0 ccwpgmcc[20]; /* 0x0050 */
u8 pad_0xf0[0x01a0-0x00f0]; /* 0x00f0 */
psw_t restart_psw; /* 0x01a0 */
psw_t external_new_psw; /* 0x01b0 */
psw_t svc_new_psw; /* 0x01c0 */
psw_t program_new_psw; /* 0x01d0 */
psw_t mcck_new_psw; /* 0x01e0 */
psw_t io_new_psw; /* 0x01f0 */
};
/*
* Initial lowcore for IPL: the first 24 bytes are loaded by IPL to
* addresses 0-23 (a PSW and two CCWs). Bytes 24-79 are discarded.
* The next 160 bytes are loaded to addresses 0x18-0xb7. They form
* the continuation of the CCW program started by IPL and load the
* range 0x0f0-0x730 from the image to the range 0x0f0-0x730 in
* memory. At the end of the channel program the PSW at location 0 is
* loaded.
* Initial processing starts at 0x200 = iplstart.
*
* The restart psw points to iplstart which allows to load a kernel
* image into memory and starting it by a psw restart on any cpu. All
* other default psw new locations contain a disabled wait psw where
* the address indicates which psw was loaded.
*
* Note that the 'file' utility can detect s390 kernel images. For
* that to succeed the two initial CCWs, and the 0x40 fill bytes must
* be present.
*/
static struct ipl_lowcore ipl_lowcore __used __section(".ipldata") = {
.ipl_psw = { .mask = PSW32_MASK_BASE, .addr = PSW32_ADDR_AMODE | IPL_START },
.ccwpgm = {
[ 0] = CCW0(CCW_CMD_READ_IPL, 0x018, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 1] = CCW0(CCW_CMD_READ_IPL, 0x068, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
},
.fill = {
[ 0 ... 55] = 0x40,
},
.ccwpgmcc = {
[ 0] = CCW0(CCW_CMD_READ_IPL, 0x0f0, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 1] = CCW0(CCW_CMD_READ_IPL, 0x140, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 2] = CCW0(CCW_CMD_READ_IPL, 0x190, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 3] = CCW0(CCW_CMD_READ_IPL, 0x1e0, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 4] = CCW0(CCW_CMD_READ_IPL, 0x230, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 5] = CCW0(CCW_CMD_READ_IPL, 0x280, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 6] = CCW0(CCW_CMD_READ_IPL, 0x2d0, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 7] = CCW0(CCW_CMD_READ_IPL, 0x320, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 8] = CCW0(CCW_CMD_READ_IPL, 0x370, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[ 9] = CCW0(CCW_CMD_READ_IPL, 0x3c0, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[10] = CCW0(CCW_CMD_READ_IPL, 0x410, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[11] = CCW0(CCW_CMD_READ_IPL, 0x460, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[12] = CCW0(CCW_CMD_READ_IPL, 0x4b0, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[13] = CCW0(CCW_CMD_READ_IPL, 0x500, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[14] = CCW0(CCW_CMD_READ_IPL, 0x550, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[15] = CCW0(CCW_CMD_READ_IPL, 0x5a0, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[16] = CCW0(CCW_CMD_READ_IPL, 0x5f0, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[17] = CCW0(CCW_CMD_READ_IPL, 0x640, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[18] = CCW0(CCW_CMD_READ_IPL, 0x690, 0x50, CCW_FLAG_SLI | CCW_FLAG_CC),
[19] = CCW0(CCW_CMD_READ_IPL, 0x6e0, 0x50, CCW_FLAG_SLI),
},
.restart_psw = { .mask = 0, .addr = IPL_START, },
.external_new_psw = { .mask = PSW_MASK_DISABLED, .addr = __LC_EXT_NEW_PSW, },
.svc_new_psw = { .mask = PSW_MASK_DISABLED, .addr = __LC_SVC_NEW_PSW, },
.program_new_psw = { .mask = PSW_MASK_DISABLED, .addr = __LC_PGM_NEW_PSW, },
.mcck_new_psw = { .mask = PSW_MASK_DISABLED, .addr = __LC_MCK_NEW_PSW, },
.io_new_psw = { .mask = PSW_MASK_DISABLED, .addr = __LC_IO_NEW_PSW, },
};
......@@ -8,9 +8,16 @@
#include <asm/sections.h>
#include <asm/boot_data.h>
#include <asm/facility.h>
#include <asm/setup.h>
#include <asm/uv.h>
#include "boot.h"
struct parmarea parmarea __section(".parmarea") = {
.kernel_version = (unsigned long)kernel_version,
.max_command_line_size = COMMAND_LINE_SIZE,
.command_line = "root=/dev/ram0 ro",
};
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
int __bootdata(noexec_disabled);
......
......@@ -8,7 +8,7 @@
#include <asm/timex.h>
#include <asm/sclp.h>
#include <asm/kasan.h>
#include "compressed/decompressor.h"
#include "decompressor.h"
#include "boot.h"
#define PRNG_MODE_TDES 1
......
......@@ -7,7 +7,7 @@
#include <asm/sections.h>
#include <asm/mem_detect.h>
#include <asm/sparsemem.h>
#include "compressed/decompressor.h"
#include "decompressor.h"
#include "boot.h"
struct mem_detect_info __bootdata(mem_detect);
......
......@@ -10,7 +10,7 @@
#include <asm/sclp.h>
#include <asm/diag.h>
#include <asm/uv.h>
#include "compressed/decompressor.h"
#include "decompressor.h"
#include "boot.h"
#include "uv.h"
......
......@@ -4,6 +4,7 @@
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/sclp.h>
#include "boot.h"
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
......@@ -13,11 +14,19 @@ ENTRY(startup)
SECTIONS
{
. = 0;
.ipldata : {
*(.ipldata)
}
. = IPL_START;
.head.text : {
_head = . ;
HEAD_TEXT
_ehead = . ;
}
. = PARMAREA;
.parmarea : {
*(.parmarea)
}
.text : {
_text = .; /* Text */
*(.text)
......
......@@ -194,7 +194,7 @@ static struct skcipher_alg cbc_des_alg = {
* same as DES. Implementers MUST reject keys that exhibit this
* property.
*
* In fips mode additinally check for all 3 keys are unique.
* In fips mode additionally check for all 3 keys are unique.
*
*/
static int des3_setkey(struct crypto_tfm *tfm, const u8 *key,
......
......@@ -528,7 +528,7 @@ static ssize_t prng_tdes_read(struct file *file, char __user *ubuf,
/* give mutex free before calling schedule() */
mutex_unlock(&prng_data->mutex);
schedule();
/* occopy mutex again */
/* occupy mutex again */
if (mutex_lock_interruptible(&prng_data->mutex)) {
if (ret == 0)
ret = -ERESTARTSYS;
......
......@@ -190,7 +190,7 @@ int hypfs_vm_create_files(struct dentry *root)
if (IS_ERR(data))
return PTR_ERR(data);
/* Hpervisor Info */
/* Hypervisor Info */
dir = hypfs_mkdir(root, "hyp");
if (IS_ERR(dir)) {
rc = PTR_ERR(dir);
......
......@@ -4,19 +4,6 @@
#ifdef __ASSEMBLY__
/*
* Check the length of an instruction sequence. The length may not be larger
* than 254 bytes and it has to be divisible by 2.
*/
.macro alt_len_check start,end
.if ( \end - \start ) > 254
.error "cpu alternatives does not support instructions blocks > 254 bytes\n"
.endif
.if ( \end - \start ) % 2
.error "cpu alternatives instructions length is odd\n"
.endif
.endm
/*
* Issue one struct alt_instr descriptor entry (need to put it into
* the section .altinstructions, see below). This entry contains
......@@ -28,66 +15,29 @@
.long \alt_start - .
.word \feature
.byte \orig_end - \orig_start
.byte \alt_end - \alt_start
.endm
/*
* Fill up @bytes with nops. The macro emits 6-byte nop instructions
* for the bulk of the area, possibly followed by a 4-byte and/or
* a 2-byte nop if the size of the area is not divisible by 6.
*/
.macro alt_pad_fill bytes
.rept ( \bytes ) / 6
brcl 0,0
.endr
.rept ( \bytes ) % 6 / 4
nop
.endr
.rept ( \bytes ) % 6 % 4 / 2
nopr
.endr
.endm
/*
* Fill up @bytes with nops. If the number of bytes is larger
* than 6, emit a jg instruction to branch over all nops, then
* fill an area of size (@bytes - 6) with nop instructions.
*/
.macro alt_pad bytes
.if ( \bytes > 0 )
.if ( \bytes > 6 )
jg . + \bytes
alt_pad_fill \bytes - 6
.else
alt_pad_fill \bytes
.endif
.endif
.org . - ( \orig_end - \orig_start ) + ( \alt_end - \alt_start )
.org . - ( \alt_end - \alt_start ) + ( \orig_end - \orig_start )
.endm
/*
* Define an alternative between two instructions. If @feature is
* present, early code in apply_alternatives() replaces @oldinstr with
* @newinstr. ".skip" directive takes care of proper instruction padding
* in case @newinstr is longer than @oldinstr.
* @newinstr.
*/
.macro ALTERNATIVE oldinstr, newinstr, feature
.pushsection .altinstr_replacement,"ax"
770: \newinstr
771: .popsection
772: \oldinstr
773: alt_len_check 770b, 771b
alt_len_check 772b, 773b
alt_pad ( ( 771b - 770b ) - ( 773b - 772b ) )
774: .pushsection .altinstructions,"a"
alt_entry 772b, 774b, 770b, 771b, \feature
773: .pushsection .altinstructions,"a"
alt_entry 772b, 773b, 770b, 771b, \feature
.popsection
.endm
/*
* Define an alternative between two instructions. If @feature is
* present, early code in apply_alternatives() replaces @oldinstr with
* @newinstr. ".skip" directive takes care of proper instruction padding
* in case @newinstr is longer than @oldinstr.
* @newinstr.
*/
.macro ALTERNATIVE_2 oldinstr, newinstr1, feature1, newinstr2, feature2
.pushsection .altinstr_replacement,"ax"
......@@ -95,17 +45,9 @@
771: \newinstr2
772: .popsection
773: \oldinstr
774: alt_len_check 770b, 771b
alt_len_check 771b, 772b
alt_len_check 773b, 774b
.if ( 771b - 770b > 772b - 771b )
alt_pad ( ( 771b - 770b ) - ( 774b - 773b ) )
.else
alt_pad ( ( 772b - 771b ) - ( 774b - 773b ) )
.endif
775: .pushsection .altinstructions,"a"
alt_entry 773b, 775b, 770b, 771b,\feature1
alt_entry 773b, 775b, 771b, 772b,\feature2
774: .pushsection .altinstructions,"a"
alt_entry 773b, 774b, 770b, 771b,\feature1
alt_entry 773b, 774b, 771b, 772b,\feature2
.popsection
.endm
......
......@@ -13,32 +13,25 @@ struct alt_instr {
s32 repl_offset; /* offset to replacement instruction */
u16 facility; /* facility bit set for replacement */
u8 instrlen; /* length of original instruction */
u8 replacementlen; /* length of new instruction */
} __packed;
void apply_alternative_instructions(void);
void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
/*
* |661: |662: |6620 |663:
* +-----------+---------------------+
* | oldinstr | oldinstr_padding |
* | +----------+----------+
* | | | |
* | | >6 bytes |6/4/2 nops|
* | |6 bytes jg----------->
* +-----------+---------------------+
* ^^ static padding ^^
* +---------------------------------+
* |661: |662:
* | oldinstr |
* +---------------------------------+
*
* .altinstr_replacement section
* +---------------------+-----------+
* +---------------------------------+
* |6641: |6651:
* | alternative instr 1 |
* +-----------+---------+- - - - - -+
* |6642: |6652: |
* | alternative instr 2 | padding
* +---------------------+- - - - - -+
* ^ runtime ^
* +---------------------------------+
* |6642: |6652:
* | alternative instr 2 |
* +---------------------------------+
*
* .altinstructions section
* +---------------------------------+
......@@ -47,77 +40,31 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
* +---------------------------------+
*/
#define b_altinstr(num) "664"#num
#define e_altinstr(num) "665"#num
#define e_oldinstr_pad_end "663"
#define b_altinstr(num) "664"#num
#define e_altinstr(num) "665"#num
#define oldinstr_len "662b-661b"
#define oldinstr_total_len e_oldinstr_pad_end"b-661b"
#define altinstr_len(num) e_altinstr(num)"b-"b_altinstr(num)"b"
#define oldinstr_pad_len(num) \
"-(((" altinstr_len(num) ")-(" oldinstr_len ")) > 0) * " \
"((" altinstr_len(num) ")-(" oldinstr_len "))"
#define INSTR_LEN_SANITY_CHECK(len) \
".if " len " > 254\n" \
"\t.error \"cpu alternatives does not support instructions " \
"blocks > 254 bytes\"\n" \
".endif\n" \
".if (" len ") %% 2\n" \
"\t.error \"cpu alternatives instructions length is odd\"\n" \
".endif\n"
#define OLDINSTR_PADDING(oldinstr, num) \
".if " oldinstr_pad_len(num) " > 6\n" \
"\tjg " e_oldinstr_pad_end "f\n" \
"6620:\n" \
"\t.rept (" oldinstr_pad_len(num) " - (6620b-662b)) / 2\n" \
"\tnopr\n" \
".else\n" \
"\t.rept " oldinstr_pad_len(num) " / 6\n" \
"\t.brcl 0,0\n" \
"\t.endr\n" \
"\t.rept " oldinstr_pad_len(num) " %% 6 / 4\n" \
"\tnop\n" \
"\t.endr\n" \
"\t.rept " oldinstr_pad_len(num) " %% 6 %% 4 / 2\n" \
"\tnopr\n" \
".endr\n" \
".endif\n"
#define OLDINSTR(oldinstr, num) \
"661:\n\t" oldinstr "\n662:\n" \
OLDINSTR_PADDING(oldinstr, num) \
e_oldinstr_pad_end ":\n" \
INSTR_LEN_SANITY_CHECK(oldinstr_len)
#define OLDINSTR_2(oldinstr, num1, num2) \
"661:\n\t" oldinstr "\n662:\n" \
".if " altinstr_len(num1) " < " altinstr_len(num2) "\n" \
OLDINSTR_PADDING(oldinstr, num2) \
".else\n" \
OLDINSTR_PADDING(oldinstr, num1) \
".endif\n" \
e_oldinstr_pad_end ":\n" \
INSTR_LEN_SANITY_CHECK(oldinstr_len)
#define OLDINSTR(oldinstr) \
"661:\n\t" oldinstr "\n662:\n"
#define ALTINSTR_ENTRY(facility, num) \
"\t.long 661b - .\n" /* old instruction */ \
"\t.long " b_altinstr(num)"b - .\n" /* alt instruction */ \
"\t.word " __stringify(facility) "\n" /* facility bit */ \
"\t.byte " oldinstr_total_len "\n" /* source len */ \
"\t.byte " altinstr_len(num) "\n" /* alt instruction len */
"\t.byte " oldinstr_len "\n" /* instruction len */ \
"\t.org . - (" oldinstr_len ") + (" altinstr_len(num) ")\n" \
"\t.org . - (" altinstr_len(num) ") + (" oldinstr_len ")\n"
#define ALTINSTR_REPLACEMENT(altinstr, num) /* replacement */ \
b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n" \
INSTR_LEN_SANITY_CHECK(altinstr_len(num))
b_altinstr(num)":\n\t" altinstr "\n" e_altinstr(num) ":\n"
/* alternative assembly primitive: */
#define ALTERNATIVE(oldinstr, altinstr, facility) \
".pushsection .altinstr_replacement, \"ax\"\n" \
ALTINSTR_REPLACEMENT(altinstr, 1) \
".popsection\n" \
OLDINSTR(oldinstr, 1) \
OLDINSTR(oldinstr) \
".pushsection .altinstructions,\"a\"\n" \
ALTINSTR_ENTRY(facility, 1) \
".popsection\n"
......@@ -127,7 +74,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end);
ALTINSTR_REPLACEMENT(altinstr1, 1) \
ALTINSTR_REPLACEMENT(altinstr2, 2) \
".popsection\n" \
OLDINSTR_2(oldinstr, 1, 2) \
OLDINSTR(oldinstr) \
".pushsection .altinstructions,\"a\"\n" \
ALTINSTR_ENTRY(facility1, 1) \
ALTINSTR_ENTRY(facility2, 2) \
......
......@@ -26,16 +26,16 @@
stringify_in_c(.long (_target) - .;) \
stringify_in_c(.short (_type);) \
stringify_in_c(.macro extable_reg reg;) \
stringify_in_c(.set found, 0;) \
stringify_in_c(.set regnr, 0;) \
stringify_in_c(.set .Lfound, 0;) \
stringify_in_c(.set .Lregnr, 0;) \
stringify_in_c(.irp rs,r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15;) \
stringify_in_c(.ifc "\reg", "%%\rs";) \
stringify_in_c(.set found, 1;) \
stringify_in_c(.short regnr;) \
stringify_in_c(.set .Lfound, 1;) \
stringify_in_c(.short .Lregnr;) \
stringify_in_c(.endif;) \
stringify_in_c(.set regnr, regnr+1;) \
stringify_in_c(.set .Lregnr, .Lregnr+1;) \
stringify_in_c(.endr;) \
stringify_in_c(.ifne (found != 1);) \
stringify_in_c(.ifne (.Lfound != 1);) \
stringify_in_c(.error "extable_reg: bad register argument";) \
stringify_in_c(.endif;) \
stringify_in_c(.endm;) \
......
......@@ -26,14 +26,14 @@ static __always_inline void bcr_serialize(void)
asm volatile(__ASM_BCR_SERIALIZE : : : "memory");
}
#define mb() bcr_serialize()
#define rmb() barrier()
#define wmb() barrier()
#define dma_rmb() mb()
#define dma_wmb() mb()
#define __smp_mb() mb()
#define __smp_rmb() rmb()
#define __smp_wmb() wmb()
#define __mb() bcr_serialize()
#define __rmb() barrier()
#define __wmb() barrier()
#define __dma_rmb() __mb()
#define __dma_wmb() __mb()
#define __smp_mb() __mb()
#define __smp_rmb() __rmb()
#define __smp_wmb() __wmb()
#define __smp_store_release(p, v) \
do { \
......
......@@ -369,7 +369,7 @@ void cio_gp_dma_destroy(struct gen_pool *gp_dma, struct device *dma_dev);
struct gen_pool *cio_gp_dma_create(struct device *dma_dev, int nr_pages);
/* Function from drivers/s390/cio/chsc.c */
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta);
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, long *clock_delta);
int chsc_sstpi(void *page, void *result, size_t size);
int chsc_stzi(void *page, void *result, size_t size);
int chsc_sgib(u32 origin);
......
......@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/thread_info.h>
#include <asm/ptrace.h>
#define compat_mode_t compat_mode_t
typedef u16 compat_mode_t;
......@@ -22,32 +23,8 @@ typedef u16 compat_mode_t;
(__force t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \
})
#define PSW32_MASK_PER 0x40000000UL
#define PSW32_MASK_DAT 0x04000000UL
#define PSW32_MASK_IO 0x02000000UL
#define PSW32_MASK_EXT 0x01000000UL
#define PSW32_MASK_KEY 0x00F00000UL
#define PSW32_MASK_BASE 0x00080000UL /* Always one */
#define PSW32_MASK_MCHECK 0x00040000UL
#define PSW32_MASK_WAIT 0x00020000UL
#define PSW32_MASK_PSTATE 0x00010000UL
#define PSW32_MASK_ASC 0x0000C000UL
#define PSW32_MASK_CC 0x00003000UL
#define PSW32_MASK_PM 0x00000f00UL
#define PSW32_MASK_RI 0x00000080UL
#define PSW32_MASK_USER 0x0000FF00UL
#define PSW32_ADDR_AMODE 0x80000000UL
#define PSW32_ADDR_INSN 0x7FFFFFFFUL
#define PSW32_DEFAULT_KEY (((u32) PAGE_DEFAULT_ACC) << 20)
#define PSW32_ASC_PRIMARY 0x00000000UL
#define PSW32_ASC_ACCREG 0x00004000UL
#define PSW32_ASC_SECONDARY 0x00008000UL
#define PSW32_ASC_HOME 0x0000C000UL
#define PSW32_USER_BITS (PSW32_MASK_DAT | PSW32_MASK_IO | PSW32_MASK_EXT | \
PSW32_DEFAULT_KEY | PSW32_MASK_BASE | \
PSW32_MASK_MCHECK | PSW32_MASK_PSTATE | \
......
......@@ -93,7 +93,9 @@ union ctlreg0 {
unsigned long tcx : 1; /* Transactional-Execution control */
unsigned long pifo : 1; /* Transactional-Execution Program-
Interruption-Filtering Override */
unsigned long : 22;
unsigned long : 3;
unsigned long ccc : 1; /* Cryptography counter control */
unsigned long : 18;
unsigned long : 3;
unsigned long lap : 1; /* Low-address-protection control */
unsigned long : 4;
......
......@@ -9,19 +9,21 @@
#include <linux/uaccess.h>
#include <asm/timex.h>
#include <asm/fpu/api.h>
#include <asm/pai.h>
#define ARCH_EXIT_TO_USER_MODE_WORK (_TIF_GUARDED_STORAGE | _TIF_PER_TRAP)
void do_per_trap(struct pt_regs *regs);
#ifdef CONFIG_DEBUG_ENTRY
static __always_inline void arch_check_user_regs(struct pt_regs *regs)
static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs)
{
debug_user_asce(0);
if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
debug_user_asce(0);
pai_kernel_enter(regs);
}
#define arch_check_user_regs arch_check_user_regs
#endif /* CONFIG_DEBUG_ENTRY */
#define arch_enter_from_user_mode arch_enter_from_user_mode
static __always_inline void arch_exit_to_user_mode_work(struct pt_regs *regs,
unsigned long ti_work)
......@@ -44,6 +46,8 @@ static __always_inline void arch_exit_to_user_mode(void)
if (IS_ENABLED(CONFIG_DEBUG_ENTRY))
debug_user_asce(1);
pai_kernel_exit(current_pt_regs());
}
#define arch_exit_to_user_mode arch_exit_to_user_mode
......
......@@ -133,6 +133,8 @@ int ipl_report_add_certificate(struct ipl_report *report, void *key,
* DIAG 308 support
*/
enum diag308_subcode {
DIAG308_CLEAR_RESET = 0,
DIAG308_LOAD_NORMAL_RESET = 1,
DIAG308_REL_HSA = 2,
DIAG308_LOAD_CLEAR = 3,
DIAG308_LOAD_NORMAL_DUMP = 4,
......@@ -141,6 +143,10 @@ enum diag308_subcode {
DIAG308_LOAD_NORMAL = 7,
};
enum diag308_subcode_flags {
DIAG308_FLAG_EI = 1UL << 16,
};
enum diag308_rc {
DIAG308_RC_OK = 0x0001,
DIAG308_RC_NOCONFIG = 0x0102,
......
......@@ -200,7 +200,10 @@ struct lowcore {
__u64 last_break_save_area; /* 0x1338 */
__u32 access_regs_save_area[16]; /* 0x1340 */
__u64 cregs_save_area[16]; /* 0x1380 */
__u8 pad_0x1400[0x1800-0x1400]; /* 0x1400 */
__u8 pad_0x1400[0x1500-0x1400]; /* 0x1400 */
/* Cryptography-counter designation */
__u64 ccd; /* 0x1500 */
__u8 pad_0x1508[0x1800-0x1508]; /* 0x1508 */
/* Transaction abort diagnostic block */
struct pgm_tdb pgm_tdb; /* 0x1800 */
......
......@@ -101,7 +101,7 @@ void nmi_alloc_mcesa_early(u64 *mcesad);
int nmi_alloc_mcesa(u64 *mcesad);
void nmi_free_mcesa(u64 *mcesad);
void s390_handle_mcck(void);
void s390_handle_mcck(struct pt_regs *regs);
void __s390_handle_mcck(void);
int s390_do_machine_check(struct pt_regs *regs);
......
......@@ -54,31 +54,31 @@
.endm
.macro __DECODE_R expand,reg
.set __decode_fail,1
.set .L__decode_fail,1
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.ifc \reg,%r\r1
\expand \r1
.set __decode_fail,0
.set .L__decode_fail,0
.endif
.endr
.if __decode_fail == 1
.if .L__decode_fail == 1
.error "__DECODE_R failed"
.endif
.endm
.macro __DECODE_RR expand,rsave,rtarget
.set __decode_fail,1
.set .L__decode_fail,1
.irp r1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.ifc \rsave,%r\r1
.irp r2,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
.ifc \rtarget,%r\r2
\expand \r1,\r2
.set __decode_fail,0
.set .L__decode_fail,0
.endif
.endr
.endif
.endr
.if __decode_fail == 1
.if .L__decode_fail == 1
.error "__DECODE_RR failed"
.endif
.endm
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Processor Activity Instrumentation support for cryptography counters
*
* Copyright IBM Corp. 2022
* Author(s): Thomas Richter <tmricht@linux.ibm.com>
*/
#ifndef _ASM_S390_PAI_H
#define _ASM_S390_PAI_H
#include <linux/jump_label.h>
#include <asm/lowcore.h>
#include <asm/ptrace.h>
struct qpaci_info_block {
u64 header;
struct {
u64 : 8;
u64 num_cc : 8; /* # of supported crypto counters */
u64 : 48;
};
};
static inline int qpaci(struct qpaci_info_block *info)
{
/* Size of info (in double words minus one) */
size_t size = sizeof(*info) / sizeof(u64) - 1;
int cc;
asm volatile(
" lgr 0,%[size]\n"
" .insn s,0xb28f0000,%[info]\n"
" lgr %[size],0\n"
" ipm %[cc]\n"
" srl %[cc],28\n"
: [cc] "=d" (cc), [info] "=Q" (*info), [size] "+&d" (size)
:
: "0", "cc", "memory");
return cc ? (size + 1) * sizeof(u64) : 0;
}
#define PAI_CRYPTO_BASE 0x1000 /* First event number */
#define PAI_CRYPTO_MAXCTR 256 /* Max # of event counters */
#define PAI_CRYPTO_KERNEL_OFFSET 2048
DECLARE_STATIC_KEY_FALSE(pai_key);
static __always_inline void pai_kernel_enter(struct pt_regs *regs)
{
if (!IS_ENABLED(CONFIG_PERF_EVENTS))
return;
if (!static_branch_unlikely(&pai_key))
return;
if (!S390_lowcore.ccd)
return;
if (!user_mode(regs))
return;
WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd | PAI_CRYPTO_KERNEL_OFFSET);
}
static __always_inline void pai_kernel_exit(struct pt_regs *regs)
{
if (!IS_ENABLED(CONFIG_PERF_EVENTS))
return;
if (!static_branch_unlikely(&pai_key))
return;
if (!S390_lowcore.ccd)
return;
if (!user_mode(regs))
return;
WRITE_ONCE(S390_lowcore.ccd, S390_lowcore.ccd & ~PAI_CRYPTO_KERNEL_OFFSET);
}
#endif
......@@ -17,9 +17,14 @@ extern debug_info_t *pci_debug_err_id;
debug_text_event(pci_debug_err_id, 0, debug_buffer); \
} while (0)
static inline void zpci_err_hex_level(int level, void *addr, int len)
{
debug_event(pci_debug_err_id, level, addr, len);
}
static inline void zpci_err_hex(void *addr, int len)
{
debug_event(pci_debug_err_id, 0, addr, len);
zpci_err_hex_level(0, addr, len);
}
#endif
......@@ -46,10 +46,17 @@ static inline bool test_preempt_need_resched(void)
static inline void __preempt_count_add(int val)
{
if (__builtin_constant_p(val) && (val >= -128) && (val <= 127))
__atomic_add_const(val, &S390_lowcore.preempt_count);
else
__atomic_add(val, &S390_lowcore.preempt_count);
/*
* With some obscure config options and CONFIG_PROFILE_ALL_BRANCHES
* enabled, gcc 12 fails to handle __builtin_constant_p().
*/
if (!IS_ENABLED(CONFIG_PROFILE_ALL_BRANCHES)) {
if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) {
__atomic_add_const(val, &S390_lowcore.preempt_count);
return;
}
}
__atomic_add(val, &S390_lowcore.preempt_count);
}
static inline void __preempt_count_sub(int val)
......
......@@ -83,6 +83,7 @@ void cpu_detect_mhz_feature(void);
extern const struct seq_operations cpuinfo_op;
extern void execve_tail(void);
extern void __bpon(void);
unsigned long vdso_size(void);
/*
* User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
......@@ -94,9 +95,10 @@ extern void __bpon(void);
(_REGION3_SIZE >> 1) : (_REGION2_SIZE >> 1))
#define TASK_SIZE_MAX (-PAGE_SIZE)
#define STACK_TOP (test_thread_flag(TIF_31BIT) ? \
_REGION3_SIZE : _REGION2_SIZE)
#define STACK_TOP_MAX _REGION2_SIZE
#define VDSO_BASE (STACK_TOP + PAGE_SIZE)
#define VDSO_LIMIT (test_thread_flag(TIF_31BIT) ? _REGION3_SIZE : _REGION2_SIZE)
#define STACK_TOP (VDSO_LIMIT - vdso_size() - PAGE_SIZE)
#define STACK_TOP_MAX (_REGION2_SIZE - vdso_size() - PAGE_SIZE)
#define HAVE_ARCH_PICK_MMAP_LAYOUT
......
......@@ -71,6 +71,35 @@ enum {
&(*(struct psw_bits *)(&(__psw))); \
}))
#define PSW32_MASK_PER 0x40000000UL
#define PSW32_MASK_DAT 0x04000000UL
#define PSW32_MASK_IO 0x02000000UL
#define PSW32_MASK_EXT 0x01000000UL
#define PSW32_MASK_KEY 0x00F00000UL
#define PSW32_MASK_BASE 0x00080000UL /* Always one */
#define PSW32_MASK_MCHECK 0x00040000UL
#define PSW32_MASK_WAIT 0x00020000UL
#define PSW32_MASK_PSTATE 0x00010000UL
#define PSW32_MASK_ASC 0x0000C000UL
#define PSW32_MASK_CC 0x00003000UL
#define PSW32_MASK_PM 0x00000f00UL
#define PSW32_MASK_RI 0x00000080UL
#define PSW32_ADDR_AMODE 0x80000000UL
#define PSW32_ADDR_INSN 0x7FFFFFFFUL
#define PSW32_DEFAULT_KEY (((u32)PAGE_DEFAULT_ACC) << 20)
#define PSW32_ASC_PRIMARY 0x00000000UL
#define PSW32_ASC_ACCREG 0x00004000UL
#define PSW32_ASC_SECONDARY 0x00008000UL
#define PSW32_ASC_HOME 0x0000C000UL
typedef struct {
unsigned int mask;
unsigned int addr;
} psw_t32 __aligned(8);
#define PGM_INT_CODE_MASK 0x7f
#define PGM_INT_CODE_PER 0x80
......
......@@ -87,6 +87,7 @@ struct sclp_info {
unsigned char has_diag318 : 1;
unsigned char has_sipl : 1;
unsigned char has_dirq : 1;
unsigned char has_iplcc : 1;
unsigned int ibc;
unsigned int mtid;
unsigned int mtid_cp;
......
......@@ -508,9 +508,21 @@ static inline int scsw_cmd_is_valid_zcc(union scsw *scsw)
*/
static inline int scsw_cmd_is_valid_ectl(union scsw *scsw)
{
return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) &&
!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) &&
(scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS);
/* Must be status pending. */
if (!(scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND))
return 0;
/* Must have alert status. */
if (!(scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS))
return 0;
/* Must be alone or together with primary, secondary or both,
* => no intermediate status.
*/
if (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS)
return 0;
return 1;
}
/**
......@@ -522,10 +534,25 @@ static inline int scsw_cmd_is_valid_ectl(union scsw *scsw)
*/
static inline int scsw_cmd_is_valid_pno(union scsw *scsw)
{
return (scsw->cmd.fctl != 0) &&
(scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) &&
(!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) ||
(scsw->cmd.actl & SCSW_ACTL_SUSPENDED));
/* Must indicate at least one I/O function. */
if (!scsw->cmd.fctl)
return 0;
/* Must be status pending. */
if (!(scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND))
return 0;
/* Can be status pending alone, or with any combination of primary,
* secondary and alert => no intermediate status.
*/
if (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS))
return 1;
/* If intermediate, must be suspended. */
if (scsw->cmd.actl & SCSW_ACTL_SUSPENDED)
return 1;
return 0;
}
/**
......@@ -675,9 +702,21 @@ static inline int scsw_tm_is_valid_q(union scsw *scsw)
*/
static inline int scsw_tm_is_valid_ectl(union scsw *scsw)
{
return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) &&
!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) &&
(scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS);
/* Must be status pending. */
if (!(scsw->tm.stctl & SCSW_STCTL_STATUS_PEND))
return 0;
/* Must have alert status. */
if (!(scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS))
return 0;
/* Must be alone or together with primary, secondary or both,
* => no intermediate status.
*/
if (scsw->tm.stctl & SCSW_STCTL_INTER_STATUS)
return 0;
return 1;
}
/**
......@@ -689,11 +728,25 @@ static inline int scsw_tm_is_valid_ectl(union scsw *scsw)
*/
static inline int scsw_tm_is_valid_pno(union scsw *scsw)
{
return (scsw->tm.fctl != 0) &&
(scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) &&
(!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) ||
((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) &&
(scsw->tm.actl & SCSW_ACTL_SUSPENDED)));
/* Must indicate at least one I/O function. */
if (!scsw->tm.fctl)
return 0;
/* Must be status pending. */
if (!(scsw->tm.stctl & SCSW_STCTL_STATUS_PEND))
return 0;
/* Can be status pending alone, or with any combination of primary,
* secondary and alert => no intermediate status.
*/
if (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS))
return 1;
/* If intermediate, must be suspended. */
if (scsw->tm.actl & SCSW_ACTL_SUSPENDED)
return 1;
return 0;
}
/**
......
......@@ -77,8 +77,9 @@ static inline int arch_spin_trylock(arch_spinlock_t *lp)
static inline void arch_spin_unlock(arch_spinlock_t *lp)
{
typecheck(int, lp->lock);
kcsan_release();
asm_inline volatile(
ALTERNATIVE("", ".insn rre,0xb2fa0000,7,0", 49) /* NIAI 7 */
ALTERNATIVE("nop", ".insn rre,0xb2fa0000,7,0", 49) /* NIAI 7 */
" sth %1,%0\n"
: "=R" (((unsigned short *) &lp->lock)[1])
: "d" (0) : "cc", "memory");
......
......@@ -44,8 +44,8 @@ struct stp_sstpi {
u32 : 32;
u32 ctnid[3];
u32 : 32;
u32 todoff[4];
u32 rsvd[48];
u64 todoff;
u32 rsvd[50];
} __packed;
struct stp_tzib {
......
......@@ -366,7 +366,7 @@
.macro VLM vfrom, vto, disp, base, hint=3
VX_NUM v1, \vfrom
VX_NUM v3, \vto
GR_NUM b2, \base /* Base register */
GR_NUM b2, \base
.word 0xE700 | ((v1&15) << 4) | (v3&15)
.word (b2 << 12) | (\disp)
MRXBOPC \hint, 0x36, v1, v3
......@@ -376,7 +376,7 @@
.macro VST vr1, disp, index="%r0", base
VX_NUM v1, \vr1
GR_NUM x2, \index
GR_NUM b2, \base /* Base register */
GR_NUM b2, \base
.word 0xE700 | ((v1&15) << 4) | (x2&15)
.word (b2 << 12) | (\disp)
MRXBOPC 0, 0x0E, v1
......@@ -386,7 +386,7 @@
.macro VSTM vfrom, vto, disp, base, hint=3
VX_NUM v1, \vfrom
VX_NUM v3, \vto
GR_NUM b2, \base /* Base register */
GR_NUM b2, \base
.word 0xE700 | ((v1&15) << 4) | (v3&15)
.word (b2 << 12) | (\disp)
MRXBOPC \hint, 0x3E, v1, v3
......
......@@ -171,7 +171,7 @@ struct pkey_skey2pkey {
#define PKEY_SKEY2PKEY _IOWR(PKEY_IOCTL_MAGIC, 0x06, struct pkey_skey2pkey)
/*
* Verify the given CCA AES secure key for being able to be useable with
* Verify the given CCA AES secure key for being able to be usable with
* the pkey module. Check for correct key type and check for having at
* least one crypto card being able to handle this key (master key
* or old master key verification pattern matches).
......
......@@ -4,7 +4,7 @@
*
* zcrypt 2.2.1 (user-visible header)
*
* Copyright IBM Corp. 2001, 2019
* Copyright IBM Corp. 2001, 2022
* Author(s): Robert Burroughs
* Eric Rossman (edrossma@us.ibm.com)
*
......@@ -85,7 +85,7 @@ struct ica_rsa_modexpo_crt {
struct CPRBX {
__u16 cprb_len; /* CPRB length 220 */
__u8 cprb_ver_id; /* CPRB version id. 0x02 */
__u8 pad_000[3]; /* Alignment pad bytes */
__u8 _pad_000[3]; /* Alignment pad bytes */
__u8 func_id[2]; /* function id 0x5432 */
__u8 cprb_flags[4]; /* Flags */
__u32 req_parml; /* request parameter buffer len */
......@@ -95,19 +95,19 @@ struct CPRBX {
__u32 rpl_datal; /* reply data block len */
__u32 rpld_datal; /* replied data block len */
__u32 req_extbl; /* request extension block len */
__u8 pad_001[4]; /* reserved */
__u8 _pad_001[4]; /* reserved */
__u32 rpld_extbl; /* replied extension block len */
__u8 padx000[16 - sizeof(__u8 *)];
__u8 _pad_002[16 - sizeof(__u8 *)];
__u8 __user *req_parmb; /* request parm block 'address' */
__u8 padx001[16 - sizeof(__u8 *)];
__u8 _pad_003[16 - sizeof(__u8 *)];
__u8 __user *req_datab; /* request data block 'address' */
__u8 padx002[16 - sizeof(__u8 *)];
__u8 _pad_004[16 - sizeof(__u8 *)];
__u8 __user *rpl_parmb; /* reply parm block 'address' */
__u8 padx003[16 - sizeof(__u8 *)];
__u8 _pad_005[16 - sizeof(__u8 *)];
__u8 __user *rpl_datab; /* reply data block 'address' */
__u8 padx004[16 - sizeof(__u8 *)];
__u8 _pad_006[16 - sizeof(__u8 *)];
__u8 __user *req_extb; /* request extension block 'addr'*/
__u8 padx005[16 - sizeof(__u8 *)];
__u8 _pad_007[16 - sizeof(__u8 *)];
__u8 __user *rpl_extb; /* reply extension block 'address'*/
__u16 ccp_rtcode; /* server return code */
__u16 ccp_rscode; /* server reason code */
......@@ -115,12 +115,10 @@ struct CPRBX {
__u8 logon_id[8]; /* Logon Identifier */
__u8 mac_value[8]; /* Mac Value */
__u8 mac_content_flgs; /* Mac content flag byte */
__u8 pad_002; /* Alignment */
__u8 _pad_008; /* Alignment */
__u16 domain; /* Domain */
__u8 usage_domain[4]; /* Usage domain */
__u8 cntrl_domain[4]; /* Control domain */
__u8 S390enf_mask[4]; /* S/390 enforcement mask */
__u8 pad_004[36]; /* reserved */
__u8 _pad_009[12]; /* reserved, checked for zeros */
__u8 _pad_010[36]; /* reserved */
} __attribute__((packed));
/**
......@@ -238,8 +236,8 @@ struct zcrypt_device_matrix_ext {
};
#define AUTOSELECT 0xFFFFFFFF
#define AUTOSEL_AP ((__u16) 0xFFFF)
#define AUTOSEL_DOM ((__u16) 0xFFFF)
#define AUTOSEL_AP ((__u16)0xFFFF)
#define AUTOSEL_DOM ((__u16)0xFFFF)
#define ZCRYPT_IOCTL_MAGIC 'z'
......@@ -305,12 +303,12 @@ struct zcrypt_device_matrix_ext {
/**
* Supported ioctl calls
*/
#define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0)
#define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
#define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
#define ZSENDEP11CPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0)
#define ICARSAMODEXPO _IOC(_IOC_READ | _IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0)
#define ICARSACRT _IOC(_IOC_READ | _IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
#define ZSECSENDCPRB _IOC(_IOC_READ | _IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
#define ZSENDEP11CPRB _IOC(_IOC_READ | _IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0)
#define ZCRYPT_DEVICE_STATUS _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x5f, 0)
#define ZCRYPT_DEVICE_STATUS _IOC(_IOC_READ | _IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x5f, 0)
#define ZCRYPT_STATUS_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x58, char[MAX_ZDEV_CARDIDS_EXT])
#define ZCRYPT_QDEPTH_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x59, char[MAX_ZDEV_CARDIDS_EXT])
#define ZCRYPT_PERDEV_REQCNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x5a, int[MAX_ZDEV_CARDIDS_EXT])
......@@ -352,7 +350,7 @@ struct zcrypt_device_matrix {
};
/* Deprecated: use ZCRYPT_DEVICE_STATUS */
#define ZDEVICESTATUS _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x4f, 0)
#define ZDEVICESTATUS _IOC(_IOC_READ | _IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x4f, 0)
/* Deprecated: use ZCRYPT_STATUS_MASK */
#define Z90STAT_STATUS_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x48, char[64])
/* Deprecated: use ZCRYPT_QDEPTH_MASK */
......
......@@ -72,6 +72,7 @@ obj-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_arch.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.o perf_cpum_cf_common.o
obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf.o perf_cpum_sf.o
obj-$(CONFIG_PERF_EVENTS) += perf_cpum_cf_events.o perf_regs.o
obj-$(CONFIG_PERF_EVENTS) += perf_pai_crypto.o
obj-$(CONFIG_TRACEPOINTS) += trace.o
obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE)) += uv.o
......
......@@ -7,8 +7,6 @@
#include <asm/facility.h>
#include <asm/nospec-branch.h>
#define MAX_PATCH_LEN (255 - 1)
static int __initdata_or_module alt_instr_disabled;
static int __init disable_alternative_instructions(char *str)
......@@ -19,85 +17,30 @@ static int __init disable_alternative_instructions(char *str)
early_param("noaltinstr", disable_alternative_instructions);
struct brcl_insn {
u16 opc;
s32 disp;
} __packed;
static u16 __initdata_or_module nop16 = 0x0700;
static u32 __initdata_or_module nop32 = 0x47000000;
static struct brcl_insn __initdata_or_module nop48 = {
0xc004, 0
};
static const void *nops[] __initdata_or_module = {
&nop16,
&nop32,
&nop48
};
static void __init_or_module add_jump_padding(void *insns, unsigned int len)
{
struct brcl_insn brcl = {
0xc0f4,
len / 2
};
memcpy(insns, &brcl, sizeof(brcl));
insns += sizeof(brcl);
len -= sizeof(brcl);
while (len > 0) {
memcpy(insns, &nop16, 2);
insns += 2;
len -= 2;
}
}
static void __init_or_module add_padding(void *insns, unsigned int len)
{
if (len > 6)
add_jump_padding(insns, len);
else if (len >= 2)
memcpy(insns, nops[len / 2 - 1], len);
}
static void __init_or_module __apply_alternatives(struct alt_instr *start,
struct alt_instr *end)
{
struct alt_instr *a;
u8 *instr, *replacement;
u8 insnbuf[MAX_PATCH_LEN];
/*
* The scan order should be from start to end. A later scanned
* alternative code can overwrite previously scanned alternative code.
*/
for (a = start; a < end; a++) {
int insnbuf_sz = 0;
instr = (u8 *)&a->instr_offset + a->instr_offset;
replacement = (u8 *)&a->repl_offset + a->repl_offset;
if (!__test_facility(a->facility, alt_stfle_fac_list))
continue;
if (unlikely(a->instrlen % 2 || a->replacementlen % 2)) {
if (unlikely(a->instrlen % 2)) {
WARN_ONCE(1, "cpu alternatives instructions length is "
"odd, skipping patching\n");
continue;
}
memcpy(insnbuf, replacement, a->replacementlen);
insnbuf_sz = a->replacementlen;
if (a->instrlen > a->replacementlen) {
add_padding(insnbuf + a->replacementlen,
a->instrlen - a->replacementlen);
insnbuf_sz += a->instrlen - a->replacementlen;
}
s390_kernel_write(instr, insnbuf, insnbuf_sz);
s390_kernel_write(instr, replacement, a->instrlen);
}
}
......
......@@ -5,69 +5,59 @@
#include <linux/compat.h>
#include <linux/socket.h>
#include <linux/syscalls.h>
#include <asm/ptrace.h>
/* Macro that masks the high order bit of an 32 bit pointer and converts it*/
/* to a 64 bit pointer */
#define A(__x) ((unsigned long)((__x) & 0x7FFFFFFFUL))
#define AA(__x) \
((unsigned long)(__x))
/*
* Macro that masks the high order bit of a 32 bit pointer and
* converts it to a 64 bit pointer.
*/
#define A(__x) ((unsigned long)((__x) & 0x7FFFFFFFUL))
#define AA(__x) ((unsigned long)(__x))
/* Now 32bit compatibility types */
struct ipc_kludge_32 {
__u32 msgp; /* pointer */
__s32 msgtyp;
__u32 msgp; /* pointer */
__s32 msgtyp;
};
/* asm/sigcontext.h */
typedef union
{
__u64 d;
__u32 f;
typedef union {
__u64 d;
__u32 f;
} freg_t32;
typedef struct
{
typedef struct {
unsigned int fpc;
unsigned int pad;
freg_t32 fprs[__NUM_FPRS];
freg_t32 fprs[__NUM_FPRS];
} _s390_fp_regs32;
typedef struct
{
__u32 mask;
__u32 addr;
} _psw_t32 __attribute__ ((aligned(8)));
typedef struct
{
_psw_t32 psw;
typedef struct {
psw_t32 psw;
__u32 gprs[__NUM_GPRS];
__u32 acrs[__NUM_ACRS];
} _s390_regs_common32;
typedef struct
{
typedef struct {
_s390_regs_common32 regs;
_s390_fp_regs32 fpregs;
_s390_fp_regs32 fpregs;
} _sigregs32;
typedef struct
{
__u32 gprs_high[__NUM_GPRS];
__u64 vxrs_low[__NUM_VXRS_LOW];
__vector128 vxrs_high[__NUM_VXRS_HIGH];
__u8 __reserved[128];
typedef struct {
__u32 gprs_high[__NUM_GPRS];
__u64 vxrs_low[__NUM_VXRS_LOW];
__vector128 vxrs_high[__NUM_VXRS_HIGH];
__u8 __reserved[128];
} _sigregs_ext32;
#define _SIGCONTEXT_NSIG32 64
#define _SIGCONTEXT_NSIG_BPW32 32
#define __SIGNAL_FRAMESIZE32 96
#define _SIGMASK_COPY_SIZE32 (sizeof(u32)*2)
#define _SIGMASK_COPY_SIZE32 (sizeof(u32) * 2)
struct sigcontext32
{
struct sigcontext32 {
__u32 oldmask[_COMPAT_NSIG_WORDS];
__u32 sregs; /* pointer */
__u32 sregs; /* pointer */
};
/* asm/signal.h */
......@@ -75,11 +65,11 @@ struct sigcontext32
/* asm/ucontext.h */
struct ucontext32 {
__u32 uc_flags;
__u32 uc_link; /* pointer */
__u32 uc_link; /* pointer */
compat_stack_t uc_stack;
_sigregs32 uc_mcontext;
compat_sigset_t uc_sigmask;
/* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
/* Allow for uc_sigmask growth. Glibc uses a 1024-bit sigset_t. */
unsigned char __unused[128 - sizeof(compat_sigset_t)];
_sigregs_ext32 uc_mcontext_ext;
};
......@@ -88,25 +78,6 @@ struct stat64_emu31;
struct mmap_arg_struct_emu31;
struct fadvise64_64_args;
long compat_sys_s390_chown16(const char __user *filename, u16 user, u16 group);
long compat_sys_s390_lchown16(const char __user *filename, u16 user, u16 group);
long compat_sys_s390_fchown16(unsigned int fd, u16 user, u16 group);
long compat_sys_s390_setregid16(u16 rgid, u16 egid);
long compat_sys_s390_setgid16(u16 gid);
long compat_sys_s390_setreuid16(u16 ruid, u16 euid);
long compat_sys_s390_setuid16(u16 uid);
long compat_sys_s390_setresuid16(u16 ruid, u16 euid, u16 suid);
long compat_sys_s390_getresuid16(u16 __user *ruid, u16 __user *euid, u16 __user *suid);
long compat_sys_s390_setresgid16(u16 rgid, u16 egid, u16 sgid);
long compat_sys_s390_getresgid16(u16 __user *rgid, u16 __user *egid, u16 __user *sgid);
long compat_sys_s390_setfsuid16(u16 uid);
long compat_sys_s390_setfsgid16(u16 gid);
long compat_sys_s390_getgroups16(int gidsetsize, u16 __user *grouplist);
long compat_sys_s390_setgroups16(int gidsetsize, u16 __user *grouplist);
long compat_sys_s390_getuid16(void);
long compat_sys_s390_geteuid16(void);
long compat_sys_s390_getgid16(void);
long compat_sys_s390_getegid16(void);
long compat_sys_s390_truncate64(const char __user *path, u32 high, u32 low);
long compat_sys_s390_ftruncate64(unsigned int fd, u32 high, u32 low);
long compat_sys_s390_pread64(unsigned int fd, char __user *ubuf, compat_size_t count, u32 high, u32 low);
......@@ -118,8 +89,8 @@ long compat_sys_s390_fstat64(unsigned int fd, struct stat64_emu31 __user *statbu
long compat_sys_s390_fstatat64(unsigned int dfd, const char __user *filename, struct stat64_emu31 __user *statbuf, int flag);
long compat_sys_s390_old_mmap(struct mmap_arg_struct_emu31 __user *arg);
long compat_sys_s390_mmap2(struct mmap_arg_struct_emu31 __user *arg);
long compat_sys_s390_read(unsigned int fd, char __user * buf, compat_size_t count);
long compat_sys_s390_write(unsigned int fd, const char __user * buf, compat_size_t count);
long compat_sys_s390_read(unsigned int fd, char __user *buf, compat_size_t count);
long compat_sys_s390_write(unsigned int fd, const char __user *buf, compat_size_t count);
long compat_sys_s390_fadvise64(int fd, u32 high, u32 low, compat_size_t len, int advise);
long compat_sys_s390_fadvise64_64(struct fadvise64_64_args __user *args);
long compat_sys_s390_sync_file_range(int fd, u32 offhigh, u32 offlow, u32 nhigh, u32 nlow, unsigned int flags);
......
......@@ -53,19 +53,19 @@ STACK_INIT = STACK_SIZE - STACK_FRAME_OVERHEAD - __PT_SIZE
_LPP_OFFSET = __LC_LPP
.macro STBEAR address
ALTERNATIVE "", ".insn s,0xb2010000,\address", 193
ALTERNATIVE "nop", ".insn s,0xb2010000,\address", 193
.endm
.macro LBEAR address
ALTERNATIVE "", ".insn s,0xb2000000,\address", 193
ALTERNATIVE "nop", ".insn s,0xb2000000,\address", 193
.endm
.macro LPSWEY address,lpswe
ALTERNATIVE "b \lpswe", ".insn siy,0xeb0000000071,\address,0", 193
ALTERNATIVE "b \lpswe; nopr", ".insn siy,0xeb0000000071,\address,0", 193
.endm
.macro MBEAR reg
ALTERNATIVE "", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
ALTERNATIVE "brcl 0,0", __stringify(mvc __PT_LAST_BREAK(8,\reg),__LC_LAST_BREAK), 193
.endm
.macro CHECK_STACK savearea
......@@ -121,16 +121,16 @@ _LPP_OFFSET = __LC_LPP
.endm
.macro BPOFF
ALTERNATIVE "", ".insn rrf,0xb2e80000,0,0,12,0", 82
ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,12,0", 82
.endm
.macro BPON
ALTERNATIVE "", ".insn rrf,0xb2e80000,0,0,13,0", 82
ALTERNATIVE "nop", ".insn rrf,0xb2e80000,0,0,13,0", 82
.endm
.macro BPENTER tif_ptr,tif_mask
ALTERNATIVE "TSTMSK \tif_ptr,\tif_mask; jz .+8; .insn rrf,0xb2e80000,0,0,13,0", \
"", 82
"j .+12; nop; nop", 82
.endm
.macro BPEXIT tif_ptr,tif_mask
......@@ -172,9 +172,19 @@ _LPP_OFFSET = __LC_LPP
lgr %r14,\reg
larl %r13,\start
slgr %r14,%r13
lghi %r13,\end - \start
clgr %r14,%r13
#ifdef CONFIG_AS_IS_LLVM
clgfrl %r14,.Lrange_size\@
#else
clgfi %r14,\end - \start
#endif
jhe \outside_label
#ifdef CONFIG_AS_IS_LLVM
.section .rodata, "a"
.align 4
.Lrange_size\@:
.long \end - \start
.previous
#endif
.endm
.macro SIEEXIT
......@@ -226,7 +236,7 @@ ENTRY(__switch_to)
aghi %r3,__TASK_pid
mvc __LC_CURRENT_PID(4,%r0),0(%r3) # store pid of next
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
ALTERNATIVE "", "lpp _LPP_OFFSET", 40
ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
BR_EX %r14
ENDPROC(__switch_to)
......@@ -473,10 +483,7 @@ ENTRY(\name)
mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
MBEAR %r11
stmg %r8,%r9,__PT_PSW(%r11)
tm %r8,0x0001 # coming from user space?
jno 1f
lctlg %c1,%c1,__LC_KERNEL_ASCE
1: lgr %r2,%r11 # pass pointer to pt_regs
lgr %r2,%r11 # pass pointer to pt_regs
brasl %r14,\handler
mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
tmhh %r8,0x0001 # returning to user ?
......@@ -602,6 +609,7 @@ ENTRY(mcck_int_handler)
mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
la %r11,STACK_FRAME_OVERHEAD(%r1)
lgr %r2,%r11
lgr %r15,%r1
brasl %r14,s390_handle_mcck
.Lmcck_return:
......@@ -612,7 +620,7 @@ ENTRY(mcck_int_handler)
jno 0f
BPEXIT __TI_flags(%r12),_TIF_ISOLATE_BP
stpt __LC_EXIT_TIMER
0: ALTERNATIVE "", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
0: ALTERNATIVE "nop", __stringify(lghi %r12,__LC_LAST_BREAK_SAVE_AREA),193
LBEAR 0(%r12)
lmg %r11,%r15,__PT_R11(%r11)
LPSWEY __LC_RETURN_MCCK_PSW,__LC_RETURN_MCCK_LPSWE
......@@ -648,7 +656,7 @@ ENTRY(mcck_int_handler)
ENDPROC(mcck_int_handler)
ENTRY(restart_int_handler)
ALTERNATIVE "", "lpp _LPP_OFFSET", 40
ALTERNATIVE "nop", "lpp _LPP_OFFSET", 40
stg %r15,__LC_SAVE_AREA_RESTART
TSTMSK __LC_RESTART_FLAGS,RESTART_FLAG_CTLREGS,4
jz 0f
......
......@@ -205,7 +205,7 @@ static void show_msi_interrupt(struct seq_file *p, int irq)
unsigned long flags;
int cpu;
irq_lock_sparse();
rcu_read_lock();
desc = irq_to_desc(irq);
if (!desc)
goto out;
......@@ -224,7 +224,7 @@ static void show_msi_interrupt(struct seq_file *p, int irq)
seq_putc(p, '\n');
raw_spin_unlock_irqrestore(&desc->lock, flags);
out:
irq_unlock_sparse();
rcu_read_unlock();
}
/*
......
......@@ -26,8 +26,10 @@
#include <asm/stacktrace.h>
#include <asm/switch_to.h>
#include <asm/nmi.h>
#include <asm/sclp.h>
typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long);
typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long,
unsigned long);
extern const unsigned char relocate_kernel[];
extern const unsigned long long relocate_kernel_len;
......@@ -243,6 +245,7 @@ void machine_crash_shutdown(struct pt_regs *regs)
*/
static void __do_machine_kexec(void *data)
{
unsigned long diag308_subcode;
relocate_kernel_t data_mover;
struct kimage *image = data;
......@@ -251,7 +254,10 @@ static void __do_machine_kexec(void *data)
__arch_local_irq_stnsm(0xfb); /* disable DAT - avoid no-execute */
/* Call the moving routine */
(*data_mover)(&image->head, image->start);
diag308_subcode = DIAG308_CLEAR_RESET;
if (sclp.has_iplcc)
diag308_subcode |= DIAG308_FLAG_EI;
(*data_mover)(&image->head, image->start, diag308_subcode);
/* Die if kexec returns */
disabled_wait();
......
......@@ -29,6 +29,8 @@
#include <asm/switch_to.h>
#include <asm/ctl_reg.h>
#include <asm/asm-offsets.h>
#include <asm/pai.h>
#include <linux/kvm_host.h>
struct mcck_struct {
......@@ -169,10 +171,12 @@ void __s390_handle_mcck(void)
}
}
void noinstr s390_handle_mcck(void)
void noinstr s390_handle_mcck(struct pt_regs *regs)
{
trace_hardirqs_off();
pai_kernel_enter(regs);
__s390_handle_mcck();
pai_kernel_exit(regs);
trace_hardirqs_on();
}
/*
......
......@@ -295,6 +295,76 @@ CPUMF_EVENT_ATTR(cf_z15, DFLT_CC, 0x00108);
CPUMF_EVENT_ATTR(cf_z15, DFLT_CCFINISH, 0x00109);
CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0);
CPUMF_EVENT_ATTR(cf_z15, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1);
CPUMF_EVENT_ATTR(cf_z16, L1D_RO_EXCL_WRITES, 0x0080);
CPUMF_EVENT_ATTR(cf_z16, DTLB2_WRITES, 0x0081);
CPUMF_EVENT_ATTR(cf_z16, DTLB2_MISSES, 0x0082);
CPUMF_EVENT_ATTR(cf_z16, CRSTE_1MB_WRITES, 0x0083);
CPUMF_EVENT_ATTR(cf_z16, DTLB2_GPAGE_WRITES, 0x0084);
CPUMF_EVENT_ATTR(cf_z16, ITLB2_WRITES, 0x0086);
CPUMF_EVENT_ATTR(cf_z16, ITLB2_MISSES, 0x0087);
CPUMF_EVENT_ATTR(cf_z16, TLB2_PTE_WRITES, 0x0089);
CPUMF_EVENT_ATTR(cf_z16, TLB2_CRSTE_WRITES, 0x008a);
CPUMF_EVENT_ATTR(cf_z16, TLB2_ENGINES_BUSY, 0x008b);
CPUMF_EVENT_ATTR(cf_z16, TX_C_TEND, 0x008c);
CPUMF_EVENT_ATTR(cf_z16, TX_NC_TEND, 0x008d);
CPUMF_EVENT_ATTR(cf_z16, L1C_TLB2_MISSES, 0x008f);
CPUMF_EVENT_ATTR(cf_z16, DCW_REQ, 0x0091);
CPUMF_EVENT_ATTR(cf_z16, DCW_REQ_IV, 0x0092);
CPUMF_EVENT_ATTR(cf_z16, DCW_REQ_CHIP_HIT, 0x0093);
CPUMF_EVENT_ATTR(cf_z16, DCW_REQ_DRAWER_HIT, 0x0094);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP, 0x0095);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_IV, 0x0096);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_CHIP_HIT, 0x0097);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_DRAWER_HIT, 0x0098);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_MODULE, 0x0099);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_DRAWER, 0x009a);
CPUMF_EVENT_ATTR(cf_z16, DCW_OFF_DRAWER, 0x009b);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_CHIP_MEMORY, 0x009c);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_MODULE_MEMORY, 0x009d);
CPUMF_EVENT_ATTR(cf_z16, DCW_ON_DRAWER_MEMORY, 0x009e);
CPUMF_EVENT_ATTR(cf_z16, DCW_OFF_DRAWER_MEMORY, 0x009f);
CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_MODULE_IV, 0x00a0);
CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_MODULE_CHIP_HIT, 0x00a1);
CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_MODULE_DRAWER_HIT, 0x00a2);
CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_DRAWER_IV, 0x00a3);
CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_DRAWER_CHIP_HIT, 0x00a4);
CPUMF_EVENT_ATTR(cf_z16, IDCW_ON_DRAWER_DRAWER_HIT, 0x00a5);
CPUMF_EVENT_ATTR(cf_z16, IDCW_OFF_DRAWER_IV, 0x00a6);
CPUMF_EVENT_ATTR(cf_z16, IDCW_OFF_DRAWER_CHIP_HIT, 0x00a7);
CPUMF_EVENT_ATTR(cf_z16, IDCW_OFF_DRAWER_DRAWER_HIT, 0x00a8);
CPUMF_EVENT_ATTR(cf_z16, ICW_REQ, 0x00a9);
CPUMF_EVENT_ATTR(cf_z16, ICW_REQ_IV, 0x00aa);
CPUMF_EVENT_ATTR(cf_z16, ICW_REQ_CHIP_HIT, 0x00ab);
CPUMF_EVENT_ATTR(cf_z16, ICW_REQ_DRAWER_HIT, 0x00ac);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP, 0x00ad);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_IV, 0x00ae);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_CHIP_HIT, 0x00af);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_DRAWER_HIT, 0x00b0);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_MODULE, 0x00b1);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_DRAWER, 0x00b2);
CPUMF_EVENT_ATTR(cf_z16, ICW_OFF_DRAWER, 0x00b3);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_CHIP_MEMORY, 0x00b4);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_MODULE_MEMORY, 0x00b5);
CPUMF_EVENT_ATTR(cf_z16, ICW_ON_DRAWER_MEMORY, 0x00b6);
CPUMF_EVENT_ATTR(cf_z16, ICW_OFF_DRAWER_MEMORY, 0x00b7);
CPUMF_EVENT_ATTR(cf_z16, BCD_DFP_EXECUTION_SLOTS, 0x00e0);
CPUMF_EVENT_ATTR(cf_z16, VX_BCD_EXECUTION_SLOTS, 0x00e1);
CPUMF_EVENT_ATTR(cf_z16, DECIMAL_INSTRUCTIONS, 0x00e2);
CPUMF_EVENT_ATTR(cf_z16, LAST_HOST_TRANSLATIONS, 0x00e8);
CPUMF_EVENT_ATTR(cf_z16, TX_NC_TABORT, 0x00f4);
CPUMF_EVENT_ATTR(cf_z16, TX_C_TABORT_NO_SPECIAL, 0x00f5);
CPUMF_EVENT_ATTR(cf_z16, TX_C_TABORT_SPECIAL, 0x00f6);
CPUMF_EVENT_ATTR(cf_z16, DFLT_ACCESS, 0x00f8);
CPUMF_EVENT_ATTR(cf_z16, DFLT_CYCLES, 0x00fd);
CPUMF_EVENT_ATTR(cf_z16, SORTL, 0x0100);
CPUMF_EVENT_ATTR(cf_z16, DFLT_CC, 0x0109);
CPUMF_EVENT_ATTR(cf_z16, DFLT_CCFINISH, 0x010a);
CPUMF_EVENT_ATTR(cf_z16, NNPA_INVOCATIONS, 0x010b);
CPUMF_EVENT_ATTR(cf_z16, NNPA_COMPLETIONS, 0x010c);
CPUMF_EVENT_ATTR(cf_z16, NNPA_WAIT_LOCK, 0x010d);
CPUMF_EVENT_ATTR(cf_z16, NNPA_HOLD_LOCK, 0x010e);
CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_ONE_THR_ACTIVE, 0x01c0);
CPUMF_EVENT_ATTR(cf_z16, MT_DIAG_CYCLES_TWO_THR_ACTIVE, 0x01c1);
static struct attribute *cpumcf_fvn1_pmu_event_attr[] __initdata = {
CPUMF_EVENT_PTR(cf_fvn1, CPU_CYCLES),
......@@ -635,6 +705,80 @@ static struct attribute *cpumcf_z15_pmu_event_attr[] __initdata = {
NULL,
};
static struct attribute *cpumcf_z16_pmu_event_attr[] __initdata = {
CPUMF_EVENT_PTR(cf_z16, L1D_RO_EXCL_WRITES),
CPUMF_EVENT_PTR(cf_z16, DTLB2_WRITES),
CPUMF_EVENT_PTR(cf_z16, DTLB2_MISSES),
CPUMF_EVENT_PTR(cf_z16, CRSTE_1MB_WRITES),
CPUMF_EVENT_PTR(cf_z16, DTLB2_GPAGE_WRITES),
CPUMF_EVENT_PTR(cf_z16, ITLB2_WRITES),
CPUMF_EVENT_PTR(cf_z16, ITLB2_MISSES),
CPUMF_EVENT_PTR(cf_z16, TLB2_PTE_WRITES),
CPUMF_EVENT_PTR(cf_z16, TLB2_CRSTE_WRITES),
CPUMF_EVENT_PTR(cf_z16, TLB2_ENGINES_BUSY),
CPUMF_EVENT_PTR(cf_z16, TX_C_TEND),
CPUMF_EVENT_PTR(cf_z16, TX_NC_TEND),
CPUMF_EVENT_PTR(cf_z16, L1C_TLB2_MISSES),
CPUMF_EVENT_PTR(cf_z16, DCW_REQ),
CPUMF_EVENT_PTR(cf_z16, DCW_REQ_IV),
CPUMF_EVENT_PTR(cf_z16, DCW_REQ_CHIP_HIT),
CPUMF_EVENT_PTR(cf_z16, DCW_REQ_DRAWER_HIT),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_IV),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_CHIP_HIT),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_DRAWER_HIT),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_MODULE),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_DRAWER),
CPUMF_EVENT_PTR(cf_z16, DCW_OFF_DRAWER),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_CHIP_MEMORY),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_MODULE_MEMORY),
CPUMF_EVENT_PTR(cf_z16, DCW_ON_DRAWER_MEMORY),
CPUMF_EVENT_PTR(cf_z16, DCW_OFF_DRAWER_MEMORY),
CPUMF_EVENT_PTR(cf_z16, IDCW_ON_MODULE_IV),
CPUMF_EVENT_PTR(cf_z16, IDCW_ON_MODULE_CHIP_HIT),
CPUMF_EVENT_PTR(cf_z16, IDCW_ON_MODULE_DRAWER_HIT),
CPUMF_EVENT_PTR(cf_z16, IDCW_ON_DRAWER_IV),
CPUMF_EVENT_PTR(cf_z16, IDCW_ON_DRAWER_CHIP_HIT),
CPUMF_EVENT_PTR(cf_z16, IDCW_ON_DRAWER_DRAWER_HIT),
CPUMF_EVENT_PTR(cf_z16, IDCW_OFF_DRAWER_IV),
CPUMF_EVENT_PTR(cf_z16, IDCW_OFF_DRAWER_CHIP_HIT),
CPUMF_EVENT_PTR(cf_z16, IDCW_OFF_DRAWER_DRAWER_HIT),
CPUMF_EVENT_PTR(cf_z16, ICW_REQ),
CPUMF_EVENT_PTR(cf_z16, ICW_REQ_IV),
CPUMF_EVENT_PTR(cf_z16, ICW_REQ_CHIP_HIT),
CPUMF_EVENT_PTR(cf_z16, ICW_REQ_DRAWER_HIT),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_IV),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_CHIP_HIT),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_DRAWER_HIT),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_MODULE),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_DRAWER),
CPUMF_EVENT_PTR(cf_z16, ICW_OFF_DRAWER),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_CHIP_MEMORY),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_MODULE_MEMORY),
CPUMF_EVENT_PTR(cf_z16, ICW_ON_DRAWER_MEMORY),
CPUMF_EVENT_PTR(cf_z16, ICW_OFF_DRAWER_MEMORY),
CPUMF_EVENT_PTR(cf_z16, BCD_DFP_EXECUTION_SLOTS),
CPUMF_EVENT_PTR(cf_z16, VX_BCD_EXECUTION_SLOTS),
CPUMF_EVENT_PTR(cf_z16, DECIMAL_INSTRUCTIONS),
CPUMF_EVENT_PTR(cf_z16, LAST_HOST_TRANSLATIONS),
CPUMF_EVENT_PTR(cf_z16, TX_NC_TABORT),
CPUMF_EVENT_PTR(cf_z16, TX_C_TABORT_NO_SPECIAL),
CPUMF_EVENT_PTR(cf_z16, TX_C_TABORT_SPECIAL),
CPUMF_EVENT_PTR(cf_z16, DFLT_ACCESS),
CPUMF_EVENT_PTR(cf_z16, DFLT_CYCLES),
CPUMF_EVENT_PTR(cf_z16, SORTL),
CPUMF_EVENT_PTR(cf_z16, DFLT_CC),
CPUMF_EVENT_PTR(cf_z16, DFLT_CCFINISH),
CPUMF_EVENT_PTR(cf_z16, NNPA_INVOCATIONS),
CPUMF_EVENT_PTR(cf_z16, NNPA_COMPLETIONS),
CPUMF_EVENT_PTR(cf_z16, NNPA_WAIT_LOCK),
CPUMF_EVENT_PTR(cf_z16, NNPA_HOLD_LOCK),
CPUMF_EVENT_PTR(cf_z16, MT_DIAG_CYCLES_ONE_THR_ACTIVE),
CPUMF_EVENT_PTR(cf_z16, MT_DIAG_CYCLES_TWO_THR_ACTIVE),
NULL,
};
/* END: CPUM_CF COUNTER DEFINITIONS ===================================== */
static struct attribute_group cpumcf_pmu_events_group = {
......@@ -749,6 +893,10 @@ __init const struct attribute_group **cpumf_cf_event_group(void)
case 0x8562:
model = cpumcf_z15_pmu_event_attr;
break;
case 0x3931:
case 0x3932:
model = cpumcf_z16_pmu_event_attr;
break;
default:
model = none;
break;
......
This diff is collapsed.
......@@ -14,6 +14,7 @@
* moves the new kernel to its destination...
* %r2 = pointer to first kimage_entry_t
* %r3 = start address - where to jump to after the job is done...
* %r4 = subcode
*
* %r5 will be used as temp. storage
* %r6 holds the destination address
......@@ -56,7 +57,7 @@ ENTRY(relocate_kernel)
jo 0b
j .base
.done:
sgr %r0,%r0 # clear register r0
lgr %r0,%r4 # subcode
cghi %r3,0
je .diag
la %r4,load_psw-.base(%r13) # load psw-address into the register
......
......@@ -494,7 +494,7 @@ static void __init setup_lowcore_dat_off(void)
lc->return_mcck_lpswe = gen_lpswe(__LC_RETURN_MCCK_PSW);
lc->preempt_count = PREEMPT_DISABLED;
set_prefix((u32)(unsigned long) lc);
set_prefix(__pa(lc));
lowcore_ptr[0] = lc;
}
......
......@@ -364,7 +364,7 @@ static inline int check_sync_clock(void)
* Apply clock delta to the global data structures.
* This is called once on the CPU that performed the clock sync.
*/
static void clock_sync_global(unsigned long delta)
static void clock_sync_global(long delta)
{
unsigned long now, adj;
struct ptff_qto qto;
......@@ -400,7 +400,7 @@ static void clock_sync_global(unsigned long delta)
* Apply clock delta to the per-CPU data structures of this CPU.
* This is called for each online CPU after the call to clock_sync_global.
*/
static void clock_sync_local(unsigned long delta)
static void clock_sync_local(long delta)
{
/* Add the delta to the clock comparator. */
if (S390_lowcore.clock_comparator != clock_comparator_max) {
......@@ -424,7 +424,7 @@ static void __init time_init_wq(void)
struct clock_sync_data {
atomic_t cpus;
int in_sync;
unsigned long clock_delta;
long clock_delta;
};
/*
......@@ -544,7 +544,7 @@ static int stpinfo_valid(void)
static int stp_sync_clock(void *data)
{
struct clock_sync_data *sync = data;
u64 clock_delta, flags;
long clock_delta, flags;
static int first;
int rc;
......@@ -554,9 +554,7 @@ static int stp_sync_clock(void *data)
while (atomic_read(&sync->cpus) != 0)
cpu_relax();
rc = 0;
if (stp_info.todoff[0] || stp_info.todoff[1] ||
stp_info.todoff[2] || stp_info.todoff[3] ||
stp_info.tmd != 2) {
if (stp_info.todoff || stp_info.tmd != 2) {
flags = vdso_update_begin();
rc = chsc_sstpc(stp_page, STP_OP_SYNC, 0,
&clock_delta);
......
......@@ -16,6 +16,7 @@
#include <linux/slab.h>
#include <linux/smp.h>
#include <linux/time_namespace.h>
#include <linux/random.h>
#include <vdso/datapage.h>
#include <asm/vdso.h>
......@@ -160,10 +161,9 @@ int vdso_getcpu_init(void)
}
early_initcall(vdso_getcpu_init); /* Must be called before SMP init */
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
static int map_vdso(unsigned long addr, unsigned long vdso_mapping_len)
{
unsigned long vdso_text_len, vdso_mapping_len;
unsigned long vvar_start, vdso_text_start;
unsigned long vvar_start, vdso_text_start, vdso_text_len;
struct vm_special_mapping *vdso_mapping;
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
......@@ -180,8 +180,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
vdso_text_len = vdso64_end - vdso64_start;
vdso_mapping = &vdso64_mapping;
}
vdso_mapping_len = vdso_text_len + VVAR_NR_PAGES * PAGE_SIZE;
vvar_start = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
vvar_start = get_unmapped_area(NULL, addr, vdso_mapping_len, 0, 0);
rc = vvar_start;
if (IS_ERR_VALUE(vvar_start))
goto out;
......@@ -210,6 +209,52 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
return rc;
}
static unsigned long vdso_addr(unsigned long start, unsigned long len)
{
unsigned long addr, end, offset;
/*
* Round up the start address. It can start out unaligned as a result
* of stack start randomization.
*/
start = PAGE_ALIGN(start);
/* Round the lowest possible end address up to a PMD boundary. */
end = (start + len + PMD_SIZE - 1) & PMD_MASK;
if (end >= VDSO_BASE)
end = VDSO_BASE;
end -= len;
if (end > start) {
offset = get_random_int() % (((end - start) >> PAGE_SHIFT) + 1);
addr = start + (offset << PAGE_SHIFT);
} else {
addr = start;
}
return addr;
}
unsigned long vdso_size(void)
{
unsigned long size = VVAR_NR_PAGES * PAGE_SIZE;
if (is_compat_task())
size += vdso32_end - vdso32_start;
else
size += vdso64_end - vdso64_start;
return PAGE_ALIGN(size);
}
int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
{
unsigned long addr = VDSO_BASE;
unsigned long size = vdso_size();
if (current->flags & PF_RANDOMIZE)
addr = vdso_addr(current->mm->start_stack + PAGE_SIZE, size);
return map_vdso(addr, size);
}
static struct page ** __init vdso_setup_pages(void *start, void *end)
{
int pages = (end - start) >> PAGE_SHIFT;
......
......@@ -11,7 +11,6 @@
#include <linux/kvm.h>
#include <linux/gfp.h>
#include <linux/errno.h>
#include <linux/compat.h>
#include <linux/mm_types.h>
#include <linux/pgtable.h>
......
......@@ -75,7 +75,7 @@ static inline int arch_load_niai4(int *lock)
int owner;
asm_inline volatile(
ALTERNATIVE("", ".insn rre,0xb2fa0000,4,0", 49) /* NIAI 4 */
ALTERNATIVE("nop", ".insn rre,0xb2fa0000,4,0", 49) /* NIAI 4 */
" l %0,%1\n"
: "=d" (owner) : "Q" (*lock) : "memory");
return owner;
......@@ -86,7 +86,7 @@ static inline int arch_cmpxchg_niai8(int *lock, int old, int new)
int expected = old;
asm_inline volatile(
ALTERNATIVE("", ".insn rre,0xb2fa0000,8,0", 49) /* NIAI 8 */
ALTERNATIVE("nop", ".insn rre,0xb2fa0000,8,0", 49) /* NIAI 8 */
" cs %0,%3,%1\n"
: "=d" (old), "=Q" (*lock)
: "0" (old), "d" (new), "Q" (*lock)
......
......@@ -58,9 +58,9 @@ static inline unsigned long mmap_base(unsigned long rnd,
/*
* Top of mmap area (just below the process stack).
* Leave at least a ~32 MB hole.
* Leave at least a ~128 MB hole.
*/
gap_min = 32 * 1024 * 1024UL;
gap_min = SZ_128M;
gap_max = (STACK_TOP / 6) * 5;
if (gap < gap_min)
......
......@@ -799,7 +799,7 @@ struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state)
struct zpci_dev *zdev;
int rc;
zpci_dbg(3, "add fid:%x, fh:%x, c:%d\n", fid, fh, state);
zpci_dbg(1, "add fid:%x, fh:%x, c:%d\n", fid, fh, state);
zdev = kzalloc(sizeof(*zdev), GFP_KERNEL);
if (!zdev)
return ERR_PTR(-ENOMEM);
......
......@@ -30,7 +30,7 @@ bool zpci_unique_uid;
void update_uid_checking(bool new)
{
if (zpci_unique_uid != new)
zpci_dbg(1, "uid checking:%d\n", new);
zpci_dbg(3, "uid checking:%d\n", new);
zpci_unique_uid = new;
}
......
......@@ -196,7 +196,7 @@ int __init zpci_debug_init(void)
if (!pci_debug_err_id)
return -EINVAL;
debug_register_view(pci_debug_err_id, &debug_hex_ascii_view);
debug_set_level(pci_debug_err_id, 6);
debug_set_level(pci_debug_err_id, 3);
debugfs_root = debugfs_create_dir("pci", NULL);
return 0;
......
......@@ -321,9 +321,6 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
zpci_dbg(3, "avl fid:%x, fh:%x, pec:%x\n",
ccdf->fid, ccdf->fh, ccdf->pec);
zpci_err("avail CCDF:\n");
zpci_err_hex(ccdf, sizeof(*ccdf));
switch (ccdf->pec) {
case 0x0301: /* Reserved|Standby -> Configured */
if (!zdev) {
......
......@@ -18,16 +18,40 @@
#define ZPCI_INSN_BUSY_DELAY 1 /* 1 microsecond */
static inline void zpci_err_insn(u8 cc, u8 status, u64 req, u64 offset)
struct zpci_err_insn_data {
u8 insn;
u8 cc;
u8 status;
union {
struct {
u64 req;
u64 offset;
};
struct {
u64 addr;
u64 len;
};
};
} __packed;
static inline void zpci_err_insn_req(int lvl, u8 insn, u8 cc, u8 status,
u64 req, u64 offset)
{
struct {
u64 req;
u64 offset;
u8 cc;
u8 status;
} __packed data = {req, offset, cc, status};
zpci_err_hex(&data, sizeof(data));
struct zpci_err_insn_data data = {
.insn = insn, .cc = cc, .status = status,
.req = req, .offset = offset};
zpci_err_hex_level(lvl, &data, sizeof(data));
}
static inline void zpci_err_insn_addr(int lvl, u8 insn, u8 cc, u8 status,
u64 addr, u64 len)
{
struct zpci_err_insn_data data = {
.insn = insn, .cc = cc, .status = status,
.addr = addr, .len = len};
zpci_err_hex_level(lvl, &data, sizeof(data));
}
/* Modify PCI Function Controls */
......@@ -47,16 +71,24 @@ static inline u8 __mpcifc(u64 req, struct zpci_fib *fib, u8 *status)
u8 zpci_mod_fc(u64 req, struct zpci_fib *fib, u8 *status)
{
bool retried = false;
u8 cc;
do {
cc = __mpcifc(req, fib, status);
if (cc == 2)
if (cc == 2) {
msleep(ZPCI_INSN_BUSY_DELAY);
if (!retried) {
zpci_err_insn_req(1, 'M', cc, *status, req, 0);
retried = true;
}
}
} while (cc == 2);
if (cc)
zpci_err_insn(cc, *status, req, 0);
zpci_err_insn_req(0, 'M', cc, *status, req, 0);
else if (retried)
zpci_err_insn_req(1, 'M', cc, *status, req, 0);
return cc;
}
......@@ -80,16 +112,24 @@ static inline u8 __rpcit(u64 fn, u64 addr, u64 range, u8 *status)
int zpci_refresh_trans(u64 fn, u64 addr, u64 range)
{
bool retried = false;
u8 cc, status;
do {
cc = __rpcit(fn, addr, range, &status);
if (cc == 2)
if (cc == 2) {
udelay(ZPCI_INSN_BUSY_DELAY);
if (!retried) {
zpci_err_insn_addr(1, 'R', cc, status, addr, range);
retried = true;
}
}
} while (cc == 2);
if (cc)
zpci_err_insn(cc, status, addr, range);
zpci_err_insn_addr(0, 'R', cc, status, addr, range);
else if (retried)
zpci_err_insn_addr(1, 'R', cc, status, addr, range);
if (cc == 1 && (status == 4 || status == 16))
return -ENOMEM;
......@@ -144,17 +184,25 @@ static inline int __pcilg(u64 *data, u64 req, u64 offset, u8 *status)
int __zpci_load(u64 *data, u64 req, u64 offset)
{
bool retried = false;
u8 status;
int cc;
do {
cc = __pcilg(data, req, offset, &status);
if (cc == 2)
if (cc == 2) {
udelay(ZPCI_INSN_BUSY_DELAY);
if (!retried) {
zpci_err_insn_req(1, 'l', cc, status, req, offset);
retried = true;
}
}
} while (cc == 2);
if (cc)
zpci_err_insn(cc, status, req, offset);
zpci_err_insn_req(0, 'l', cc, status, req, offset);
else if (retried)
zpci_err_insn_req(1, 'l', cc, status, req, offset);
return (cc > 0) ? -EIO : cc;
}
......@@ -198,7 +246,7 @@ int zpci_load(u64 *data, const volatile void __iomem *addr, unsigned long len)
cc = __pcilg_mio(data, (__force u64) addr, len, &status);
if (cc)
zpci_err_insn(cc, status, 0, (__force u64) addr);
zpci_err_insn_addr(0, 'L', cc, status, (__force u64) addr, len);
return (cc > 0) ? -EIO : cc;
}
......@@ -225,17 +273,25 @@ static inline int __pcistg(u64 data, u64 req, u64 offset, u8 *status)
int __zpci_store(u64 data, u64 req, u64 offset)
{
bool retried = false;
u8 status;
int cc;
do {
cc = __pcistg(data, req, offset, &status);
if (cc == 2)
if (cc == 2) {
udelay(ZPCI_INSN_BUSY_DELAY);
if (!retried) {
zpci_err_insn_req(1, 's', cc, status, req, offset);
retried = true;
}
}
} while (cc == 2);
if (cc)
zpci_err_insn(cc, status, req, offset);
zpci_err_insn_req(0, 's', cc, status, req, offset);
else if (retried)
zpci_err_insn_req(1, 's', cc, status, req, offset);
return (cc > 0) ? -EIO : cc;
}
......@@ -278,7 +334,7 @@ int zpci_store(const volatile void __iomem *addr, u64 data, unsigned long len)
cc = __pcistg_mio(data, (__force u64) addr, len, &status);
if (cc)
zpci_err_insn(cc, status, 0, (__force u64) addr);
zpci_err_insn_addr(0, 'S', cc, status, (__force u64) addr, len);
return (cc > 0) ? -EIO : cc;
}
......@@ -304,17 +360,25 @@ static inline int __pcistb(const u64 *data, u64 req, u64 offset, u8 *status)
int __zpci_store_block(const u64 *data, u64 req, u64 offset)
{
bool retried = false;
u8 status;
int cc;
do {
cc = __pcistb(data, req, offset, &status);
if (cc == 2)
if (cc == 2) {
udelay(ZPCI_INSN_BUSY_DELAY);
if (!retried) {
zpci_err_insn_req(0, 'b', cc, status, req, offset);
retried = true;
}
}
} while (cc == 2);
if (cc)
zpci_err_insn(cc, status, req, offset);
zpci_err_insn_req(0, 'b', cc, status, req, offset);
else if (retried)
zpci_err_insn_req(1, 'b', cc, status, req, offset);
return (cc > 0) ? -EIO : cc;
}
......@@ -358,7 +422,7 @@ int zpci_write_block(volatile void __iomem *dst,
cc = __pcistb_mio(src, (__force u64) dst, len, &status);
if (cc)
zpci_err_insn(cc, status, 0, (__force u64) dst);
zpci_err_insn_addr(0, 'B', cc, status, (__force u64) dst, len);
return (cc > 0) ? -EIO : cc;
}
......
......@@ -44,11 +44,14 @@
.endm
.macro MEMSWAP dst,src,buf,len
10: cghi \len,bufsz
10: larl %r0,purgatory_end
larl %r1,stack
slgr %r0,%r1
cgr \len,%r0
jh 11f
lgr %r4,\len
j 12f
11: lghi %r4,bufsz
11: lgr %r4,%r0
12: MEMCPY \buf,\dst,%r4
MEMCPY \dst,\src,%r4
......@@ -135,12 +138,18 @@ ENTRY(purgatory_start)
.start_crash_kernel:
/* Location of purgatory_start in crash memory */
larl %r0,.base_crash
larl %r1,purgatory_start
slgr %r0,%r1
lgr %r8,%r13
aghi %r8,-(.base_crash-purgatory_start)
sgr %r8,%r0
/* Destination for this code i.e. end of memory to be swapped. */
larl %r0,purgatory_end
larl %r1,purgatory_start
slgr %r0,%r1
lg %r9,crash_size-.base_crash(%r13)
aghi %r9,-(purgatory_end-purgatory_start)
sgr %r9,%r0
/* Destination in crash memory, i.e. same as r9 but in crash memory. */
lg %r10,crash_start-.base_crash(%r13)
......@@ -149,15 +158,19 @@ ENTRY(purgatory_start)
/* 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 %r11,purgatory_end
larl %r12,stack
slgr %r11,%r12
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
larl %r0,.jump_to_dst
larl %r1,purgatory_start
slgr %r0,%r1
agr %r7,%r0
br %r7
.jump_to_dst:
......@@ -169,7 +182,10 @@ ENTRY(purgatory_start)
/* Load new buffer location after jump */
larl %r7,stack
aghi %r10,stack-purgatory_start
lgr %r0,%r7
larl %r1,purgatory_start
slgr %r0,%r1
agr %r10,%r0
MEMCPY %r10,%r7,%r11 /* (new) buf -> (crash) buf */
/* Now the code is set up to run from its designated location. Start
......
......@@ -10,7 +10,7 @@
#include <asm/fpu/api.h>
/* Check that the stack and regs on entry from user mode are sane. */
static __always_inline void arch_check_user_regs(struct pt_regs *regs)
static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs)
{
if (IS_ENABLED(CONFIG_DEBUG_ENTRY)) {
/*
......@@ -42,7 +42,7 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs)
WARN_ON_ONCE(regs != task_pt_regs(current));
}
}
#define arch_check_user_regs arch_check_user_regs
#define arch_enter_from_user_mode arch_enter_from_user_mode
static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
unsigned long ti_work)
......
......@@ -771,35 +771,36 @@ static struct tty_driver *con3215_device(struct console *c, int *index)
}
/*
* panic() calls con3215_flush through a panic_notifier
* before the system enters a disabled, endless loop.
* The below function is called as a panic/reboot notifier before the
* system enters a disabled, endless loop.
*
* Notice we must use the spin_trylock() alternative, to prevent lockups
* in atomic context (panic routine runs with secondary CPUs, local IRQs
* and preemption disabled).
*/
static void con3215_flush(void)
static int con3215_notify(struct notifier_block *self,
unsigned long event, void *data)
{
struct raw3215_info *raw;
unsigned long flags;
raw = raw3215[0]; /* console 3215 is the first one */
spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
if (!spin_trylock_irqsave(get_ccwdev_lock(raw->cdev), flags))
return NOTIFY_DONE;
raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
static int con3215_notify(struct notifier_block *self,
unsigned long event, void *data)
{
con3215_flush();
return NOTIFY_OK;
return NOTIFY_DONE;
}
static struct notifier_block on_panic_nb = {
.notifier_call = con3215_notify,
.priority = 0,
.priority = INT_MIN + 1, /* run the callback late */
};
static struct notifier_block on_reboot_nb = {
.notifier_call = con3215_notify,
.priority = 0,
.priority = INT_MIN + 1, /* run the callback late */
};
/*
......
......@@ -535,20 +535,26 @@ con3270_wait_write(struct con3270 *cp)
}
/*
* panic() calls con3270_flush through a panic_notifier
* before the system enters a disabled, endless loop.
* The below function is called as a panic/reboot notifier before the
* system enters a disabled, endless loop.
*
* Notice we must use the spin_trylock() alternative, to prevent lockups
* in atomic context (panic routine runs with secondary CPUs, local IRQs
* and preemption disabled).
*/
static void
con3270_flush(void)
static int con3270_notify(struct notifier_block *self,
unsigned long event, void *data)
{
struct con3270 *cp;
unsigned long flags;
cp = condev;
if (!cp->view.dev)
return;
raw3270_activate_view(&cp->view);
spin_lock_irqsave(&cp->view.lock, flags);
return NOTIFY_DONE;
if (!raw3270_view_lock_unavailable(&cp->view))
raw3270_activate_view(&cp->view);
if (!spin_trylock_irqsave(&cp->view.lock, flags))
return NOTIFY_DONE;
con3270_wait_write(cp);
cp->nr_up = 0;
con3270_rebuild_update(cp);
......@@ -560,23 +566,18 @@ con3270_flush(void)
con3270_wait_write(cp);
}
spin_unlock_irqrestore(&cp->view.lock, flags);
}
static int con3270_notify(struct notifier_block *self,
unsigned long event, void *data)
{
con3270_flush();
return NOTIFY_OK;
return NOTIFY_DONE;
}
static struct notifier_block on_panic_nb = {
.notifier_call = con3270_notify,
.priority = 0,
.priority = INT_MIN + 1, /* run the callback late */
};
static struct notifier_block on_reboot_nb = {
.notifier_call = con3270_notify,
.priority = 0,
.priority = INT_MIN + 1, /* run the callback late */
};
/*
......
......@@ -830,6 +830,21 @@ raw3270_create_device(struct ccw_device *cdev)
return rp;
}
/*
* This helper just validates that it is safe to activate a
* view in the panic() context, due to locking restrictions.
*/
int raw3270_view_lock_unavailable(struct raw3270_view *view)
{
struct raw3270 *rp = view->dev;
if (!rp)
return -ENODEV;
if (spin_is_locked(get_ccwdev_lock(rp->cdev)))
return -EBUSY;
return 0;
}
/*
* Activate a view.
*/
......
......@@ -160,6 +160,7 @@ struct raw3270_view {
};
int raw3270_add_view(struct raw3270_view *, struct raw3270_fn *, int, int);
int raw3270_view_lock_unavailable(struct raw3270_view *view);
int raw3270_activate_view(struct raw3270_view *);
void raw3270_del_view(struct raw3270_view *);
void raw3270_deactivate_view(struct raw3270_view *);
......
......@@ -220,30 +220,34 @@ sclp_console_device(struct console *c, int *index)
}
/*
* Make sure that all buffers will be flushed to the SCLP.
* This panic/reboot notifier makes sure that all buffers
* will be flushed to the SCLP.
*/
static void
sclp_console_flush(void)
static int sclp_console_notify(struct notifier_block *self,
unsigned long event, void *data)
{
/*
* Perform the lock check before effectively getting the
* lock on sclp_conbuf_emit() / sclp_console_sync_queue()
* to prevent potential lockups in atomic context.
*/
if (spin_is_locked(&sclp_con_lock))
return NOTIFY_DONE;
sclp_conbuf_emit();
sclp_console_sync_queue();
}
static int sclp_console_notify(struct notifier_block *self,
unsigned long event, void *data)
{
sclp_console_flush();
return NOTIFY_OK;
return NOTIFY_DONE;
}
static struct notifier_block on_panic_nb = {
.notifier_call = sclp_console_notify,
.priority = 1,
.priority = INT_MIN + 1, /* run the callback late */
};
static struct notifier_block on_reboot_nb = {
.notifier_call = sclp_console_notify,
.priority = 1,
.priority = INT_MIN + 1, /* run the callback late */
};
/*
......
......@@ -49,8 +49,10 @@ static void __init sclp_early_facilities_detect(void)
S390_lowcore.machine_flags |= MACHINE_FLAG_ESOP;
if (sccb->fac91 & 0x40)
S390_lowcore.machine_flags |= MACHINE_FLAG_TLB_GUEST;
if (sccb->cpuoff > 134)
if (sccb->cpuoff > 134) {
sclp.has_diag318 = !!(sccb->byte_134 & 0x80);
sclp.has_iplcc = !!(sccb->byte_134 & 0x02);
}
if (sccb->cpuoff > 137)
sclp.has_sipl = !!(sccb->cbl & 0x4000);
sclp.rnmax = sccb->rnmax ? sccb->rnmax : sccb->rnmax2;
......
......@@ -769,21 +769,6 @@ __initcall(sclp_vt220_tty_init);
#ifdef CONFIG_SCLP_VT220_CONSOLE
static void __sclp_vt220_flush_buffer(void)
{
unsigned long flags;
sclp_vt220_emit_current();
spin_lock_irqsave(&sclp_vt220_lock, flags);
del_timer(&sclp_vt220_timer);
while (sclp_vt220_queue_running) {
spin_unlock_irqrestore(&sclp_vt220_lock, flags);
sclp_sync_wait();
spin_lock_irqsave(&sclp_vt220_lock, flags);
}
spin_unlock_irqrestore(&sclp_vt220_lock, flags);
}
static void
sclp_vt220_con_write(struct console *con, const char *buf, unsigned int count)
{
......@@ -797,22 +782,41 @@ sclp_vt220_con_device(struct console *c, int *index)
return sclp_vt220_driver;
}
/*
* This panic/reboot notifier runs in atomic context, so
* locking restrictions apply to prevent potential lockups.
*/
static int
sclp_vt220_notify(struct notifier_block *self,
unsigned long event, void *data)
{
__sclp_vt220_flush_buffer();
return NOTIFY_OK;
unsigned long flags;
if (spin_is_locked(&sclp_vt220_lock))
return NOTIFY_DONE;
sclp_vt220_emit_current();
spin_lock_irqsave(&sclp_vt220_lock, flags);
del_timer(&sclp_vt220_timer);
while (sclp_vt220_queue_running) {
spin_unlock_irqrestore(&sclp_vt220_lock, flags);
sclp_sync_wait();
spin_lock_irqsave(&sclp_vt220_lock, flags);
}
spin_unlock_irqrestore(&sclp_vt220_lock, flags);
return NOTIFY_DONE;
}
static struct notifier_block on_panic_nb = {
.notifier_call = sclp_vt220_notify,
.priority = 1,
.priority = INT_MIN + 1, /* run the callback late */
};
static struct notifier_block on_reboot_nb = {
.notifier_call = sclp_vt220_notify,
.priority = 1,
.priority = INT_MIN + 1, /* run the callback late */
};
/* Structure needed to register with printk */
......
......@@ -1255,7 +1255,7 @@ chsc_determine_css_characteristics(void)
EXPORT_SYMBOL_GPL(css_general_characteristics);
EXPORT_SYMBOL_GPL(css_chsc_characteristics);
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta)
int chsc_sstpc(void *page, unsigned int op, u16 ctrl, long *clock_delta)
{
struct {
struct chsc_header request;
......@@ -1266,7 +1266,7 @@ int chsc_sstpc(void *page, unsigned int op, u16 ctrl, u64 *clock_delta)
unsigned int rsvd2[5];
struct chsc_header response;
unsigned int rsvd3[3];
u64 clock_delta;
s64 clock_delta;
unsigned int rsvd4[2];
} *rr;
int rc;
......
......@@ -179,7 +179,7 @@ static int ap_qci_available(void)
* ap_apft_available(): Test if AP facilities test (APFT)
* facility is available.
*
* Returns 1 if APFT is is available.
* Returns 1 if APFT is available.
*/
static int ap_apft_available(void)
{
......@@ -693,6 +693,24 @@ void ap_send_online_uevent(struct ap_device *ap_dev, int online)
}
EXPORT_SYMBOL(ap_send_online_uevent);
static void ap_send_mask_changed_uevent(unsigned long *newapm,
unsigned long *newaqm)
{
char buf[100];
char *envp[] = { buf, NULL };
if (newapm)
snprintf(buf, sizeof(buf),
"APMASK=0x%016lx%016lx%016lx%016lx\n",
newapm[0], newapm[1], newapm[2], newapm[3]);
else
snprintf(buf, sizeof(buf),
"AQMASK=0x%016lx%016lx%016lx%016lx\n",
newaqm[0], newaqm[1], newaqm[2], newaqm[3]);
kobject_uevent_env(&ap_root_device->kobj, KOBJ_CHANGE, envp);
}
/*
* calc # of bound APQNs
*/
......@@ -704,7 +722,7 @@ struct __ap_calc_ctrs {
static int __ap_calc_helper(struct device *dev, void *arg)
{
struct __ap_calc_ctrs *pctrs = (struct __ap_calc_ctrs *) arg;
struct __ap_calc_ctrs *pctrs = (struct __ap_calc_ctrs *)arg;
if (is_queue_dev(dev)) {
pctrs->apqns++;
......@@ -720,7 +738,7 @@ static void ap_calc_bound_apqns(unsigned int *apqns, unsigned int *bound)
struct __ap_calc_ctrs ctrs;
memset(&ctrs, 0, sizeof(ctrs));
bus_for_each_dev(&ap_bus_type, NULL, (void *) &ctrs, __ap_calc_helper);
bus_for_each_dev(&ap_bus_type, NULL, (void *)&ctrs, __ap_calc_helper);
*apqns = ctrs.apqns;
*bound = ctrs.bound;
......@@ -781,7 +799,7 @@ EXPORT_SYMBOL(ap_wait_init_apqn_bindings_complete);
static int __ap_queue_devices_with_id_unregister(struct device *dev, void *data)
{
if (is_queue_dev(dev) &&
AP_QID_CARD(to_ap_queue(dev)->qid) == (int)(long) data)
AP_QID_CARD(to_ap_queue(dev)->qid) == (int)(long)data)
device_unregister(dev);
return 0;
}
......@@ -794,8 +812,8 @@ static int __ap_revise_reserved(struct device *dev, void *dummy)
card = AP_QID_CARD(to_ap_queue(dev)->qid);
queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
mutex_lock(&ap_perms_mutex);
devres = test_bit_inv(card, ap_perms.apm)
&& test_bit_inv(queue, ap_perms.aqm);
devres = test_bit_inv(card, ap_perms.apm) &&
test_bit_inv(queue, ap_perms.aqm);
mutex_unlock(&ap_perms_mutex);
drvres = to_ap_drv(dev->driver)->flags
& AP_DRIVER_FLAG_DEFAULT;
......@@ -826,8 +844,8 @@ int ap_owned_by_def_drv(int card, int queue)
mutex_lock(&ap_perms_mutex);
if (test_bit_inv(card, ap_perms.apm)
&& test_bit_inv(queue, ap_perms.aqm))
if (test_bit_inv(card, ap_perms.apm) &&
test_bit_inv(queue, ap_perms.aqm))
rc = 1;
mutex_unlock(&ap_perms_mutex);
......@@ -876,8 +894,8 @@ static int ap_device_probe(struct device *dev)
card = AP_QID_CARD(to_ap_queue(dev)->qid);
queue = AP_QID_QUEUE(to_ap_queue(dev)->qid);
mutex_lock(&ap_perms_mutex);
devres = test_bit_inv(card, ap_perms.apm)
&& test_bit_inv(queue, ap_perms.aqm);
devres = test_bit_inv(card, ap_perms.apm) &&
test_bit_inv(queue, ap_perms.aqm);
mutex_unlock(&ap_perms_mutex);
drvres = ap_drv->flags & AP_DRIVER_FLAG_DEFAULT;
if (!!devres != !!drvres)
......@@ -898,8 +916,9 @@ static int ap_device_probe(struct device *dev)
if (is_queue_dev(dev))
hash_del(&to_ap_queue(dev)->hnode);
spin_unlock_bh(&ap_queues_lock);
} else
} else {
ap_check_bindings_complete();
}
out:
if (rc)
......@@ -980,8 +999,8 @@ void ap_bus_force_rescan(void)
EXPORT_SYMBOL(ap_bus_force_rescan);
/*
* A config change has happened, force an ap bus rescan.
*/
* A config change has happened, force an ap bus rescan.
*/
void ap_bus_cfg_chg(void)
{
AP_DBF_DBG("%s config change, forcing bus rescan\n", __func__);
......@@ -1105,7 +1124,7 @@ int ap_parse_mask_str(const char *str,
if (bits & 0x07)
return -EINVAL;
size = BITS_TO_LONGS(bits)*sizeof(unsigned long);
size = BITS_TO_LONGS(bits) * sizeof(unsigned long);
newmap = kmalloc(size, GFP_KERNEL);
if (!newmap)
return -ENOMEM;
......@@ -1241,8 +1260,9 @@ static ssize_t poll_thread_store(struct bus_type *bus,
rc = ap_poll_thread_start();
if (rc)
count = rc;
} else
} else {
ap_poll_thread_stop();
}
return count;
}
......@@ -1355,7 +1375,7 @@ static int apmask_commit(unsigned long *newapm)
static ssize_t apmask_store(struct bus_type *bus, const char *buf,
size_t count)
{
int rc;
int rc, changes = 0;
DECLARE_BITMAP(newapm, AP_DEVICES);
if (mutex_lock_interruptible(&ap_perms_mutex))
......@@ -1365,14 +1385,19 @@ static ssize_t apmask_store(struct bus_type *bus, const char *buf,
if (rc)
goto done;
rc = apmask_commit(newapm);
changes = memcmp(ap_perms.apm, newapm, APMASKSIZE);
if (changes)
rc = apmask_commit(newapm);
done:
mutex_unlock(&ap_perms_mutex);
if (rc)
return rc;
ap_bus_revise_bindings();
if (changes) {
ap_bus_revise_bindings();
ap_send_mask_changed_uevent(newapm, NULL);
}
return count;
}
......@@ -1443,7 +1468,7 @@ static int aqmask_commit(unsigned long *newaqm)
static ssize_t aqmask_store(struct bus_type *bus, const char *buf,
size_t count)
{
int rc;
int rc, changes = 0;
DECLARE_BITMAP(newaqm, AP_DOMAINS);
if (mutex_lock_interruptible(&ap_perms_mutex))
......@@ -1453,14 +1478,19 @@ static ssize_t aqmask_store(struct bus_type *bus, const char *buf,
if (rc)
goto done;
rc = aqmask_commit(newaqm);
changes = memcmp(ap_perms.aqm, newaqm, APMASKSIZE);
if (changes)
rc = aqmask_commit(newaqm);
done:
mutex_unlock(&ap_perms_mutex);
if (rc)
return rc;
ap_bus_revise_bindings();
if (changes) {
ap_bus_revise_bindings();
ap_send_mask_changed_uevent(NULL, newaqm);
}
return count;
}
......@@ -1605,9 +1635,9 @@ static int ap_get_compatible_type(ap_qid_t qid, int rawtype, unsigned int func)
apinfo.mode = (func >> 26) & 0x07;
apinfo.cat = AP_DEVICE_TYPE_CEX8;
status = ap_qact(qid, 0, &apinfo);
if (status.response_code == AP_RESPONSE_NORMAL
&& apinfo.cat >= AP_DEVICE_TYPE_CEX2A
&& apinfo.cat <= AP_DEVICE_TYPE_CEX8)
if (status.response_code == AP_RESPONSE_NORMAL &&
apinfo.cat >= AP_DEVICE_TYPE_CEX2A &&
apinfo.cat <= AP_DEVICE_TYPE_CEX8)
comp_type = apinfo.cat;
}
if (!comp_type)
......@@ -1627,7 +1657,7 @@ static int ap_get_compatible_type(ap_qid_t qid, int rawtype, unsigned int func)
*/
static int __match_card_device_with_id(struct device *dev, const void *data)
{
return is_card_dev(dev) && to_ap_card(dev)->id == (int)(long)(void *) data;
return is_card_dev(dev) && to_ap_card(dev)->id == (int)(long)(void *)data;
}
/*
......@@ -1636,7 +1666,7 @@ static int __match_card_device_with_id(struct device *dev, const void *data)
*/
static int __match_queue_device_with_qid(struct device *dev, const void *data)
{
return is_queue_dev(dev) && to_ap_queue(dev)->qid == (int)(long) data;
return is_queue_dev(dev) && to_ap_queue(dev)->qid == (int)(long)data;
}
/*
......@@ -1645,8 +1675,8 @@ static int __match_queue_device_with_qid(struct device *dev, const void *data)
*/
static int __match_queue_device_with_queue_id(struct device *dev, const void *data)
{
return is_queue_dev(dev)
&& AP_QID_QUEUE(to_ap_queue(dev)->qid) == (int)(long) data;
return is_queue_dev(dev) &&
AP_QID_QUEUE(to_ap_queue(dev)->qid) == (int)(long)data;
}
/* Helper function for notify_config_changed */
......@@ -1699,7 +1729,7 @@ static inline void notify_scan_complete(void)
static inline void ap_scan_rm_card_dev_and_queue_devs(struct ap_card *ac)
{
bus_for_each_dev(&ap_bus_type, NULL,
(void *)(long) ac->id,
(void *)(long)ac->id,
__ap_queue_devices_with_id_unregister);
device_unregister(&ac->ap_dev.device);
}
......@@ -1727,7 +1757,7 @@ static inline void ap_scan_domains(struct ap_card *ac)
for (dom = 0; dom <= ap_max_domain_id; dom++) {
qid = AP_MKQID(ac->id, dom);
dev = bus_find_device(&ap_bus_type, NULL,
(void *)(long) qid,
(void *)(long)qid,
__match_queue_device_with_qid);
aq = dev ? to_ap_queue(dev) : NULL;
if (!ap_test_config_usage_domain(dom)) {
......@@ -1873,7 +1903,7 @@ static inline void ap_scan_adapter(int ap)
/* Is there currently a card device for this adapter ? */
dev = bus_find_device(&ap_bus_type, NULL,
(void *)(long) ap,
(void *)(long)ap,
__match_card_device_with_id);
ac = dev ? to_ap_card(dev) : NULL;
......@@ -2074,7 +2104,7 @@ static void ap_scan_bus(struct work_struct *unused)
if (ap_domain_index >= 0) {
struct device *dev =
bus_find_device(&ap_bus_type, NULL,
(void *)(long) ap_domain_index,
(void *)(long)ap_domain_index,
__match_queue_device_with_queue_id);
if (dev)
put_device(dev);
......@@ -2109,7 +2139,7 @@ static int __init ap_debug_init(void)
static void __init ap_perms_init(void)
{
/* all resources useable if no kernel parameter string given */
/* all resources usable if no kernel parameter string given */
memset(&ap_perms.ioctlm, 0xFF, sizeof(ap_perms.ioctlm));
memset(&ap_perms.apm, 0xFF, sizeof(ap_perms.apm));
memset(&ap_perms.aqm, 0xFF, sizeof(ap_perms.aqm));
......
......@@ -317,6 +317,7 @@ struct ap_perms {
unsigned long aqm[BITS_TO_LONGS(AP_DOMAINS)];
unsigned long adm[BITS_TO_LONGS(AP_DOMAINS)];
};
extern struct ap_perms ap_perms;
extern struct mutex ap_perms_mutex;
......
......@@ -99,7 +99,7 @@ int ap_recv(ap_qid_t qid, unsigned long long *psmid, void *msg, size_t length)
{
struct ap_queue_status status;
if (msg == NULL)
if (!msg)
return -EINVAL;
status = ap_dqap(qid, psmid, msg, length, NULL, NULL);
switch (status.response_code) {
......@@ -603,7 +603,7 @@ static ssize_t interrupt_show(struct device *dev,
static DEVICE_ATTR_RO(interrupt);
static ssize_t config_show(struct device *dev,
struct device_attribute *attr, char *buf)
struct device_attribute *attr, char *buf)
{
struct ap_queue *aq = to_ap_queue(dev);
int rc;
......@@ -827,8 +827,9 @@ int ap_queue_message(struct ap_queue *aq, struct ap_message *ap_msg)
aq->requestq_count++;
aq->total_request_count++;
atomic64_inc(&aq->card->total_request_count);
} else
} else {
rc = -ENODEV;
}
/* Send/receive as many request from the queue as possible. */
ap_wait(ap_sm_event_loop(aq, AP_SM_EVENT_POLL));
......
This diff is collapsed.
......@@ -46,8 +46,6 @@ static struct ap_device_id ap_queue_ids[] = {
{ /* end of sibling */ },
};
MODULE_DEVICE_TABLE(vfio_ap, ap_queue_ids);
static struct ap_matrix_mdev *vfio_ap_mdev_for_queue(struct vfio_ap_queue *q)
{
struct ap_matrix_mdev *matrix_mdev;
......
This diff is collapsed.
......@@ -170,7 +170,7 @@ static inline unsigned long z_copy_from_user(bool userspace,
{
if (likely(userspace))
return copy_from_user(to, from, n);
memcpy(to, (void __force *) from, n);
memcpy(to, (void __force *)from, n);
return 0;
}
......@@ -181,7 +181,7 @@ static inline unsigned long z_copy_to_user(bool userspace,
{
if (likely(userspace))
return copy_to_user(to, from, n);
memcpy((void __force *) to, from, n);
memcpy((void __force *)to, from, n);
return 0;
}
......
......@@ -138,7 +138,7 @@ struct zcrypt_card *zcrypt_card_alloc(void)
{
struct zcrypt_card *zc;
zc = kzalloc(sizeof(struct zcrypt_card), GFP_KERNEL);
zc = kzalloc(sizeof(*zc), GFP_KERNEL);
if (!zc)
return NULL;
INIT_LIST_HEAD(&zc->list);
......
......@@ -11,7 +11,7 @@
#ifndef _ZCRYPT_CCA_KEY_H_
#define _ZCRYPT_CCA_KEY_H_
struct T6_keyBlock_hdr {
struct t6_keyblock_hdr {
unsigned short blen;
unsigned short ulen;
unsigned short flags;
......@@ -63,7 +63,7 @@ struct cca_public_sec {
* complement of the residue modulo 8 of the sum of
* (p_len + q_len + dp_len + dq_len + u_len).
*/
struct cca_pvt_ext_CRT_sec {
struct cca_pvt_ext_crt_sec {
unsigned char section_identifier;
unsigned char version;
unsigned short section_length;
......@@ -108,9 +108,9 @@ static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p)
.section_identifier = 0x04,
};
struct {
struct T6_keyBlock_hdr t6_hdr;
struct cca_token_hdr pubHdr;
struct cca_public_sec pubSec;
struct t6_keyblock_hdr t6_hdr;
struct cca_token_hdr pubhdr;
struct cca_public_sec pubsec;
char exponent[0];
} __packed *key = p;
unsigned char *temp;
......@@ -127,8 +127,8 @@ static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p)
memset(key, 0, sizeof(*key));
key->pubHdr = static_pub_hdr;
key->pubSec = static_pub_sec;
key->pubhdr = static_pub_hdr;
key->pubsec = static_pub_sec;
/* key parameter block */
temp = key->exponent;
......@@ -146,16 +146,16 @@ static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p)
if (copy_from_user(temp, mex->n_modulus, mex->inputdatalength))
return -EFAULT;
key->pubSec.modulus_bit_len = 8 * mex->inputdatalength;
key->pubSec.modulus_byte_len = mex->inputdatalength;
key->pubSec.exponent_len = mex->inputdatalength - i;
key->pubSec.section_length = sizeof(key->pubSec) +
2*mex->inputdatalength - i;
key->pubHdr.token_length =
key->pubSec.section_length + sizeof(key->pubHdr);
key->t6_hdr.ulen = key->pubHdr.token_length + 4;
key->t6_hdr.blen = key->pubHdr.token_length + 6;
return sizeof(*key) + 2*mex->inputdatalength - i;
key->pubsec.modulus_bit_len = 8 * mex->inputdatalength;
key->pubsec.modulus_byte_len = mex->inputdatalength;
key->pubsec.exponent_len = mex->inputdatalength - i;
key->pubsec.section_length = sizeof(key->pubsec) +
2 * mex->inputdatalength - i;
key->pubhdr.token_length =
key->pubsec.section_length + sizeof(key->pubhdr);
key->t6_hdr.ulen = key->pubhdr.token_length + 4;
key->t6_hdr.blen = key->pubhdr.token_length + 6;
return sizeof(*key) + 2 * mex->inputdatalength - i;
}
/**
......@@ -177,9 +177,9 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
};
static char pk_exponent[3] = { 0x01, 0x00, 0x01 };
struct {
struct T6_keyBlock_hdr t6_hdr;
struct t6_keyblock_hdr t6_hdr;
struct cca_token_hdr token;
struct cca_pvt_ext_CRT_sec pvt;
struct cca_pvt_ext_crt_sec pvt;
char key_parts[0];
} __packed *key = p;
struct cca_public_sec *pub;
......@@ -198,8 +198,8 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
short_len = (crt->inputdatalength + 1) / 2;
long_len = short_len + 8;
pad_len = -(3*long_len + 2*short_len) & 7;
key_len = 3*long_len + 2*short_len + pad_len + crt->inputdatalength;
pad_len = -(3 * long_len + 2 * short_len) & 7;
key_len = 3 * long_len + 2 * short_len + pad_len + crt->inputdatalength;
size = sizeof(*key) + key_len + sizeof(*pub) + 3;
/* parameter block.key block */
......@@ -223,15 +223,15 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
/* key parts */
if (copy_from_user(key->key_parts, crt->np_prime, long_len) ||
copy_from_user(key->key_parts + long_len,
crt->nq_prime, short_len) ||
crt->nq_prime, short_len) ||
copy_from_user(key->key_parts + long_len + short_len,
crt->bp_key, long_len) ||
copy_from_user(key->key_parts + 2*long_len + short_len,
crt->bq_key, short_len) ||
copy_from_user(key->key_parts + 2*long_len + 2*short_len,
crt->u_mult_inv, long_len))
crt->bp_key, long_len) ||
copy_from_user(key->key_parts + 2 * long_len + short_len,
crt->bq_key, short_len) ||
copy_from_user(key->key_parts + 2 * long_len + 2 * short_len,
crt->u_mult_inv, long_len))
return -EFAULT;
memset(key->key_parts + 3*long_len + 2*short_len + pad_len,
memset(key->key_parts + 3 * long_len + 2 * short_len + pad_len,
0xff, crt->inputdatalength);
pub = (struct cca_public_sec *)(key->key_parts + key_len);
*pub = static_cca_pub_sec;
......@@ -241,7 +241,7 @@ static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
* section. So, an arbitrary public exponent of 0x010001 will be
* used.
*/
memcpy((char *) (pub + 1), pk_exponent, 3);
memcpy((char *)(pub + 1), pk_exponent, 3);
return size;
}
......
This diff is collapsed.
......@@ -251,12 +251,18 @@ struct cca_info {
char new_apka_mk_state; /* '1' empty, '2' partially full, '3' full */
char cur_apka_mk_state; /* '1' invalid, '2' valid */
char old_apka_mk_state; /* '1' invalid, '2' valid */
char new_asym_mk_state; /* '1' empty, '2' partially full, '3' full */
char cur_asym_mk_state; /* '1' invalid, '2' valid */
char old_asym_mk_state; /* '1' invalid, '2' valid */
u64 new_aes_mkvp; /* truncated sha256 of new aes master key */
u64 cur_aes_mkvp; /* truncated sha256 of current aes master key */
u64 old_aes_mkvp; /* truncated sha256 of old aes master key */
u64 new_apka_mkvp; /* truncated sha256 of new apka master key */
u64 cur_apka_mkvp; /* truncated sha256 of current apka mk */
u64 old_apka_mkvp; /* truncated sha256 of old apka mk */
u8 new_asym_mkvp[16]; /* verify pattern of new asym master key */
u8 cur_asym_mkvp[16]; /* verify pattern of current asym master key */
u8 old_asym_mkvp[16]; /* verify pattern of old asym master key */
char serial[9]; /* serial number (8 ascii numbers + 0x00) */
};
......
......@@ -34,10 +34,11 @@
#define CEX3A_MAX_RESPONSE_SIZE 0x210 /* 512 bit modulus
* (max outputdatalength) +
* type80_hdr*/
* type80_hdr
*/
#define CEX3A_MAX_MESSAGE_SIZE sizeof(struct type50_crb3_msg)
#define CEX2A_CLEANUP_TIME (15*HZ)
#define CEX2A_CLEANUP_TIME (15 * HZ)
#define CEX3A_CLEANUP_TIME CEX2A_CLEANUP_TIME
MODULE_AUTHOR("IBM Corporation");
......@@ -117,9 +118,8 @@ static int zcrypt_cex2a_card_probe(struct ap_device *ap_dev)
zc->online = 1;
rc = zcrypt_card_register(zc);
if (rc) {
if (rc)
zcrypt_card_free(zc);
}
return rc;
}
......@@ -176,9 +176,8 @@ static int zcrypt_cex2a_queue_probe(struct ap_device *ap_dev)
aq->request_timeout = CEX2A_CLEANUP_TIME;
dev_set_drvdata(&ap_dev->device, zq);
rc = zcrypt_queue_register(zq);
if (rc) {
if (rc)
zcrypt_queue_free(zq);
}
return rc;
}
......
......@@ -31,8 +31,8 @@
#define CEX2C_MAX_MOD_SIZE 256 /* 2048 bits */
#define CEX3C_MIN_MOD_SIZE 16 /* 128 bits */
#define CEX3C_MAX_MOD_SIZE 512 /* 4096 bits */
#define CEX2C_MAX_XCRB_MESSAGE_SIZE (12*1024)
#define CEX2C_CLEANUP_TIME (15*HZ)
#define CEX2C_MAX_XCRB_MESSAGE_SIZE (12 * 1024)
#define CEX2C_CLEANUP_TIME (15 * HZ)
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("CEX2C/CEX3C Cryptographic Coprocessor device driver, " \
......@@ -200,11 +200,11 @@ static int zcrypt_cex2c_rng_supported(struct ap_queue *aq)
int rc, i;
ap_init_message(&ap_msg);
ap_msg.msg = (void *) get_zeroed_page(GFP_KERNEL);
ap_msg.msg = (void *)get_zeroed_page(GFP_KERNEL);
if (!ap_msg.msg)
return -ENOMEM;
rng_type6CPRB_msgX(&ap_msg, 4, &domain);
rng_type6cprb_msgx(&ap_msg, 4, &domain);
msg = ap_msg.msg;
msg->cprbx.domain = AP_QID_QUEUE(aq->qid);
......@@ -233,7 +233,7 @@ static int zcrypt_cex2c_rng_supported(struct ap_queue *aq)
else
rc = 0;
out_free:
free_page((unsigned long) ap_msg.msg);
free_page((unsigned long)ap_msg.msg);
return rc;
}
......
......@@ -33,7 +33,7 @@
* But the maximum time limit managed by the stomper code is set to 60sec.
* Hence we have to wait at least that time period.
*/
#define CEX4_CLEANUP_TIME (900*HZ)
#define CEX4_CLEANUP_TIME (900 * HZ)
MODULE_AUTHOR("IBM Corporation");
MODULE_DESCRIPTION("CEX[45678] Cryptographic Card device driver, " \
......@@ -123,11 +123,12 @@ static ssize_t cca_mkvps_show(struct device *dev,
&ci, zq->online);
if (ci.new_aes_mk_state >= '1' && ci.new_aes_mk_state <= '3')
n = scnprintf(buf, PAGE_SIZE, "AES NEW: %s 0x%016llx\n",
new_state[ci.new_aes_mk_state - '1'],
ci.new_aes_mkvp);
n += scnprintf(buf + n, PAGE_SIZE,
"AES NEW: %s 0x%016llx\n",
new_state[ci.new_aes_mk_state - '1'],
ci.new_aes_mkvp);
else
n = scnprintf(buf, PAGE_SIZE, "AES NEW: - -\n");
n += scnprintf(buf + n, PAGE_SIZE, "AES NEW: - -\n");
if (ci.cur_aes_mk_state >= '1' && ci.cur_aes_mk_state <= '2')
n += scnprintf(buf + n, PAGE_SIZE - n,
......@@ -169,6 +170,33 @@ static ssize_t cca_mkvps_show(struct device *dev,
else
n += scnprintf(buf + n, PAGE_SIZE - n, "APKA OLD: - -\n");
if (ci.new_asym_mk_state >= '1' && ci.new_asym_mk_state <= '3')
n += scnprintf(buf + n, PAGE_SIZE,
"ASYM NEW: %s 0x%016llx%016llx\n",
new_state[ci.new_asym_mk_state - '1'],
*((u64 *)(ci.new_asym_mkvp)),
*((u64 *)(ci.new_asym_mkvp + sizeof(u64))));
else
n += scnprintf(buf + n, PAGE_SIZE, "ASYM NEW: - -\n");
if (ci.cur_asym_mk_state >= '1' && ci.cur_asym_mk_state <= '2')
n += scnprintf(buf + n, PAGE_SIZE - n,
"ASYM CUR: %s 0x%016llx%016llx\n",
cao_state[ci.cur_asym_mk_state - '1'],
*((u64 *)(ci.cur_asym_mkvp)),
*((u64 *)(ci.cur_asym_mkvp + sizeof(u64))));
else
n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM CUR: - -\n");
if (ci.old_asym_mk_state >= '1' && ci.old_asym_mk_state <= '2')
n += scnprintf(buf + n, PAGE_SIZE - n,
"ASYM OLD: %s 0x%016llx%016llx\n",
cao_state[ci.old_asym_mk_state - '1'],
*((u64 *)(ci.old_asym_mkvp)),
*((u64 *)(ci.old_asym_mkvp + sizeof(u64))));
else
n += scnprintf(buf + n, PAGE_SIZE - n, "ASYM OLD: - -\n");
return n;
}
......@@ -336,8 +364,9 @@ static ssize_t ep11_mkvps_show(struct device *dev,
bin2hex(buf + n, di.cur_wkvp, sizeof(di.cur_wkvp));
n += 2 * sizeof(di.cur_wkvp);
n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
} else
} else {
n = scnprintf(buf, PAGE_SIZE, "WK CUR: - -\n");
}
if (di.new_wk_state == '0') {
n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s -\n",
......@@ -348,8 +377,9 @@ static ssize_t ep11_mkvps_show(struct device *dev,
bin2hex(buf + n, di.new_wkvp, sizeof(di.new_wkvp));
n += 2 * sizeof(di.new_wkvp);
n += scnprintf(buf + n, PAGE_SIZE - n, "\n");
} else
} else {
n += scnprintf(buf + n, PAGE_SIZE - n, "WK NEW: - -\n");
}
return n;
}
......
This diff is collapsed.
......@@ -50,7 +50,7 @@ struct ep11keyblob {
/* check ep11 key magic to find out if this is an ep11 key blob */
static inline bool is_ep11_keyblob(const u8 *key)
{
struct ep11keyblob *kb = (struct ep11keyblob *) key;
struct ep11keyblob *kb = (struct ep11keyblob *)key;
return (kb->version == EP11_STRUCT_MAGIC);
}
......
......@@ -121,10 +121,11 @@ static inline int convert_error(struct zcrypt_queue *zq,
ZCRYPT_DBF_WARN(
"%s dev=%02x.%04x RY=0x%02x apfs=0x%x => bus rescan, rc=EAGAIN\n",
__func__, card, queue, ehdr->reply_code, apfs);
} else
} else {
ZCRYPT_DBF_WARN("%s dev=%02x.%04x RY=0x%02x => bus rescan, rc=EAGAIN\n",
__func__, card, queue,
ehdr->reply_code);
}
return -EAGAIN;
default:
/* Assume request is valid and a retry will be worth it */
......
......@@ -158,7 +158,6 @@ struct type80_hdr {
int get_rsa_modex_fc(struct ica_rsa_modexpo *mex, int *fcode)
{
if (!mex->inputdatalength)
return -EINVAL;
......@@ -174,7 +173,6 @@ int get_rsa_modex_fc(struct ica_rsa_modexpo *mex, int *fcode)
int get_rsa_crt_fc(struct ica_rsa_modexpo_crt *crt, int *fcode)
{
if (!crt->inputdatalength)
return -EINVAL;
......@@ -239,8 +237,9 @@ static int ICAMEX_msg_to_type50MEX_msg(struct zcrypt_queue *zq,
mod = meb3->modulus + sizeof(meb3->modulus) - mod_len;
exp = meb3->exponent + sizeof(meb3->exponent) - mod_len;
inp = meb3->message + sizeof(meb3->message) - mod_len;
} else
} else {
return -EINVAL;
}
if (copy_from_user(mod, mex->n_modulus, mod_len) ||
copy_from_user(exp, mex->b_key, mod_len) ||
......@@ -323,8 +322,9 @@ static int ICACRT_msg_to_type50CRT_msg(struct zcrypt_queue *zq,
dq = crb3->dq + sizeof(crb3->dq) - short_len;
u = crb3->u + sizeof(crb3->u) - short_len;
inp = crb3->message + sizeof(crb3->message) - mod_len;
} else
} else {
return -EINVAL;
}
/*
* correct the offset of p, bp and mult_inv according zcrypt.h
......@@ -392,7 +392,7 @@ static int convert_response_cex2a(struct zcrypt_queue *zq,
unsigned int outputdatalength)
{
/* Response type byte is the second byte in the response. */
unsigned char rtype = ((unsigned char *) reply->msg)[1];
unsigned char rtype = ((unsigned char *)reply->msg)[1];
switch (rtype) {
case TYPE82_RSP_CODE:
......@@ -406,11 +406,11 @@ static int convert_response_cex2a(struct zcrypt_queue *zq,
pr_err("Crypto dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid),
(int) rtype);
(int)rtype);
ZCRYPT_DBF_ERR(
"%s dev=%02x.%04x unknown response type 0x%02x => online=0 rc=EAGAIN\n",
__func__, AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid), (int) rtype);
AP_QID_QUEUE(zq->queue->qid), (int)rtype);
ap_send_online_uevent(&zq->queue->ap_dev, zq->online);
return -EAGAIN;
}
......@@ -447,10 +447,11 @@ static void zcrypt_cex2a_receive(struct ap_queue *aq,
memcpy(msg->msg, reply->msg, len);
msg->len = len;
}
} else
} else {
memcpy(msg->msg, reply->msg, sizeof(error_reply));
}
out:
complete((struct completion *) msg->private);
complete((struct completion *)msg->private);
}
static atomic_t zcrypt_step = ATOMIC_INIT(0);
......@@ -475,7 +476,7 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_queue *zq,
if (!ap_msg->msg)
return -ENOMEM;
ap_msg->receive = zcrypt_cex2a_receive;
ap_msg->psmid = (((unsigned long long) current->pid) << 32) +
ap_msg->psmid = (((unsigned long long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg->private = &work;
rc = ICAMEX_msg_to_type50MEX_msg(zq, ap_msg, mex);
......@@ -492,9 +493,11 @@ static long zcrypt_cex2a_modexpo(struct zcrypt_queue *zq,
rc = convert_response_cex2a(zq, ap_msg,
mex->outputdata,
mex->outputdatalength);
} else
} else {
/* Signal pending. */
ap_cancel_message(zq->queue, ap_msg);
}
out:
ap_msg->private = NULL;
if (rc)
......@@ -524,7 +527,7 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_queue *zq,
if (!ap_msg->msg)
return -ENOMEM;
ap_msg->receive = zcrypt_cex2a_receive;
ap_msg->psmid = (((unsigned long long) current->pid) << 32) +
ap_msg->psmid = (((unsigned long long)current->pid) << 32) +
atomic_inc_return(&zcrypt_step);
ap_msg->private = &work;
rc = ICACRT_msg_to_type50CRT_msg(zq, ap_msg, crt);
......@@ -541,9 +544,11 @@ static long zcrypt_cex2a_modexpo_crt(struct zcrypt_queue *zq,
rc = convert_response_cex2a(zq, ap_msg,
crt->outputdata,
crt->outputdatalength);
} else
} else {
/* Signal pending. */
ap_cancel_message(zq->queue, ap_msg);
}
out:
ap_msg->private = NULL;
if (rc)
......
This diff is collapsed.
......@@ -45,14 +45,14 @@ struct type6_hdr {
unsigned char reserved5[2]; /* 0x0000 */
unsigned char function_code[2]; /* for PKD, 0x5044 (ascii 'PD') */
unsigned char reserved6[2]; /* 0x0000 */
unsigned int ToCardLen1; /* (request CPRB len + 3) & -4 */
unsigned int ToCardLen2; /* db len 0x00000000 for PKD */
unsigned int ToCardLen3; /* 0x00000000 */
unsigned int ToCardLen4; /* 0x00000000 */
unsigned int FromCardLen1; /* response buffer length */
unsigned int FromCardLen2; /* db len 0x00000000 for PKD */
unsigned int FromCardLen3; /* 0x00000000 */
unsigned int FromCardLen4; /* 0x00000000 */
unsigned int tocardlen1; /* (request CPRB len + 3) & -4 */
unsigned int tocardlen2; /* db len 0x00000000 for PKD */
unsigned int tocardlen3; /* 0x00000000 */
unsigned int tocardlen4; /* 0x00000000 */
unsigned int fromcardlen1; /* response buffer length */
unsigned int fromcardlen2; /* db len 0x00000000 for PKD */
unsigned int fromcardlen3; /* 0x00000000 */
unsigned int fromcardlen4; /* 0x00000000 */
} __packed;
/**
......@@ -116,7 +116,7 @@ int speed_idx_ep11(int);
* @ap_dev: AP device pointer
* @ap_msg: pointer to AP message
*/
static inline void rng_type6CPRB_msgX(struct ap_message *ap_msg,
static inline void rng_type6cprb_msgx(struct ap_message *ap_msg,
unsigned int random_number_length,
unsigned int *domain)
{
......@@ -134,8 +134,8 @@ static inline void rng_type6CPRB_msgX(struct ap_message *ap_msg,
.offset1 = 0x00000058,
.agent_id = {'C', 'A'},
.function_code = {'R', 'L'},
.ToCardLen1 = sizeof(*msg) - sizeof(msg->hdr),
.FromCardLen1 = sizeof(*msg) - sizeof(msg->hdr),
.tocardlen1 = sizeof(*msg) - sizeof(msg->hdr),
.fromcardlen1 = sizeof(*msg) - sizeof(msg->hdr),
};
static struct CPRBX local_cprbx = {
.cprb_len = 0x00dc,
......@@ -147,9 +147,9 @@ static inline void rng_type6CPRB_msgX(struct ap_message *ap_msg,
};
msg->hdr = static_type6_hdrX;
msg->hdr.FromCardLen2 = random_number_length,
msg->hdr.fromcardlen2 = random_number_length;
msg->cprbx = local_cprbx;
msg->cprbx.rpl_datal = random_number_length,
msg->cprbx.rpl_datal = random_number_length;
memcpy(msg->function_code, msg->hdr.function_code, 0x02);
msg->rule_length = 0x0a;
memcpy(msg->rule, "RANDOM ", 8);
......
......@@ -114,7 +114,7 @@ struct zcrypt_queue *zcrypt_queue_alloc(size_t reply_buf_size)
{
struct zcrypt_queue *zq;
zq = kzalloc(sizeof(struct zcrypt_queue), GFP_KERNEL);
zq = kzalloc(sizeof(*zq), GFP_KERNEL);
if (!zq)
return NULL;
zq->reply.msg = kmalloc(reply_buf_size, GFP_KERNEL);
......
......@@ -63,7 +63,7 @@
ARCH_EXIT_TO_USER_MODE_WORK)
/**
* arch_check_user_regs - Architecture specific sanity check for user mode regs
* arch_enter_from_user_mode - Architecture specific sanity check for user mode regs
* @regs: Pointer to currents pt_regs
*
* Defaults to an empty implementation. Can be replaced by architecture
......@@ -73,10 +73,10 @@
* section. Use __always_inline so the compiler cannot push it out of line
* and make it instrumentable.
*/
static __always_inline void arch_check_user_regs(struct pt_regs *regs);
static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs);
#ifndef arch_check_user_regs
static __always_inline void arch_check_user_regs(struct pt_regs *regs) {}
#ifndef arch_enter_from_user_mode
static __always_inline void arch_enter_from_user_mode(struct pt_regs *regs) {}
#endif
/**
......
......@@ -17,7 +17,7 @@
/* See comment for enter_from_user_mode() in entry-common.h */
static __always_inline void __enter_from_user_mode(struct pt_regs *regs)
{
arch_check_user_regs(regs);
arch_enter_from_user_mode(regs);
lockdep_hardirqs_off(CALLER_ADDR0);
CT_WARN_ON(ct_state() != CONTEXT_USER);
......
......@@ -24,9 +24,8 @@ icc)
echo 16.0.3
;;
llvm)
# https://lore.kernel.org/r/YMtib5hKVyNknZt3@osiris/
if [ "$SRCARCH" = s390 ]; then
echo 13.0.0
echo 14.0.0
else
echo 11.0.0
fi
......
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