s390 updates for 6.19 merge window

- Provide a new interface for dynamic configuration and deconfiguration of
   hotplug memory, allowing with and without memmap_on_memory support. This
   makes the way memory hotplug is handled on s390 much more similar to
   other architectures
 
 - Remove compat support. There shouldn't be any compat user space around
   anymore, therefore get rid of a lot of code which also doesn't need to be
   tested anymore
 
 - Add stackprotector support. GCC 16 will get new compiler options, which
   allow to generate code required for kernel stackprotector support
 
 - Merge pai_crypto and pai_ext PMU drivers into a new driver. This removes
   a lot of duplicated code. The new driver is also extendable and allows
   to support new PMUs
 
 - Add driver override support for AP queues
 
 - Rework and extend zcrypt and AP trace events to allow for tracing of
   crypto requests
 
 - Support block sizes larger than 65535 bytes for CCW tape devices
 
 - Since the rework of the virtual kernel address space the module area and
   the kernel image are within the same 4GB area. This eliminates the need
   of weak per cpu variables. Get rid of ARCH_MODULE_NEEDS_WEAK_PER_CPU
 
 - Various other small improvements and fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEECMNfWEw3SLnmiLkZIg7DeRspbsIFAmktZioACgkQIg7DeRsp
 bsK4Rw//VzkvHyzOtGKZ8Hb4S+Sh/PFlaZQXNhj+Xt5gWoOhP1uPmmhBe6LxjYaB
 J9Ns3hpONQ1dTHV7VVkds8FvM/SBcGe8m5RpefmChC/bjm5UEOV/MppKtA0aLnEH
 hJmdubIrrRAXKggxlHEfRLzBsFvV/rJ9Xf16FhRxGDc4pgmgkI1NPQ41/dyCHklQ
 dB3YrFVPIETywVYYVB/G3h11JgF5Z6CKtjYCdSx72Fkbj65+6JPfcPgLKMpcJuPd
 UxUXtCo1FCXlP70jsz8JQI8cdieG0KDQTtnZP4P/pqjQ3wirOqvMewNa9t9xmQ2e
 p6Rc1Vx5DESkq9bRWtQEaprTVVzK7DDLH3RuZwB+uLrcLGD8JvVS6/m9n9CgzBMT
 BnJXG2sLZH+gdQy+DSD/fVDD7OvIk8TGrH+OFwVIKhrT/J3B2E7ZSYyZZCNIS7VG
 yiuypoDGYg3ZpYjH9+qOXWB3nc0vQWrlFzb1bsQu1omJGmunLv4jtTjAKGN82C33
 auBsIYAlQW20X7DV0vZa59PwqwtBqtdQQcTidwtSztzKogRXAdK8KKHtN60JM4S2
 7sWFOFCQaTChAeDNw6MF5EtULb551nwH2RtJ9x3CrJj+OGK6clbQNcxIA7Oy0veR
 Sl9v1lMfeKOgDrPdDy3ArQBJ8WLlF9qX9wLKbiaNyIKmkz2ymkg=
 =CNrb
 -----END PGP SIGNATURE-----

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

Pull s390 updates from Heiko Carstens:

 - Provide a new interface for dynamic configuration and deconfiguration
   of hotplug memory, allowing with and without memmap_on_memory
   support. This makes the way memory hotplug is handled on s390 much
   more similar to other architectures

 - Remove compat support. There shouldn't be any compat user space
   around anymore, therefore get rid of a lot of code which also doesn't
   need to be tested anymore

 - Add stackprotector support. GCC 16 will get new compiler options,
   which allow to generate code required for kernel stackprotector
   support

 - Merge pai_crypto and pai_ext PMU drivers into a new driver. This
   removes a lot of duplicated code. The new driver is also extendable
   and allows to support new PMUs

 - Add driver override support for AP queues

 - Rework and extend zcrypt and AP trace events to allow for tracing of
   crypto requests

 - Support block sizes larger than 65535 bytes for CCW tape devices

 - Since the rework of the virtual kernel address space the module area
   and the kernel image are within the same 4GB area. This eliminates
   the need of weak per cpu variables. Get rid of
   ARCH_MODULE_NEEDS_WEAK_PER_CPU

 - Various other small improvements and fixes

* tag 's390-6.19-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (92 commits)
  watchdog: diag288_wdt: Remove KMSG_COMPONENT macro
  s390/entry: Use lay instead of aghik
  s390/vdso: Get rid of -m64 flag handling
  s390/vdso: Rename vdso64 to vdso
  s390: Rename head64.S to head.S
  s390/vdso: Use common STABS_DEBUG and DWARF_DEBUG macros
  s390: Add stackprotector support
  s390/modules: Simplify module_finalize() slightly
  s390: Remove KMSG_COMPONENT macro
  s390/percpu: Get rid of ARCH_MODULE_NEEDS_WEAK_PER_CPU
  s390/ap: Restrict driver_override versus apmask and aqmask use
  s390/ap: Rename mutex ap_perms_mutex to ap_attr_mutex
  s390/ap: Support driver_override for AP queue devices
  s390/ap: Use all-bits-one apmask/aqmask for vfio in_use() checks
  s390/debug: Update description of resize operation
  s390/syscalls: Switch to generic system call table generation
  s390/syscalls: Remove system call table pointer from thread_struct
  s390/uapi: Remove 31 bit support from uapi header files
  s390: Remove compat support
  tools: Remove s390 compat support
  ...
pull/1354/merge
Linus Torvalds 2025-12-02 16:37:00 -08:00
commit 2547f79b0b
258 changed files with 3136 additions and 6189 deletions

View File

@ -243,9 +243,8 @@ Examples:
Changing the size of debug areas
------------------------------------
It is possible the change the size of debug areas through piping
the number of pages to the debugfs file "pages". The resize request will
also flush the debug areas.
To resize a debug area, write the desired page count to the "pages" file.
Existing data is preserved if it fits; otherwise, oldest entries are dropped.
Example:

View File

@ -69,6 +69,9 @@ config CC_HAS_ASM_AOR_FORMAT_FLAGS
Clang versions before 19.1.0 do not support A,
O, and R inline assembly format flags.
config CC_HAS_STACKPROTECTOR_GLOBAL
def_bool $(cc-option, -mstack-protector-guard=global -mstack-protector-guard-record)
config S390
def_bool y
#
@ -140,7 +143,6 @@ config S390
select ARCH_INLINE_WRITE_UNLOCK_IRQ
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
select ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE
select ARCH_MODULE_NEEDS_WEAK_PER_CPU
select ARCH_STACKWALK
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_DEBUG_PAGEALLOC
@ -245,6 +247,7 @@ config S390
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_SETUP_PER_CPU_AREA
select HAVE_SOFTIRQ_ON_OWN_STACK
select HAVE_STACKPROTECTOR if CC_HAS_STACKPROTECTOR_GLOBAL
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_VIRT_CPU_ACCOUNTING
select HAVE_VIRT_CPU_ACCOUNTING_IDLE
@ -504,22 +507,6 @@ config COMMAND_LINE_SIZE
This allows you to specify the maximum length of the kernel command
line.
config COMPAT
def_bool n
prompt "Kernel support for 31 bit emulation"
select ARCH_WANT_OLD_COMPAT_IPC
select COMPAT_OLD_SIGACTION
select HAVE_UID16
depends on MULTIUSER
depends on !CC_IS_CLANG && !LD_IS_LLD
help
Select this option if you want to enable your system kernel to
handle system-calls from ELF binaries for 31 bit ESA. This option
(and some other stuff like libraries and such) is needed for
executing 31 bit applications.
If unsure say N.
config SMP
def_bool y

View File

@ -90,6 +90,10 @@ ifdef CONFIG_EXPOLINE
aflags-y += -DCC_USING_EXPOLINE
endif
ifeq ($(CONFIG_STACKPROTECTOR),y)
KBUILD_CFLAGS += -mstack-protector-guard=global -mstack-protector-guard-record
endif
ifdef CONFIG_FUNCTION_TRACER
ifeq ($(call cc-option,-mfentry -mnop-mcount),)
# make use of hotpatch feature if the compiler supports it
@ -135,10 +139,9 @@ zfcpdump:
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
archheaders:
$(Q)$(MAKE) $(build)=$(syscalls) uapi
$(Q)$(MAKE) $(build)=$(syscalls) all
archprepare:
$(Q)$(MAKE) $(build)=$(syscalls) kapi
$(Q)$(MAKE) $(build)=$(tools) kapi $(extra_tools)
ifeq ($(KBUILD_EXTMOD),)
# We need to generate vdso-offsets.h before compiling certain files in kernel/.
@ -149,12 +152,9 @@ ifeq ($(KBUILD_EXTMOD),)
# this hack.
prepare: vdso_prepare
vdso_prepare: prepare0
$(Q)$(MAKE) $(build)=arch/s390/kernel/vdso64 include/generated/vdso64-offsets.h
$(if $(CONFIG_COMPAT),$(Q)$(MAKE) \
$(build)=arch/s390/kernel/vdso32 include/generated/vdso32-offsets.h)
$(Q)$(MAKE) $(build)=arch/s390/kernel/vdso include/generated/vdso-offsets.h
vdso-install-y += arch/s390/kernel/vdso64/vdso64.so.dbg
vdso-install-$(CONFIG_COMPAT) += arch/s390/kernel/vdso32/vdso32.so.dbg
vdso-install-y += arch/s390/kernel/vdso/vdso.so.dbg
endif

View File

@ -9,8 +9,7 @@
* Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
*/
#define KMSG_COMPONENT "appldata"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "appldata: " fmt
#include <linux/export.h>
#include <linux/module.h>

View File

@ -8,8 +8,7 @@
* Author: Gerald Schaefer <gerald.schaefer@de.ibm.com>
*/
#define KMSG_COMPONENT "appldata"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "appldata: " fmt
#include <linux/module.h>
#include <linux/init.h>

View File

@ -32,6 +32,7 @@ obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-y += $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
obj-$(CONFIG_KMSAN) += kmsan.o
obj-$(CONFIG_STACKPROTECTOR) += stackprotector.o
obj-all := $(obj-y) piggy.o syms.o
targets := bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)

View File

@ -28,6 +28,10 @@ struct vmlinux_info {
unsigned long invalid_pg_dir_off;
unsigned long alt_instructions;
unsigned long alt_instructions_end;
#ifdef CONFIG_STACKPROTECTOR
unsigned long stack_prot_start;
unsigned long stack_prot_end;
#endif
#ifdef CONFIG_KASAN
unsigned long kasan_early_shadow_page_off;
unsigned long kasan_early_shadow_pte_off;

View File

@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/compat.h>
#include <linux/ptrace.h>
#include <asm/cio.h>
#include <asm/asm-offsets.h>
@ -12,7 +11,7 @@
#define PSW_MASK_DISABLED (PSW_MASK_WAIT | PSW_MASK_EA | PSW_MASK_BA)
struct ipl_lowcore {
psw_t32 ipl_psw; /* 0x0000 */
psw32_t ipl_psw; /* 0x0000 */
struct ccw0 ccwpgm[2]; /* 0x0008 */
u8 fill[56]; /* 0x0018 */
struct ccw0 ccwpgmcc[20]; /* 0x0050 */

View File

@ -3,6 +3,7 @@
#include <linux/init.h>
#include <linux/ctype.h>
#include <linux/pgtable.h>
#include <asm/arch-stackprotector.h>
#include <asm/abs_lowcore.h>
#include <asm/page-states.h>
#include <asm/machine.h>
@ -294,6 +295,11 @@ void parse_boot_command_line(void)
cmma_flag = 0;
}
#ifdef CONFIG_STACKPROTECTOR
if (!strcmp(param, "debug_stackprotector"))
stack_protector_debug = 1;
#endif
#if IS_ENABLED(CONFIG_KVM)
if (!strcmp(param, "prot_virt")) {
rc = kstrtobool(val, &enabled);

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
#define boot_fmt(fmt) "stackprot: " fmt
#include "boot.h"
#include "../kernel/stackprotector.c"

View File

@ -20,6 +20,9 @@
#include <asm/uv.h>
#include <asm/abs_lowcore.h>
#include <asm/physmem_info.h>
#include <asm/stacktrace.h>
#include <asm/asm-offsets.h>
#include <asm/arch-stackprotector.h>
#include "decompressor.h"
#include "boot.h"
#include "uv.h"
@ -477,6 +480,10 @@ static void kaslr_adjust_vmlinux_info(long offset)
vmlinux.invalid_pg_dir_off += offset;
vmlinux.alt_instructions += offset;
vmlinux.alt_instructions_end += offset;
#ifdef CONFIG_STACKPROTECTOR
vmlinux.stack_prot_start += offset;
vmlinux.stack_prot_end += offset;
#endif
#ifdef CONFIG_KASAN
vmlinux.kasan_early_shadow_page_off += offset;
vmlinux.kasan_early_shadow_pte_off += offset;
@ -622,6 +629,7 @@ void startup_kernel(void)
__apply_alternatives((struct alt_instr *)_vmlinux_info.alt_instructions,
(struct alt_instr *)_vmlinux_info.alt_instructions_end,
ALT_CTX_EARLY);
stack_protector_apply_early(text_lma);
/*
* Save KASLR offset for early dumps, before vmcore_info is set.

View File

@ -1,3 +0,0 @@
# Help: Enable compat support
CONFIG_COMPAT=y
CONFIG_COMPAT_32BIT_TIME=y

View File

@ -14,8 +14,7 @@
* Derived from "crypto/aes_generic.c"
*/
#define KMSG_COMPONENT "aes_s390"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "aes_s390: " fmt
#include <crypto/aes.h>
#include <crypto/algapi.h>

View File

@ -5,8 +5,7 @@
* s390 specific HMAC support.
*/
#define KMSG_COMPONENT "hmac_s390"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "hmac_s390: " fmt
#include <asm/cpacf.h>
#include <crypto/internal/hash.h>

View File

@ -10,8 +10,7 @@
* Harald Freudenberger <freude@de.ibm.com>
*/
#define KMSG_COMPONENT "paes_s390"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "paes_s390: " fmt
#include <linux/atomic.h>
#include <linux/cpufeature.h>

View File

@ -5,8 +5,7 @@
* s390 specific HMAC support for protected keys.
*/
#define KMSG_COMPONENT "phmac_s390"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "phmac_s390: " fmt
#include <asm/cpacf.h>
#include <asm/pkey.h>

View File

@ -6,8 +6,7 @@
* Driver for the s390 pseudo random number generator
*/
#define KMSG_COMPONENT "prng"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "prng: " fmt
#include <linux/fs.h>
#include <linux/fips.h>

View File

@ -7,8 +7,7 @@
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
*/
#define KMSG_COMPONENT "hypfs"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "hypfs: " fmt
#include <linux/types.h>
#include <linux/errno.h>

View File

@ -7,8 +7,7 @@
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
*/
#define KMSG_COMPONENT "hypfs"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "hypfs: " fmt
#include <linux/types.h>
#include <linux/errno.h>

View File

@ -7,7 +7,6 @@
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <linux/compat.h>
#include <linux/errno.h>
#include <linux/gfp.h>
#include <linux/string.h>
@ -116,10 +115,7 @@ static long hypfs_sprp_ioctl(struct file *file, unsigned int cmd,
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (is_compat_task())
argp = compat_ptr(arg);
else
argp = (void __user *) arg;
argp = (void __user *)arg;
switch (cmd) {
case HYPFS_DIAG304:
return __hypfs_sprp_ioctl(argp);

View File

@ -6,8 +6,7 @@
* Author(s): Michael Holzheu <holzheu@de.ibm.com>
*/
#define KMSG_COMPONENT "hypfs"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "hypfs: " fmt
#include <linux/types.h>
#include <linux/errno.h>

View File

@ -38,16 +38,30 @@ typedef unsigned int ap_qid_t;
* The ap queue status word is returned by all three AP functions
* (PQAP, NQAP and DQAP). There's a set of flags in the first
* byte, followed by a 1 byte response code.
*
* For convenience the 'value' field is a 32 bit access of the
* whole status and the 'status_bits' and 'rc' fields comprise
* the leftmost 8 status bits and the response_code.
*/
struct ap_queue_status {
unsigned int queue_empty : 1;
unsigned int replies_waiting : 1;
unsigned int queue_full : 1;
unsigned int : 3;
unsigned int async : 1;
unsigned int irq_enabled : 1;
unsigned int response_code : 8;
unsigned int : 16;
union {
unsigned int value : 32;
struct {
unsigned int status_bits : 8;
unsigned int rc : 8;
unsigned int : 16;
};
struct {
unsigned int queue_empty : 1;
unsigned int replies_waiting : 1;
unsigned int queue_full : 1;
unsigned int : 3;
unsigned int async : 1;
unsigned int irq_enabled : 1;
unsigned int response_code : 8;
unsigned int : 16;
};
};
};
/*

View File

@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390_ARCH_STACKPROTECTOR_H
#define _ASM_S390_ARCH_STACKPROTECTOR_H
extern unsigned long __stack_chk_guard;
extern int stack_protector_debug;
void __stack_protector_apply_early(unsigned long kernel_start);
int __stack_protector_apply(unsigned long *start, unsigned long *end, unsigned long kernel_start);
static inline void stack_protector_apply_early(unsigned long kernel_start)
{
if (IS_ENABLED(CONFIG_STACKPROTECTOR))
__stack_protector_apply_early(kernel_start);
}
static inline int stack_protector_apply(unsigned long *start, unsigned long *end)
{
if (IS_ENABLED(CONFIG_STACKPROTECTOR))
return __stack_protector_apply(start, end, 0);
return 0;
}
#endif /* _ASM_S390_ARCH_STACKPROTECTOR_H */

View File

@ -18,6 +18,8 @@
#include <asm/scsw.h>
#define CCW_MAX_BYTE_COUNT 65535
/**
* struct ccw1 - channel command word
* @cmd_code: command code

View File

@ -1,140 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390X_COMPAT_H
#define _ASM_S390X_COMPAT_H
/*
* Architecture specific compatibility types
*/
#include <linux/types.h>
#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;
#define __compat_uid_t __compat_uid_t
typedef u16 __compat_uid_t;
typedef u16 __compat_gid_t;
#define compat_dev_t compat_dev_t
typedef u16 compat_dev_t;
#define compat_ipc_pid_t compat_ipc_pid_t
typedef u16 compat_ipc_pid_t;
#define compat_statfs compat_statfs
#include <asm-generic/compat.h>
#define __TYPE_IS_PTR(t) (!__builtin_types_compatible_p( \
typeof(0?(__force t)0:0ULL), u64))
#define __SC_DELOUSE(t,v) ({ \
BUILD_BUG_ON(sizeof(t) > 4 && !__TYPE_IS_PTR(t)); \
(__force t)(__TYPE_IS_PTR(t) ? ((v) & 0x7fffffff) : (v)); \
})
#define PSW32_MASK_USER 0x0000FF00UL
#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 | \
PSW32_ASC_PRIMARY)
#define COMPAT_UTS_MACHINE "s390\0\0\0\0"
typedef u16 compat_nlink_t;
typedef struct {
u32 mask;
u32 addr;
} __aligned(8) psw_compat_t;
typedef struct {
psw_compat_t psw;
u32 gprs[NUM_GPRS];
u32 acrs[NUM_ACRS];
u32 orig_gpr2;
} s390_compat_regs;
typedef struct {
u32 gprs_high[NUM_GPRS];
} s390_compat_regs_high;
struct compat_stat {
compat_dev_t st_dev;
u16 __pad1;
compat_ino_t st_ino;
compat_mode_t st_mode;
compat_nlink_t st_nlink;
__compat_uid_t st_uid;
__compat_gid_t st_gid;
compat_dev_t st_rdev;
u16 __pad2;
u32 st_size;
u32 st_blksize;
u32 st_blocks;
u32 st_atime;
u32 st_atime_nsec;
u32 st_mtime;
u32 st_mtime_nsec;
u32 st_ctime;
u32 st_ctime_nsec;
u32 __unused4;
u32 __unused5;
};
struct compat_statfs {
u32 f_type;
u32 f_bsize;
u32 f_blocks;
u32 f_bfree;
u32 f_bavail;
u32 f_files;
u32 f_ffree;
compat_fsid_t f_fsid;
u32 f_namelen;
u32 f_frsize;
u32 f_flags;
u32 f_spare[4];
};
struct compat_statfs64 {
u32 f_type;
u32 f_bsize;
u64 f_blocks;
u64 f_bfree;
u64 f_bavail;
u64 f_files;
u64 f_ffree;
compat_fsid_t f_fsid;
u32 f_namelen;
u32 f_frsize;
u32 f_flags;
u32 f_spare[5];
};
/*
* A pointer passed in from user mode. This should not
* be used for syscall parameters, just declare them
* as pointers because the syscall entry code will have
* appropriately converted them already.
*/
static inline void __user *compat_ptr(compat_uptr_t uptr)
{
return (void __user *)(unsigned long)(uptr & 0x7fffffffUL);
}
#define compat_ptr(uptr) compat_ptr(uptr)
#ifdef CONFIG_COMPAT
static inline int is_compat_task(void)
{
return test_thread_flag(TIF_31BIT);
}
#endif
#endif /* _ASM_S390X_COMPAT_H */

View File

@ -27,7 +27,6 @@ int cpu_have_feature(unsigned int nr);
#define cpu_has_edat1() test_facility(8)
#define cpu_has_edat2() test_facility(78)
#define cpu_has_gs() test_facility(133)
#define cpu_has_idte() test_facility(3)
#define cpu_has_nx() test_facility(130)
#define cpu_has_rdp() test_facility(194)
#define cpu_has_seq_insn() test_facility(85)

View File

@ -162,8 +162,6 @@ enum {
* ELF register definitions..
*/
#include <linux/compat.h>
#include <asm/ptrace.h>
#include <asm/syscall.h>
#include <asm/user.h>
@ -171,9 +169,6 @@ enum {
typedef s390_fp_regs elf_fpregset_t;
typedef s390_regs elf_gregset_t;
typedef s390_fp_regs compat_elf_fpregset_t;
typedef s390_compat_regs compat_elf_gregset_t;
#include <linux/sched/mm.h> /* for task_struct */
#include <asm/mmu_context.h>
@ -183,10 +178,6 @@ typedef s390_compat_regs compat_elf_gregset_t;
#define elf_check_arch(x) \
(((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \
&& (x)->e_ident[EI_CLASS] == ELF_CLASS)
#define compat_elf_check_arch(x) \
(((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \
&& (x)->e_ident[EI_CLASS] == ELF_CLASS)
#define compat_start_thread start_thread31
/* For SVR4/S390 the function pointer to be registered with `atexit` is
passed in R14. */
@ -203,9 +194,7 @@ typedef s390_compat_regs compat_elf_gregset_t;
the loader. We need to make sure that it is out of the way of the program
that it will "exec", and that there is sufficient room for the brk. 64-bit
tasks are aligned to 4GB. */
#define ELF_ET_DYN_BASE (is_compat_task() ? \
(STACK_TOP / 3 * 2) : \
(STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
#define ELF_ET_DYN_BASE ((STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
/* This yields a mask that user programs can use to figure out what
instruction set this CPU supports. */
@ -224,43 +213,21 @@ extern unsigned long elf_hwcap;
extern char elf_platform[];
#define ELF_PLATFORM (elf_platform)
#ifndef CONFIG_COMPAT
#define SET_PERSONALITY(ex) \
do { \
set_personality(PER_LINUX | \
(current->personality & (~PER_MASK))); \
current->thread.sys_call_table = sys_call_table; \
} while (0)
#else /* CONFIG_COMPAT */
#define SET_PERSONALITY(ex) \
do { \
if (personality(current->personality) != PER_LINUX32) \
set_personality(PER_LINUX | \
(current->personality & ~PER_MASK)); \
if ((ex).e_ident[EI_CLASS] == ELFCLASS32) { \
set_thread_flag(TIF_31BIT); \
current->thread.sys_call_table = \
sys_call_table_emu; \
} else { \
clear_thread_flag(TIF_31BIT); \
current->thread.sys_call_table = \
sys_call_table; \
} \
} while (0)
#endif /* CONFIG_COMPAT */
/*
* Cache aliasing on the latest machines calls for a mapping granularity
* of 512KB for the anonymous mapping base. For 64-bit processes use a
* 512KB alignment and a randomization of up to 1GB. For 31-bit processes
* the virtual address space is limited, use no alignment and limit the
* randomization to 8MB.
* For the additional randomization of the program break use 32MB for
* 64-bit and 8MB for 31-bit.
* of 512KB for the anonymous mapping base. Use a 512KB alignment and a
* randomization of up to 1GB.
* For the additional randomization of the program break use 32MB.
*/
#define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x1fffUL)
#define MMAP_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ff80UL)
#define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL)
#define BRK_RND_MASK (0x1fffUL)
#define MMAP_RND_MASK (0x3ff80UL)
#define MMAP_ALIGN_MASK (0x7fUL)
#define STACK_RND_MASK MMAP_RND_MASK
/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */

View File

@ -12,6 +12,7 @@
#ifndef __ASSEMBLER__
#include <linux/instrumented.h>
#include <linux/kmsan.h>
#include <asm/asm-extable.h>
asm(".include \"asm/fpu-insn-asm.h\"\n");
@ -393,6 +394,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
: [vxr] "=Q" (*(u8 *)vxr)
: [index] "d" (index), [v1] "I" (v1)
: "memory");
kmsan_unpoison_memory(vxr, size);
}
#else /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */
@ -409,6 +411,7 @@ static __always_inline void fpu_vstl(u8 v1, u32 index, const void *vxr)
: [vxr] "=R" (*(u8 *)vxr)
: [index] "d" (index), [v1] "I" (v1)
: "memory", "1");
kmsan_unpoison_memory(vxr, size);
}
#endif /* CONFIG_CC_HAS_ASM_AOR_FORMAT_FLAGS */

View File

@ -105,28 +105,11 @@ static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsi
}
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
/*
* Even though the system call numbers are identical for s390/s390x a
* different system call table is used for compat tasks. This may lead
* to e.g. incorrect or missing trace event sysfs files.
* Therefore simply do not trace compat system calls at all.
* See kernel/trace/trace_syscalls.c.
*/
#define ARCH_TRACE_IGNORE_COMPAT_SYSCALLS
static inline bool arch_trace_is_compat_syscall(struct pt_regs *regs)
{
return is_compat_task();
}
#define ARCH_HAS_SYSCALL_MATCH_SYM_NAME
static inline bool arch_syscall_match_sym_name(const char *sym,
const char *name)
{
/*
* Skip __s390_ and __s390x_ prefix - due to compat wrappers
* and aliasing some symbols of 64 bit system call functions
* may get the __s390_ prefix instead of the __s390x_ prefix.
*/
/* Skip the __s390x_ prefix. */
return !strcmp(sym + 7, name) || !strcmp(sym + 8, name);
}

View File

@ -180,6 +180,82 @@ static inline void idal_buffer_free(struct idal_buffer *ib)
kfree(ib);
}
/*
* Allocate an array of IDAL buffers to cover a total data size of @size. The
* resulting array is null-terminated.
*
* The amount of individual IDAL buffers is determined based on @size.
* Each IDAL buffer can have a maximum size of @CCW_MAX_BYTE_COUNT.
*/
static inline struct idal_buffer **idal_buffer_array_alloc(size_t size, int page_order)
{
struct idal_buffer **ibs;
size_t ib_size; /* Size of a single idal buffer */
int count; /* Amount of individual idal buffers */
int i;
count = (size + CCW_MAX_BYTE_COUNT - 1) / CCW_MAX_BYTE_COUNT;
ibs = kmalloc_array(count + 1, sizeof(*ibs), GFP_KERNEL);
for (i = 0; i < count; i++) {
/* Determine size for the current idal buffer */
ib_size = min(size, CCW_MAX_BYTE_COUNT);
size -= ib_size;
ibs[i] = idal_buffer_alloc(ib_size, page_order);
if (IS_ERR(ibs[i])) {
while (i--)
idal_buffer_free(ibs[i]);
kfree(ibs);
ibs = NULL;
return ERR_PTR(-ENOMEM);
}
}
ibs[i] = NULL;
return ibs;
}
/*
* Free array of IDAL buffers
*/
static inline void idal_buffer_array_free(struct idal_buffer ***ibs)
{
struct idal_buffer **p;
if (!ibs || !*ibs)
return;
for (p = *ibs; *p; p++)
idal_buffer_free(*p);
kfree(*ibs);
*ibs = NULL;
}
/*
* Determine size of IDAL buffer array
*/
static inline int idal_buffer_array_size(struct idal_buffer **ibs)
{
int size = 0;
while (ibs && *ibs) {
size++;
ibs++;
}
return size;
}
/*
* Determine total data size covered by IDAL buffer array
*/
static inline size_t idal_buffer_array_datasize(struct idal_buffer **ibs)
{
size_t size = 0;
while (ibs && *ibs) {
size += (*ibs)->size;
ibs++;
}
return size;
}
/*
* Test if a idal list is really needed.
*/

View File

@ -100,7 +100,8 @@ struct lowcore {
/* Save areas. */
__u64 save_area[8]; /* 0x0200 */
__u8 pad_0x0240[0x0280-0x0240]; /* 0x0240 */
__u64 stack_canary; /* 0x0240 */
__u8 pad_0x0248[0x0280-0x0248]; /* 0x0248 */
__u64 save_area_restart[1]; /* 0x0280 */
__u64 pcpu; /* 0x0288 */

View File

@ -77,6 +77,7 @@ static __always_inline void pai_kernel_exit(struct pt_regs *regs)
#define PAI_SAVE_AREA(x) ((x)->hw.event_base)
#define PAI_CPU_MASK(x) ((x)->hw.addr_filters)
#define PAI_PMU_IDX(x) ((x)->hw.last_tag)
#define PAI_SWLIST(x) (&(x)->hw.tp_list)
#endif

View File

@ -12,14 +12,6 @@
*/
#define __my_cpu_offset get_lowcore()->percpu_offset
/*
* For 64 bit module code, the module may be more than 4G above the
* per cpu area, use weak definitions to force the compiler to
* generate external references.
* Therefore, we have enabled CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU
* in the Kconfig.
*/
/*
* We use a compare-and-swap loop since that uses less cpu cycles than
* disabling and enabling interrupts like the generic variant would do.

View File

@ -648,18 +648,6 @@ static inline int mm_uses_skeys(struct mm_struct *mm)
return 0;
}
static inline void csp(unsigned int *ptr, unsigned int old, unsigned int new)
{
union register_pair r1 = { .even = old, .odd = new, };
unsigned long address = (unsigned long)ptr | 1;
asm volatile(
" csp %[r1],%[address]"
: [r1] "+&d" (r1.pair), "+m" (*ptr)
: [address] "d" (address)
: "cc");
}
/**
* cspg() - Compare and Swap and Purge (CSPG)
* @ptr: Pointer to the value to be exchanged
@ -1400,7 +1388,6 @@ int set_pgste_bits(struct mm_struct *mm, unsigned long addr,
int get_pgste(struct mm_struct *mm, unsigned long hva, unsigned long *pgstep);
int pgste_perform_essa(struct mm_struct *mm, unsigned long hva, int orc,
unsigned long *oldpte, unsigned long *oldpgste);
void gmap_pmdp_csp(struct mm_struct *mm, unsigned long vmaddr);
void gmap_pmdp_invalidate(struct mm_struct *mm, unsigned long vmaddr);
void gmap_pmdp_idte_local(struct mm_struct *mm, unsigned long vmaddr);
void gmap_pmdp_idte_global(struct mm_struct *mm, unsigned long vmaddr);
@ -1690,10 +1677,10 @@ static inline pmd_t mk_pmd_phys(unsigned long physpage, pgprot_t pgprot)
#endif /* CONFIG_TRANSPARENT_HUGEPAGE || CONFIG_HUGETLB_PAGE */
static inline void __pmdp_csp(pmd_t *pmdp)
static inline void __pmdp_cspg(pmd_t *pmdp)
{
csp((unsigned int *)pmdp + 1, pmd_val(*pmdp),
pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
cspg((unsigned long *)pmdp, pmd_val(*pmdp),
pmd_val(*pmdp) | _SEGMENT_ENTRY_INVALID);
}
#define IDTE_GLOBAL 0

View File

@ -119,18 +119,12 @@ extern void execve_tail(void);
unsigned long vdso_text_size(void);
unsigned long vdso_size(void);
/*
* User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
*/
#define TASK_SIZE (test_thread_flag(TIF_31BIT) ? \
_REGION3_SIZE : TASK_SIZE_MAX)
#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \
(_REGION3_SIZE >> 1) : (_REGION2_SIZE >> 1))
#define TASK_SIZE (TASK_SIZE_MAX)
#define TASK_UNMAPPED_BASE (_REGION2_SIZE >> 1)
#define TASK_SIZE_MAX (-PAGE_SIZE)
#define VDSO_BASE (STACK_TOP + PAGE_SIZE)
#define VDSO_LIMIT (test_thread_flag(TIF_31BIT) ? _REGION3_SIZE : _REGION2_SIZE)
#define VDSO_LIMIT (_REGION2_SIZE)
#define STACK_TOP (VDSO_LIMIT - vdso_size() - PAGE_SIZE)
#define STACK_TOP_MAX (_REGION2_SIZE - vdso_size() - PAGE_SIZE)
@ -181,7 +175,6 @@ struct thread_struct {
unsigned long system_timer; /* task cputime in kernel space */
unsigned long hardirq_timer; /* task cputime in hardirq context */
unsigned long softirq_timer; /* task cputime in softirq context */
const sys_call_ptr_t *sys_call_table; /* system call table address */
union teid gmap_teid; /* address and flags of last gmap fault */
unsigned int gmap_int_code; /* int code of last gmap fault */
int ufpu_flags; /* user fpu flags */
@ -379,14 +372,19 @@ static inline void local_mcck_enable(void)
/*
* Rewind PSW instruction address by specified number of bytes.
*/
static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc)
static inline unsigned long __rewind_psw(psw_t psw, long ilen)
{
unsigned long mask;
mask = (psw.mask & PSW_MASK_EA) ? -1UL :
(psw.mask & PSW_MASK_BA) ? (1UL << 31) - 1 :
(1UL << 24) - 1;
return (psw.addr - ilc) & mask;
return (psw.addr - ilen) & mask;
}
static inline unsigned long __forward_psw(psw_t psw, long ilen)
{
return __rewind_psw(psw, -ilen);
}
/*

View File

@ -8,16 +8,19 @@
#define _S390_PTRACE_H
#include <linux/bits.h>
#include <linux/typecheck.h>
#include <uapi/asm/ptrace.h>
#include <asm/thread_info.h>
#include <asm/tpi.h>
#define PIF_SYSCALL 0 /* inside a system call */
#define PIF_PSW_ADDR_ADJUSTED 1 /* psw address has been adjusted */
#define PIF_SYSCALL_RET_SET 2 /* return value was set via ptrace */
#define PIF_GUEST_FAULT 3 /* indicates program check in sie64a */
#define PIF_FTRACE_FULL_REGS 4 /* all register contents valid (ftrace) */
#define _PIF_SYSCALL BIT(PIF_SYSCALL)
#define _PIF_ADDR_PSW_ADJUSTED BIT(PIF_PSW_ADDR_ADJUSTED)
#define _PIF_SYSCALL_RET_SET BIT(PIF_SYSCALL_RET_SET)
#define _PIF_GUEST_FAULT BIT(PIF_GUEST_FAULT)
#define _PIF_FTRACE_FULL_REGS BIT(PIF_FTRACE_FULL_REGS)
@ -99,7 +102,7 @@ enum {
typedef struct {
unsigned int mask;
unsigned int addr;
} psw_t32 __aligned(8);
} psw32_t __aligned(8);
#define PGM_INT_CODE_MASK 0x7f
#define PGM_INT_CODE_PER 0x80

View File

@ -19,10 +19,5 @@
#define SECCOMP_ARCH_NATIVE AUDIT_ARCH_S390X
#define SECCOMP_ARCH_NATIVE_NR NR_syscalls
#define SECCOMP_ARCH_NATIVE_NAME "s390x"
#ifdef CONFIG_COMPAT
# define SECCOMP_ARCH_COMPAT AUDIT_ARCH_S390
# define SECCOMP_ARCH_COMPAT_NR NR_syscalls
# define SECCOMP_ARCH_COMPAT_NAME "s390"
#endif
#endif /* _ASM_S390_SECCOMP_H */

View File

@ -43,7 +43,7 @@ extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
extern void smp_call_ipl_cpu(void (*func)(void *), void *);
extern void __noreturn smp_call_ipl_cpu(void (*func)(void *), void *data);
extern void smp_emergency_stop(void);
extern int smp_find_processor_id(u16 address);

View File

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390_STACKPROTECTOR_H
#define _ASM_S390_STACKPROTECTOR_H
#include <linux/sched.h>
#include <asm/current.h>
#include <asm/lowcore.h>
static __always_inline void boot_init_stack_canary(void)
{
current->stack_canary = get_random_canary();
get_lowcore()->stack_canary = current->stack_canary;
}
#endif /* _ASM_S390_STACKPROTECTOR_H */

View File

@ -15,7 +15,6 @@
#include <asm/ptrace.h>
extern const sys_call_ptr_t sys_call_table[];
extern const sys_call_ptr_t sys_call_table_emu[];
static inline long syscall_get_nr(struct task_struct *task,
struct pt_regs *regs)
@ -46,15 +45,7 @@ static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
unsigned long error = regs->gprs[2];
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_31BIT)) {
/*
* Sign-extend the value so (int)-EFOO becomes (long)-EFOO
* and will match correctly in comparisons.
*/
error = (long)(int)error;
}
#endif
return IS_ERR_VALUE(error) ? error : 0;
}
@ -78,10 +69,6 @@ static inline void syscall_get_arguments(struct task_struct *task,
{
unsigned long mask = -1UL;
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_31BIT))
mask = 0xffffffff;
#endif
for (int i = 1; i < 6; i++)
args[i] = regs->gprs[2 + i] & mask;
@ -99,10 +86,6 @@ static inline void syscall_set_arguments(struct task_struct *task,
static inline int syscall_get_arch(struct task_struct *task)
{
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_31BIT))
return AUDIT_ARCH_S390;
#endif
return AUDIT_ARCH_S390X;
}

View File

@ -13,101 +13,12 @@
,, regs->orig_gpr2,, regs->gprs[3],, regs->gprs[4] \
,, regs->gprs[5],, regs->gprs[6],, regs->gprs[7])
#ifdef CONFIG_COMPAT
#define __SC_COMPAT_CAST(t, a) \
({ \
long __ReS = a; \
\
BUILD_BUG_ON((sizeof(t) > 4) && !__TYPE_IS_L(t) && \
!__TYPE_IS_UL(t) && !__TYPE_IS_PTR(t) && \
!__TYPE_IS_LL(t)); \
if (__TYPE_IS_L(t)) \
__ReS = (s32)a; \
if (__TYPE_IS_UL(t)) \
__ReS = (u32)a; \
if (__TYPE_IS_PTR(t)) \
__ReS = a & 0x7fffffff; \
if (__TYPE_IS_LL(t)) \
return -ENOSYS; \
(t)__ReS; \
})
/*
* To keep the naming coherent, re-define SYSCALL_DEFINE0 to create an alias
* named __s390x_sys_*()
*/
#define COMPAT_SYSCALL_DEFINE0(sname) \
long __s390_compat_sys_##sname(void); \
ALLOW_ERROR_INJECTION(__s390_compat_sys_##sname, ERRNO); \
long __s390_compat_sys_##sname(void)
#define SYSCALL_DEFINE0(sname) \
SYSCALL_METADATA(_##sname, 0); \
long __s390_sys_##sname(void); \
ALLOW_ERROR_INJECTION(__s390_sys_##sname, ERRNO); \
long __s390x_sys_##sname(void); \
long __s390x_sys_##sname(struct pt_regs *__unused); \
ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \
static inline long __do_sys_##sname(void); \
long __s390_sys_##sname(void) \
{ \
return __do_sys_##sname(); \
} \
long __s390x_sys_##sname(void) \
{ \
return __do_sys_##sname(); \
} \
static inline long __do_sys_##sname(void)
#define COND_SYSCALL(name) \
cond_syscall(__s390x_sys_##name); \
cond_syscall(__s390_sys_##name)
#define COMPAT_SYSCALL_DEFINEx(x, name, ...) \
long __s390_compat_sys##name(struct pt_regs *regs); \
ALLOW_ERROR_INJECTION(__s390_compat_sys##name, ERRNO); \
static inline long __se_compat_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)); \
static inline long __do_compat_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__)); \
long __s390_compat_sys##name(struct pt_regs *regs) \
{ \
return __se_compat_sys##name(SC_S390_REGS_TO_ARGS(x, __VA_ARGS__)); \
} \
static inline long __se_compat_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)) \
{ \
__MAP(x, __SC_TEST, __VA_ARGS__); \
return __do_compat_sys##name(__MAP(x, __SC_DELOUSE, __VA_ARGS__)); \
} \
static inline long __do_compat_sys##name(__MAP(x, __SC_DECL, __VA_ARGS__))
/*
* As some compat syscalls may not be implemented, we need to expand
* COND_SYSCALL_COMPAT in kernel/sys_ni.c to cover this case as well.
*/
#define COND_SYSCALL_COMPAT(name) \
cond_syscall(__s390_compat_sys_##name)
#define __S390_SYS_STUBx(x, name, ...) \
long __s390_sys##name(struct pt_regs *regs); \
ALLOW_ERROR_INJECTION(__s390_sys##name, ERRNO); \
static inline long ___se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)); \
long __s390_sys##name(struct pt_regs *regs) \
{ \
return ___se_sys##name(SC_S390_REGS_TO_ARGS(x, __VA_ARGS__)); \
} \
static inline long ___se_sys##name(__MAP(x, __SC_LONG, __VA_ARGS__)) \
{ \
__MAP(x, __SC_TEST, __VA_ARGS__); \
return __do_sys##name(__MAP(x, __SC_COMPAT_CAST, __VA_ARGS__)); \
}
#else /* CONFIG_COMPAT */
#define SYSCALL_DEFINE0(sname) \
SYSCALL_METADATA(_##sname, 0); \
long __s390x_sys_##sname(void); \
ALLOW_ERROR_INJECTION(__s390x_sys_##sname, ERRNO); \
static inline long __do_sys_##sname(void); \
long __s390x_sys_##sname(void) \
long __s390x_sys_##sname(struct pt_regs *__unused) \
{ \
return __do_sys_##sname(); \
} \
@ -118,8 +29,6 @@
#define __S390_SYS_STUBx(x, fullname, name, ...)
#endif /* CONFIG_COMPAT */
#define __SYSCALL_DEFINEx(x, name, ...) \
long __s390x_sys##name(struct pt_regs *regs); \
ALLOW_ERROR_INJECTION(__s390x_sys##name, ERRNO); \

View File

@ -69,7 +69,6 @@ void arch_setup_new_exec(void);
#define TIF_GUARDED_STORAGE 17 /* load guarded storage control block */
#define TIF_ISOLATE_BP_GUEST 18 /* Run KVM guests with isolated BP */
#define TIF_PER_TRAP 19 /* Need to handle PER trap on exit to usermode */
#define TIF_31BIT 20 /* 32bit process */
#define TIF_SINGLE_STEP 21 /* This task is single stepped */
#define TIF_BLOCK_STEP 22 /* This task is block stepped */
#define TIF_UPROBE_SINGLESTEP 23 /* This task is uprobe single stepped */
@ -78,7 +77,6 @@ void arch_setup_new_exec(void);
#define _TIF_GUARDED_STORAGE BIT(TIF_GUARDED_STORAGE)
#define _TIF_ISOLATE_BP_GUEST BIT(TIF_ISOLATE_BP_GUEST)
#define _TIF_PER_TRAP BIT(TIF_PER_TRAP)
#define _TIF_31BIT BIT(TIF_31BIT)
#define _TIF_SINGLE_STEP BIT(TIF_SINGLE_STEP)
#define _TIF_BLOCK_STEP BIT(TIF_BLOCK_STEP)
#define _TIF_UPROBE_SINGLESTEP BIT(TIF_UPROBE_SINGLESTEP)

View File

@ -35,9 +35,9 @@ static inline void __tlb_flush_idte(unsigned long asce)
*/
static inline void __tlb_flush_global(void)
{
unsigned int dummy = 0;
unsigned long dummy = 0;
csp(&dummy, 0, 0);
cspg(&dummy, 0, 0);
}
/*
@ -54,7 +54,7 @@ static inline void __tlb_flush_mm(struct mm_struct *mm)
cpumask_copy(mm_cpumask(mm), &mm->context.cpu_attach_mask);
barrier();
gmap_asce = READ_ONCE(mm->context.gmap_asce);
if (cpu_has_idte() && gmap_asce != -1UL) {
if (gmap_asce != -1UL) {
if (gmap_asce)
__tlb_flush_idte(gmap_asce);
__tlb_flush_idte(mm->context.asce);
@ -68,10 +68,7 @@ static inline void __tlb_flush_mm(struct mm_struct *mm)
static inline void __tlb_flush_kernel(void)
{
if (cpu_has_idte())
__tlb_flush_idte(init_mm.context.asce);
else
__tlb_flush_global();
__tlb_flush_idte(init_mm.context.asce);
}
static inline void __tlb_flush_mm_lazy(struct mm_struct * mm)
@ -86,7 +83,6 @@ static inline void __tlb_flush_mm_lazy(struct mm_struct * mm)
/*
* TLB flushing:
* flush_tlb() - flushes the current mm struct TLBs
* flush_tlb_all() - flushes all processes TLBs
* flush_tlb_mm(mm) - flushes the specified mm context TLB's
* flush_tlb_page(vma, vmaddr) - flushes one page
@ -102,7 +98,6 @@ static inline void __tlb_flush_mm_lazy(struct mm_struct * mm)
* only one user. At the end of the update the flush_tlb_mm and
* flush_tlb_range functions need to do the flush.
*/
#define flush_tlb() do { } while (0)
#define flush_tlb_all() do { } while (0)
#define flush_tlb_page(vma, addr) do { } while (0)

View File

@ -0,0 +1,87 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Tracepoint definitions for s390 ap bus related trace events
*
* There are two AP bus related tracepoint events defined here:
* There is a tracepoint s390_ap_nqap event immediately after a request
* has been pushed into the AP firmware queue with the NQAP AP command.
* The other tracepoint s390_ap_dqap event fires immediately after a
* reply has been pulled out of the AP firmware queue via DQAP AP command.
* The idea of these two trace events focuses on performance to measure
* the runtime of a crypto request/reply as close as possible at the
* firmware level. In combination with the two zcrypt tracepoints (see the
* zcrypt.h trace event definition file) this gives measurement data about
* the runtime of a request/reply within the zcrpyt and AP bus layer.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM s390
#if !defined(_TRACE_S390_AP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_S390_AP_H
#include <linux/tracepoint.h>
DECLARE_EVENT_CLASS(s390_ap_nqapdqap_template,
TP_PROTO(u16 card, u16 dom, u32 status, u64 psmid),
TP_ARGS(card, dom, status, psmid),
TP_STRUCT__entry(
__field(u16, card)
__field(u16, dom)
__field(u32, status)
__field(u64, psmid)),
TP_fast_assign(
__entry->card = card;
__entry->dom = dom;
__entry->status = status;
__entry->psmid = psmid;),
TP_printk("card=%u dom=%u status=0x%08x psmid=0x%016lx",
(unsigned short)__entry->card,
(unsigned short)__entry->dom,
(unsigned int)__entry->status,
(unsigned long)__entry->psmid)
);
/**
* trace_s390_ap_nqap - ap msg nqap tracepoint function
* @card: Crypto card number addressed.
* @dom: Domain within the crypto card addressed.
* @status: AP queue status (GR1 on return of nqap).
* @psmid: Unique id identifying this request/reply.
*
* Called immediately after a request has been enqueued into
* the AP firmware queue with the NQAP command.
*/
DEFINE_EVENT(s390_ap_nqapdqap_template,
s390_ap_nqap,
TP_PROTO(u16 card, u16 dom, u32 status, u64 psmid),
TP_ARGS(card, dom, status, psmid)
);
/**
* trace_s390_ap_dqap - ap msg dqap tracepoint function
* @card: Crypto card number addressed.
* @dom: Domain within the crypto card addressed.
* @status: AP queue status (GR1 on return of dqap).
* @psmid: Unique id identifying this request/reply.
*
* Called immediately after a reply has been dequeued from
* the AP firmware queue with the DQAP command.
*/
DEFINE_EVENT(s390_ap_nqapdqap_template,
s390_ap_dqap,
TP_PROTO(u16 card, u16 dom, u32 status, u64 psmid),
TP_ARGS(card, dom, status, psmid)
);
#endif /* _TRACE_S390_AP_H */
/* This part must be outside protection */
#undef TRACE_INCLUDE_PATH
#undef TRACE_INCLUDE_FILE
#define TRACE_INCLUDE_PATH asm/trace
#define TRACE_INCLUDE_FILE ap
#include <trace/define_trace.h>

View File

@ -2,7 +2,7 @@
/*
* Tracepoint definitions for the s390 zcrypt device driver
*
* Copyright IBM Corp. 2016
* Copyright IBM Corp. 2016,2025
* Author(s): Harald Freudenberger <freude@de.ibm.com>
*
* Currently there are two tracepoint events defined here.
@ -73,14 +73,15 @@ TRACE_EVENT(s390_zcrypt_req,
/**
* trace_s390_zcrypt_rep - zcrypt reply tracepoint function
* @ptr: Address of the local buffer where the request from userspace
* is stored. Can be used as a unique id to match together
* request and reply.
* @fc: Function code.
* @rc: The bare returncode as returned by the device driver ioctl
* function.
* @dev: The adapter nr where this request was actually processed.
* @dom: Domain id of the device where this request was processed.
* @ptr: Address of the local buffer where the request from userspace
* is stored. Can be used as a unique id to match together
* request and reply.
* @fc: Function code.
* @rc: The bare returncode as returned by the device driver ioctl
* function.
* @card: The adapter nr where this request was actually processed.
* @dom: Domain id of the device where this request was processed.
* @psmid: Unique id identifying this request/reply.
*
* Called upon recognising the reply from the crypto adapter. This
* message may act as the exit timestamp for the request but also
@ -88,26 +89,29 @@ TRACE_EVENT(s390_zcrypt_req,
* and the returncode from the device driver.
*/
TRACE_EVENT(s390_zcrypt_rep,
TP_PROTO(void *ptr, u32 fc, u32 rc, u16 dev, u16 dom),
TP_ARGS(ptr, fc, rc, dev, dom),
TP_PROTO(void *ptr, u32 fc, u32 rc, u16 card, u16 dom, u64 psmid),
TP_ARGS(ptr, fc, rc, card, dom, psmid),
TP_STRUCT__entry(
__field(void *, ptr)
__field(u32, fc)
__field(u32, rc)
__field(u16, device)
__field(u16, domain)),
__field(u16, card)
__field(u16, dom)
__field(u64, psmid)),
TP_fast_assign(
__entry->ptr = ptr;
__entry->fc = fc;
__entry->rc = rc;
__entry->device = dev;
__entry->domain = dom;),
TP_printk("ptr=%p fc=0x%04x rc=%d dev=0x%02hx domain=0x%04hx",
__entry->card = card;
__entry->dom = dom;
__entry->psmid = psmid;),
TP_printk("ptr=%p fc=0x%04x rc=%d card=%u dom=%u psmid=0x%016lx",
__entry->ptr,
(unsigned int) __entry->fc,
(int) __entry->rc,
(unsigned short) __entry->device,
(unsigned short) __entry->domain)
(unsigned int)__entry->fc,
(int)__entry->rc,
(unsigned short)__entry->card,
(unsigned short)__entry->dom,
(unsigned long)__entry->psmid)
);
#endif /* _TRACE_S390_ZCRYPT_H */

View File

@ -8,7 +8,8 @@
#define _ASM_S390_UNISTD_H_
#include <uapi/asm/unistd.h>
#include <asm/unistd_nr.h>
#define NR_syscalls (__NR_syscalls)
#define __ARCH_WANT_NEW_STAT
#define __ARCH_WANT_OLD_READDIR
@ -27,11 +28,6 @@
#define __ARCH_WANT_SYS_OLDUMOUNT
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
# ifdef CONFIG_COMPAT
# define __ARCH_WANT_COMPAT_STAT
# define __ARCH_WANT_SYS_TIME32
# define __ARCH_WANT_SYS_UTIME32
# endif
#define __ARCH_WANT_SYS_FORK
#define __ARCH_WANT_SYS_VFORK
#define __ARCH_WANT_SYS_CLONE

View File

@ -2,16 +2,8 @@
#ifndef __S390_VDSO_SYMBOLS_H__
#define __S390_VDSO_SYMBOLS_H__
#include <generated/vdso64-offsets.h>
#ifdef CONFIG_COMPAT
#include <generated/vdso32-offsets.h>
#endif
#include <generated/vdso-offsets.h>
#define VDSO64_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso64_offset_##name))
#ifdef CONFIG_COMPAT
#define VDSO32_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso32_offset_##name))
#else
#define VDSO32_SYMBOL(tsk, name) (-1UL)
#endif
#define VDSO_SYMBOL(tsk, name) ((tsk)->mm->context.vdso_base + (vdso_offset_##name))
#endif /* __S390_VDSO_SYMBOLS_H__ */

View File

@ -2,11 +2,7 @@
#ifndef __ASM_S390_BITSPERLONG_H
#define __ASM_S390_BITSPERLONG_H
#ifndef __s390x__
#define __BITS_PER_LONG 32
#else
#define __BITS_PER_LONG 64
#endif
#include <asm-generic/bitsperlong.h>

View File

@ -24,9 +24,6 @@ struct ipc64_perm
__kernel_mode_t mode;
unsigned short __pad1;
unsigned short seq;
#ifndef __s390x__
unsigned short __pad2;
#endif /* ! __s390x__ */
unsigned long __unused1;
unsigned long __unused2;
};

View File

@ -26,17 +26,6 @@ typedef unsigned short __kernel_old_gid_t;
#define __kernel_old_uid_t __kernel_old_uid_t
#endif
#ifndef __s390x__
typedef unsigned long __kernel_ino_t;
typedef unsigned short __kernel_mode_t;
typedef unsigned short __kernel_ipc_pid_t;
typedef unsigned short __kernel_uid_t;
typedef unsigned short __kernel_gid_t;
typedef int __kernel_ptrdiff_t;
#else /* __s390x__ */
typedef unsigned int __kernel_ino_t;
typedef unsigned int __kernel_mode_t;
typedef int __kernel_ipc_pid_t;
@ -45,8 +34,6 @@ typedef unsigned int __kernel_gid_t;
typedef long __kernel_ptrdiff_t;
typedef unsigned long __kernel_sigset_t; /* at least 32 bits */
#endif /* __s390x__ */
#define __kernel_ino_t __kernel_ino_t
#define __kernel_mode_t __kernel_mode_t
#define __kernel_ipc_pid_t __kernel_ipc_pid_t

View File

@ -14,94 +14,6 @@
* Offsets in the user_regs_struct. They are used for the ptrace
* system call and in entry.S
*/
#ifndef __s390x__
#define PT_PSWMASK 0x00
#define PT_PSWADDR 0x04
#define PT_GPR0 0x08
#define PT_GPR1 0x0C
#define PT_GPR2 0x10
#define PT_GPR3 0x14
#define PT_GPR4 0x18
#define PT_GPR5 0x1C
#define PT_GPR6 0x20
#define PT_GPR7 0x24
#define PT_GPR8 0x28
#define PT_GPR9 0x2C
#define PT_GPR10 0x30
#define PT_GPR11 0x34
#define PT_GPR12 0x38
#define PT_GPR13 0x3C
#define PT_GPR14 0x40
#define PT_GPR15 0x44
#define PT_ACR0 0x48
#define PT_ACR1 0x4C
#define PT_ACR2 0x50
#define PT_ACR3 0x54
#define PT_ACR4 0x58
#define PT_ACR5 0x5C
#define PT_ACR6 0x60
#define PT_ACR7 0x64
#define PT_ACR8 0x68
#define PT_ACR9 0x6C
#define PT_ACR10 0x70
#define PT_ACR11 0x74
#define PT_ACR12 0x78
#define PT_ACR13 0x7C
#define PT_ACR14 0x80
#define PT_ACR15 0x84
#define PT_ORIGGPR2 0x88
#define PT_FPC 0x90
/*
* A nasty fact of life that the ptrace api
* only supports passing of longs.
*/
#define PT_FPR0_HI 0x98
#define PT_FPR0_LO 0x9C
#define PT_FPR1_HI 0xA0
#define PT_FPR1_LO 0xA4
#define PT_FPR2_HI 0xA8
#define PT_FPR2_LO 0xAC
#define PT_FPR3_HI 0xB0
#define PT_FPR3_LO 0xB4
#define PT_FPR4_HI 0xB8
#define PT_FPR4_LO 0xBC
#define PT_FPR5_HI 0xC0
#define PT_FPR5_LO 0xC4
#define PT_FPR6_HI 0xC8
#define PT_FPR6_LO 0xCC
#define PT_FPR7_HI 0xD0
#define PT_FPR7_LO 0xD4
#define PT_FPR8_HI 0xD8
#define PT_FPR8_LO 0XDC
#define PT_FPR9_HI 0xE0
#define PT_FPR9_LO 0xE4
#define PT_FPR10_HI 0xE8
#define PT_FPR10_LO 0xEC
#define PT_FPR11_HI 0xF0
#define PT_FPR11_LO 0xF4
#define PT_FPR12_HI 0xF8
#define PT_FPR12_LO 0xFC
#define PT_FPR13_HI 0x100
#define PT_FPR13_LO 0x104
#define PT_FPR14_HI 0x108
#define PT_FPR14_LO 0x10C
#define PT_FPR15_HI 0x110
#define PT_FPR15_LO 0x114
#define PT_CR_9 0x118
#define PT_CR_10 0x11C
#define PT_CR_11 0x120
#define PT_IEEE_IP 0x13C
#define PT_LASTOFF PT_IEEE_IP
#define PT_ENDREGS 0x140-1
#define GPR_SIZE 4
#define CR_SIZE 4
#define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */
#else /* __s390x__ */
#define PT_PSWMASK 0x00
#define PT_PSWADDR 0x08
#define PT_GPR0 0x10
@ -166,38 +78,6 @@
#define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */
#endif /* __s390x__ */
#ifndef __s390x__
#define PSW_MASK_PER _AC(0x40000000, UL)
#define PSW_MASK_DAT _AC(0x04000000, UL)
#define PSW_MASK_IO _AC(0x02000000, UL)
#define PSW_MASK_EXT _AC(0x01000000, UL)
#define PSW_MASK_KEY _AC(0x00F00000, UL)
#define PSW_MASK_BASE _AC(0x00080000, UL) /* always one */
#define PSW_MASK_MCHECK _AC(0x00040000, UL)
#define PSW_MASK_WAIT _AC(0x00020000, UL)
#define PSW_MASK_PSTATE _AC(0x00010000, UL)
#define PSW_MASK_ASC _AC(0x0000C000, UL)
#define PSW_MASK_CC _AC(0x00003000, UL)
#define PSW_MASK_PM _AC(0x00000F00, UL)
#define PSW_MASK_RI _AC(0x00000000, UL)
#define PSW_MASK_EA _AC(0x00000000, UL)
#define PSW_MASK_BA _AC(0x00000000, UL)
#define PSW_MASK_USER _AC(0x0000FF00, UL)
#define PSW_ADDR_AMODE _AC(0x80000000, UL)
#define PSW_ADDR_INSN _AC(0x7FFFFFFF, UL)
#define PSW_ASC_PRIMARY _AC(0x00000000, UL)
#define PSW_ASC_ACCREG _AC(0x00004000, UL)
#define PSW_ASC_SECONDARY _AC(0x00008000, UL)
#define PSW_ASC_HOME _AC(0x0000C000, UL)
#else /* __s390x__ */
#define PSW_MASK_PER _AC(0x4000000000000000, UL)
#define PSW_MASK_DAT _AC(0x0400000000000000, UL)
#define PSW_MASK_IO _AC(0x0200000000000000, UL)
@ -224,8 +104,6 @@
#define PSW_ASC_SECONDARY _AC(0x0000800000000000, UL)
#define PSW_ASC_HOME _AC(0x0000C00000000000, UL)
#endif /* __s390x__ */
#define NUM_GPRS 16
#define NUM_FPRS 16
#define NUM_CRS 16
@ -308,9 +186,7 @@ typedef struct {
#define PER_EM_MASK 0xE8000000UL
typedef struct {
#ifdef __s390x__
unsigned : 32;
#endif /* __s390x__ */
unsigned em_branching : 1;
unsigned em_instruction_fetch : 1;
/*

View File

@ -17,24 +17,12 @@
#define __NUM_VXRS_LOW 16
#define __NUM_VXRS_HIGH 16
#ifndef __s390x__
/* Has to be at least _NSIG_WORDS from asm/signal.h */
#define _SIGCONTEXT_NSIG 64
#define _SIGCONTEXT_NSIG_BPW 32
/* Size of stack frame allocated when calling signal handler. */
#define __SIGNAL_FRAMESIZE 96
#else /* __s390x__ */
/* Has to be at least _NSIG_WORDS from asm/signal.h */
#define _SIGCONTEXT_NSIG 64
#define _SIGCONTEXT_NSIG_BPW 64
/* Size of stack frame allocated when calling signal handler. */
#define __SIGNAL_FRAMESIZE 160
#endif /* __s390x__ */
#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
@ -66,9 +54,6 @@ typedef struct
typedef struct
{
#ifndef __s390x__
unsigned long gprs_high[__NUM_GPRS];
#endif
unsigned long long vxrs_low[__NUM_VXRS_LOW];
__vector128 vxrs_high[__NUM_VXRS_HIGH];
unsigned char __reserved[128];

View File

@ -8,74 +8,6 @@
#ifndef _S390_STAT_H
#define _S390_STAT_H
#ifndef __s390x__
struct __old_kernel_stat {
unsigned short st_dev;
unsigned short st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned long st_size;
unsigned long st_atime;
unsigned long st_mtime;
unsigned long st_ctime;
};
struct stat {
unsigned short st_dev;
unsigned short __pad1;
unsigned long st_ino;
unsigned short st_mode;
unsigned short st_nlink;
unsigned short st_uid;
unsigned short st_gid;
unsigned short st_rdev;
unsigned short __pad2;
unsigned long st_size;
unsigned long st_blksize;
unsigned long st_blocks;
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec;
unsigned long __unused4;
unsigned long __unused5;
};
/* This matches struct stat64 in glibc2.1, hence the absolutely
* insane amounts of padding around dev_t's.
*/
struct stat64 {
unsigned long long st_dev;
unsigned int __pad1;
#define STAT64_HAS_BROKEN_ST_INO 1
unsigned long __st_ino;
unsigned int st_mode;
unsigned int st_nlink;
unsigned long st_uid;
unsigned long st_gid;
unsigned long long st_rdev;
unsigned int __pad3;
long long st_size;
unsigned long st_blksize;
unsigned char __pad4[4];
unsigned long __pad5; /* future possible st_blocks high bits */
unsigned long st_blocks; /* Number 512-byte blocks allocated. */
unsigned long st_atime;
unsigned long st_atime_nsec;
unsigned long st_mtime;
unsigned long st_mtime_nsec;
unsigned long st_ctime;
unsigned long st_ctime_nsec; /* will be high 32 bits of ctime someday */
unsigned long long st_ino;
};
#else /* __s390x__ */
struct stat {
unsigned long st_dev;
unsigned long st_ino;
@ -97,8 +29,6 @@ struct stat {
unsigned long __unused[3];
};
#endif /* __s390x__ */
#define STAT_HAVE_NSEC 1
#endif

View File

@ -8,10 +8,6 @@
#ifndef _UAPI_ASM_S390_UNISTD_H_
#define _UAPI_ASM_S390_UNISTD_H_
#ifdef __s390x__
#include <asm/unistd_64.h>
#else
#include <asm/unistd_32.h>
#endif
#endif /* _UAPI_ASM_S390_UNISTD_H_ */

View File

@ -36,7 +36,7 @@ CFLAGS_stacktrace.o += -fno-optimize-sibling-calls
CFLAGS_dumpstack.o += -fno-optimize-sibling-calls
CFLAGS_unwind_bc.o += -fno-optimize-sibling-calls
obj-y := head64.o traps.o time.o process.o early.o setup.o idle.o vtime.o
obj-y := head.o traps.o time.o process.o early.o setup.o idle.o vtime.o
obj-y += processor.o syscall.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o
obj-y += debug.o irq.o ipl.o dis.o vdso.o cpufeature.o
obj-y += sysinfo.o lgr.o os_info.o ctlreg.o
@ -56,9 +56,6 @@ obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o hiperdispatch.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_AUDIT) += audit.o
compat-obj-$(CONFIG_AUDIT) += compat_audit.o
obj-$(CONFIG_COMPAT) += compat_linux.o compat_signal.o
obj-$(CONFIG_COMPAT) += $(compat-obj-y)
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KPROBES) += kprobes.o
obj-$(CONFIG_KPROBES) += mcount.o
@ -70,7 +67,7 @@ obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o
obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o
obj-$(CONFIG_UPROBES) += uprobes.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o
obj-$(CONFIG_STACKPROTECTOR) += stackprotector.o
obj-$(CONFIG_KEXEC_FILE) += machine_kexec_file.o kexec_image.o
obj-$(CONFIG_KEXEC_FILE) += kexec_elf.o
obj-$(CONFIG_CERT_STORE) += cert_store.o
@ -79,10 +76,9 @@ obj-$(CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT) += ima_arch.o
obj-$(CONFIG_PERF_EVENTS) += perf_event.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 perf_pai_ext.o
obj-$(CONFIG_PERF_EVENTS) += perf_pai.o
obj-$(CONFIG_TRACEPOINTS) += trace.o
# vdso
obj-y += vdso64/
obj-$(CONFIG_COMPAT) += vdso32/
obj-y += vdso/

View File

@ -21,6 +21,9 @@ int main(void)
OFFSET(__TASK_stack, task_struct, stack);
OFFSET(__TASK_thread, task_struct, thread);
OFFSET(__TASK_pid, task_struct, pid);
#ifdef CONFIG_STACKPROTECTOR
OFFSET(__TASK_stack_canary, task_struct, stack_canary);
#endif
BLANK();
/* thread struct offsets */
OFFSET(__THREAD_ksp, thread_struct, ksp);
@ -139,6 +142,7 @@ int main(void)
OFFSET(__LC_CURRENT_PID, lowcore, current_pid);
OFFSET(__LC_LAST_BREAK, lowcore, last_break);
/* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
OFFSET(__LC_STACK_CANARY, lowcore, stack_canary);
OFFSET(__LC_DUMP_REIPL, lowcore, ipib);
OFFSET(__LC_VMCORE_INFO, lowcore, vmcore_info);
OFFSET(__LC_OS_INFO, lowcore, os_info);

View File

@ -3,7 +3,6 @@
#include <linux/types.h>
#include <linux/audit.h>
#include <asm/unistd.h>
#include "audit.h"
static unsigned dir_class[] = {
#include <asm-generic/audit_dir_write.h>
@ -32,19 +31,11 @@ static unsigned signal_class[] = {
int audit_classify_arch(int arch)
{
#ifdef CONFIG_COMPAT
if (arch == AUDIT_ARCH_S390)
return 1;
#endif
return 0;
}
int audit_classify_syscall(int abi, unsigned syscall)
{
#ifdef CONFIG_COMPAT
if (abi == AUDIT_ARCH_S390)
return s390_classify_syscall(syscall);
#endif
switch(syscall) {
case __NR_open:
return AUDITSC_OPEN;
@ -63,13 +54,6 @@ int audit_classify_syscall(int abi, unsigned syscall)
static int __init audit_classes_init(void)
{
#ifdef CONFIG_COMPAT
audit_register_class(AUDIT_CLASS_WRITE_32, s390_write_class);
audit_register_class(AUDIT_CLASS_READ_32, s390_read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE_32, s390_dir_class);
audit_register_class(AUDIT_CLASS_CHATTR_32, s390_chattr_class);
audit_register_class(AUDIT_CLASS_SIGNAL_32, s390_signal_class);
#endif
audit_register_class(AUDIT_CLASS_WRITE, write_class);
audit_register_class(AUDIT_CLASS_READ, read_class);
audit_register_class(AUDIT_CLASS_DIR_WRITE, dir_class);

View File

@ -1,16 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ARCH_S390_KERNEL_AUDIT_H
#define __ARCH_S390_KERNEL_AUDIT_H
#include <linux/types.h>
#ifdef CONFIG_COMPAT
extern int s390_classify_syscall(unsigned);
extern __u32 s390_dir_class[];
extern __u32 s390_write_class[];
extern __u32 s390_read_class[];
extern __u32 s390_chattr_class[];
extern __u32 s390_signal_class[];
#endif /* CONFIG_COMPAT */
#endif /* __ARCH_S390_KERNEL_AUDIT_H */

View File

@ -1,48 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
#undef __s390x__
#include <linux/audit_arch.h>
#include <asm/unistd.h>
#include "audit.h"
unsigned s390_dir_class[] = {
#include <asm-generic/audit_dir_write.h>
~0U
};
unsigned s390_chattr_class[] = {
#include <asm-generic/audit_change_attr.h>
~0U
};
unsigned s390_write_class[] = {
#include <asm-generic/audit_write.h>
~0U
};
unsigned s390_read_class[] = {
#include <asm-generic/audit_read.h>
~0U
};
unsigned s390_signal_class[] = {
#include <asm-generic/audit_signal.h>
~0U
};
int s390_classify_syscall(unsigned syscall)
{
switch(syscall) {
case __NR_open:
return AUDITSC_OPEN;
case __NR_openat:
return AUDITSC_OPENAT;
case __NR_socketcall:
return AUDITSC_SOCKETCALL;
case __NR_execve:
return AUDITSC_EXECVE;
case __NR_openat2:
return AUDITSC_OPENAT2;
default:
return AUDITSC_COMPAT;
}
}

View File

@ -1,289 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* S390 version
* Copyright IBM Corp. 2000
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
* Gerhard Tonn (ton@de.ibm.com)
* Thomas Spatzier (tspat@de.ibm.com)
*
* Conversion between 31bit and 64bit native syscalls.
*
* Heavily inspired by the 32-bit Sparc compat code which is
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/signal.h>
#include <linux/resource.h>
#include <linux/times.h>
#include <linux/smp.h>
#include <linux/sem.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/uio.h>
#include <linux/quota.h>
#include <linux/poll.h>
#include <linux/personality.h>
#include <linux/stat.h>
#include <linux/filter.h>
#include <linux/highmem.h>
#include <linux/mman.h>
#include <linux/ipv6.h>
#include <linux/in.h>
#include <linux/icmpv6.h>
#include <linux/syscalls.h>
#include <linux/sysctl.h>
#include <linux/binfmts.h>
#include <linux/capability.h>
#include <linux/compat.h>
#include <linux/vfs.h>
#include <linux/ptrace.h>
#include <linux/fadvise.h>
#include <linux/ipc.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <linux/uaccess.h>
#include <net/scm.h>
#include <net/sock.h>
#include "compat_linux.h"
#ifdef CONFIG_SYSVIPC
COMPAT_SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, compat_ulong_t, second,
compat_ulong_t, third, compat_uptr_t, ptr)
{
if (call >> 16) /* hack for backward compatibility */
return -EINVAL;
return compat_ksys_ipc(call, first, second, third, ptr, third);
}
#endif
COMPAT_SYSCALL_DEFINE3(s390_truncate64, const char __user *, path, u32, high, u32, low)
{
return ksys_truncate(path, (unsigned long)high << 32 | low);
}
COMPAT_SYSCALL_DEFINE3(s390_ftruncate64, unsigned int, fd, u32, high, u32, low)
{
return ksys_ftruncate(fd, (unsigned long)high << 32 | low);
}
COMPAT_SYSCALL_DEFINE5(s390_pread64, unsigned int, fd, char __user *, ubuf,
compat_size_t, count, u32, high, u32, low)
{
if ((compat_ssize_t) count < 0)
return -EINVAL;
return ksys_pread64(fd, ubuf, count, (unsigned long)high << 32 | low);
}
COMPAT_SYSCALL_DEFINE5(s390_pwrite64, unsigned int, fd, const char __user *, ubuf,
compat_size_t, count, u32, high, u32, low)
{
if ((compat_ssize_t) count < 0)
return -EINVAL;
return ksys_pwrite64(fd, ubuf, count, (unsigned long)high << 32 | low);
}
COMPAT_SYSCALL_DEFINE4(s390_readahead, int, fd, u32, high, u32, low, s32, count)
{
return ksys_readahead(fd, (unsigned long)high << 32 | low, count);
}
struct stat64_emu31 {
unsigned long long st_dev;
unsigned int __pad1;
#define STAT64_HAS_BROKEN_ST_INO 1
u32 __st_ino;
unsigned int st_mode;
unsigned int st_nlink;
u32 st_uid;
u32 st_gid;
unsigned long long st_rdev;
unsigned int __pad3;
long st_size;
u32 st_blksize;
unsigned char __pad4[4];
u32 __pad5; /* future possible st_blocks high bits */
u32 st_blocks; /* Number 512-byte blocks allocated. */
u32 st_atime;
u32 __pad6;
u32 st_mtime;
u32 __pad7;
u32 st_ctime;
u32 __pad8; /* will be high 32 bits of ctime someday */
unsigned long st_ino;
};
static int cp_stat64(struct stat64_emu31 __user *ubuf, struct kstat *stat)
{
struct stat64_emu31 tmp;
memset(&tmp, 0, sizeof(tmp));
tmp.st_dev = huge_encode_dev(stat->dev);
tmp.st_ino = stat->ino;
tmp.__st_ino = (u32)stat->ino;
tmp.st_mode = stat->mode;
tmp.st_nlink = (unsigned int)stat->nlink;
tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
tmp.st_rdev = huge_encode_dev(stat->rdev);
tmp.st_size = stat->size;
tmp.st_blksize = (u32)stat->blksize;
tmp.st_blocks = (u32)stat->blocks;
tmp.st_atime = (u32)stat->atime.tv_sec;
tmp.st_mtime = (u32)stat->mtime.tv_sec;
tmp.st_ctime = (u32)stat->ctime.tv_sec;
return copy_to_user(ubuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
}
COMPAT_SYSCALL_DEFINE2(s390_stat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf)
{
struct kstat stat;
int ret = vfs_stat(filename, &stat);
if (!ret)
ret = cp_stat64(statbuf, &stat);
return ret;
}
COMPAT_SYSCALL_DEFINE2(s390_lstat64, const char __user *, filename, struct stat64_emu31 __user *, statbuf)
{
struct kstat stat;
int ret = vfs_lstat(filename, &stat);
if (!ret)
ret = cp_stat64(statbuf, &stat);
return ret;
}
COMPAT_SYSCALL_DEFINE2(s390_fstat64, unsigned int, fd, struct stat64_emu31 __user *, statbuf)
{
struct kstat stat;
int ret = vfs_fstat(fd, &stat);
if (!ret)
ret = cp_stat64(statbuf, &stat);
return ret;
}
COMPAT_SYSCALL_DEFINE4(s390_fstatat64, unsigned int, dfd, const char __user *, filename,
struct stat64_emu31 __user *, statbuf, int, flag)
{
struct kstat stat;
int error;
error = vfs_fstatat(dfd, filename, &stat, flag);
if (error)
return error;
return cp_stat64(statbuf, &stat);
}
/*
* Linux/i386 didn't use to be able to handle more than
* 4 system call parameters, so these system calls used a memory
* block for parameter passing..
*/
struct mmap_arg_struct_emu31 {
compat_ulong_t addr;
compat_ulong_t len;
compat_ulong_t prot;
compat_ulong_t flags;
compat_ulong_t fd;
compat_ulong_t offset;
};
COMPAT_SYSCALL_DEFINE1(s390_old_mmap, struct mmap_arg_struct_emu31 __user *, arg)
{
struct mmap_arg_struct_emu31 a;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
if (a.offset & ~PAGE_MASK)
return -EINVAL;
return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd,
a.offset >> PAGE_SHIFT);
}
COMPAT_SYSCALL_DEFINE1(s390_mmap2, struct mmap_arg_struct_emu31 __user *, arg)
{
struct mmap_arg_struct_emu31 a;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
return ksys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
}
COMPAT_SYSCALL_DEFINE3(s390_read, unsigned int, fd, char __user *, buf, compat_size_t, count)
{
if ((compat_ssize_t) count < 0)
return -EINVAL;
return ksys_read(fd, buf, count);
}
COMPAT_SYSCALL_DEFINE3(s390_write, unsigned int, fd, const char __user *, buf, compat_size_t, count)
{
if ((compat_ssize_t) count < 0)
return -EINVAL;
return ksys_write(fd, buf, count);
}
/*
* 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
* These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
* because the 31 bit values differ from the 64 bit values.
*/
COMPAT_SYSCALL_DEFINE5(s390_fadvise64, int, fd, u32, high, u32, low, compat_size_t, len, int, advise)
{
if (advise == 4)
advise = POSIX_FADV_DONTNEED;
else if (advise == 5)
advise = POSIX_FADV_NOREUSE;
return ksys_fadvise64_64(fd, (unsigned long)high << 32 | low, len,
advise);
}
struct fadvise64_64_args {
int fd;
long long offset;
long long len;
int advice;
};
COMPAT_SYSCALL_DEFINE1(s390_fadvise64_64, struct fadvise64_64_args __user *, args)
{
struct fadvise64_64_args a;
if ( copy_from_user(&a, args, sizeof(a)) )
return -EFAULT;
if (a.advice == 4)
a.advice = POSIX_FADV_DONTNEED;
else if (a.advice == 5)
a.advice = POSIX_FADV_NOREUSE;
return ksys_fadvise64_64(a.fd, a.offset, a.len, a.advice);
}
COMPAT_SYSCALL_DEFINE6(s390_sync_file_range, int, fd, u32, offhigh, u32, offlow,
u32, nhigh, u32, nlow, unsigned int, flags)
{
return ksys_sync_file_range(fd, ((loff_t)offhigh << 32) + offlow,
((u64)nhigh << 32) + nlow, flags);
}
COMPAT_SYSCALL_DEFINE6(s390_fallocate, int, fd, int, mode, u32, offhigh, u32, offlow,
u32, lenhigh, u32, lenlow)
{
return ksys_fallocate(fd, mode, ((loff_t)offhigh << 32) + offlow,
((u64)lenhigh << 32) + lenlow);
}

View File

@ -1,101 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390X_S390_H
#define _ASM_S390X_S390_H
#include <linux/compat.h>
#include <linux/socket.h>
#include <linux/syscalls.h>
#include <asm/ptrace.h>
/*
* 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;
};
/* asm/sigcontext.h */
typedef union {
__u64 d;
__u32 f;
} freg_t32;
typedef struct {
unsigned int fpc;
unsigned int pad;
freg_t32 fprs[__NUM_FPRS];
} _s390_fp_regs32;
typedef struct {
psw_t32 psw;
__u32 gprs[__NUM_GPRS];
__u32 acrs[__NUM_ACRS];
} _s390_regs_common32;
typedef struct {
_s390_regs_common32 regs;
_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];
} _sigregs_ext32;
#define _SIGCONTEXT_NSIG32 64
#define _SIGCONTEXT_NSIG_BPW32 32
#define __SIGNAL_FRAMESIZE32 96
#define _SIGMASK_COPY_SIZE32 (sizeof(u32) * 2)
struct sigcontext32 {
__u32 oldmask[_COMPAT_NSIG_WORDS];
__u32 sregs; /* pointer */
};
/* asm/signal.h */
/* asm/ucontext.h */
struct ucontext32 {
__u32 uc_flags;
__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. */
unsigned char __unused[128 - sizeof(compat_sigset_t)];
_sigregs_ext32 uc_mcontext_ext;
};
struct stat64_emu31;
struct mmap_arg_struct_emu31;
struct fadvise64_64_args;
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);
long compat_sys_s390_pwrite64(unsigned int fd, const char __user *ubuf, compat_size_t count, u32 high, u32 low);
long compat_sys_s390_readahead(int fd, u32 high, u32 low, s32 count);
long compat_sys_s390_stat64(const char __user *filename, struct stat64_emu31 __user *statbuf);
long compat_sys_s390_lstat64(const char __user *filename, struct stat64_emu31 __user *statbuf);
long compat_sys_s390_fstat64(unsigned int fd, struct stat64_emu31 __user *statbuf);
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_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);
long compat_sys_s390_fallocate(int fd, int mode, u32 offhigh, u32 offlow, u32 lenhigh, u32 lenlow);
long compat_sys_sigreturn(void);
long compat_sys_rt_sigreturn(void);
#endif /* _ASM_S390X_S390_H */

View File

@ -1,64 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _PTRACE32_H
#define _PTRACE32_H
#include <asm/ptrace.h> /* needed for NUM_CR_WORDS */
#include "compat_linux.h" /* needed for psw_compat_t */
struct compat_per_struct_kernel {
__u32 cr9; /* PER control bits */
__u32 cr10; /* PER starting address */
__u32 cr11; /* PER ending address */
__u32 bits; /* Obsolete software bits */
__u32 starting_addr; /* User specified start address */
__u32 ending_addr; /* User specified end address */
__u16 perc_atmid; /* PER trap ATMID */
__u32 address; /* PER trap instruction address */
__u8 access_id; /* PER trap access identification */
};
struct compat_user_regs_struct
{
psw_compat_t psw;
u32 gprs[NUM_GPRS];
u32 acrs[NUM_ACRS];
u32 orig_gpr2;
/* nb: there's a 4-byte hole here */
s390_fp_regs fp_regs;
/*
* These per registers are in here so that gdb can modify them
* itself as there is no "official" ptrace interface for hardware
* watchpoints. This is the way intel does it.
*/
struct compat_per_struct_kernel per_info;
u32 ieee_instruction_pointer; /* obsolete, always 0 */
};
struct compat_user {
/* We start with the registers, to mimic the way that "memory"
is returned from the ptrace(3,...) function. */
struct compat_user_regs_struct regs;
/* The rest of this junk is to help gdb figure out what goes where */
u32 u_tsize; /* Text segment size (pages). */
u32 u_dsize; /* Data segment size (pages). */
u32 u_ssize; /* Stack segment size (pages). */
u32 start_code; /* Starting virtual address of text. */
u32 start_stack; /* Starting virtual address of stack area.
This is actually the bottom of the stack,
the top of the stack is always found in the
esp register. */
s32 signal; /* Signal that caused the core dump. */
u32 u_ar0; /* Used by gdb to help find the values for */
/* the registers. */
u32 magic; /* To uniquely identify a core file */
char u_comm[32]; /* User command that was responsible */
};
typedef struct
{
__u32 len;
__u32 kernel_addr;
__u32 process_addr;
} compat_ptrace_area;
#endif /* _PTRACE32_H */

View File

@ -1,420 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright IBM Corp. 2000, 2006
* Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
* Gerhard Tonn (ton@de.ibm.com)
*
* Copyright (C) 1991, 1992 Linus Torvalds
*
* 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
*/
#include <linux/compat.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/mm.h>
#include <linux/smp.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/tty.h>
#include <linux/personality.h>
#include <linux/binfmts.h>
#include <asm/vdso-symbols.h>
#include <asm/access-regs.h>
#include <asm/ucontext.h>
#include <linux/uaccess.h>
#include <asm/lowcore.h>
#include <asm/fpu.h>
#include "compat_linux.h"
#include "compat_ptrace.h"
#include "entry.h"
typedef struct
{
__u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
struct sigcontext32 sc;
_sigregs32 sregs;
int signo;
_sigregs_ext32 sregs_ext;
__u16 svc_insn; /* Offset of svc_insn is NOT fixed! */
} sigframe32;
typedef struct
{
__u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
__u16 svc_insn;
compat_siginfo_t info;
struct ucontext32 uc;
} rt_sigframe32;
/* Store registers needed to create the signal frame */
static void store_sigregs(void)
{
save_access_regs(current->thread.acrs);
save_user_fpu_regs();
}
/* Load registers after signal return */
static void load_sigregs(void)
{
restore_access_regs(current->thread.acrs);
}
static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
{
_sigregs32 user_sregs;
int i;
user_sregs.regs.psw.mask = (__u32)(regs->psw.mask >> 32);
user_sregs.regs.psw.mask &= PSW32_MASK_USER | PSW32_MASK_RI;
user_sregs.regs.psw.mask |= PSW32_USER_BITS;
user_sregs.regs.psw.addr = (__u32) regs->psw.addr |
(__u32)(regs->psw.mask & PSW_MASK_BA);
for (i = 0; i < NUM_GPRS; i++)
user_sregs.regs.gprs[i] = (__u32) regs->gprs[i];
memcpy(&user_sregs.regs.acrs, current->thread.acrs,
sizeof(user_sregs.regs.acrs));
fpregs_store((_s390_fp_regs *) &user_sregs.fpregs, &current->thread.ufpu);
if (__copy_to_user(sregs, &user_sregs, sizeof(_sigregs32)))
return -EFAULT;
return 0;
}
static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
{
_sigregs32 user_sregs;
int i;
/* Always make any pending restarted system call return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
if (__copy_from_user(&user_sregs, &sregs->regs, sizeof(user_sregs)))
return -EFAULT;
if (!is_ri_task(current) && (user_sregs.regs.psw.mask & PSW32_MASK_RI))
return -EINVAL;
/* Use regs->psw.mask instead of PSW_USER_BITS to preserve PER bit. */
regs->psw.mask = (regs->psw.mask & ~(PSW_MASK_USER | PSW_MASK_RI)) |
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_USER) << 32 |
(__u64)(user_sregs.regs.psw.mask & PSW32_MASK_RI) << 32 |
(__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_AMODE);
/* Check for invalid user address space control. */
if ((regs->psw.mask & PSW_MASK_ASC) == PSW_ASC_HOME)
regs->psw.mask = PSW_ASC_PRIMARY |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64)(user_sregs.regs.psw.addr & PSW32_ADDR_INSN);
for (i = 0; i < NUM_GPRS; i++)
regs->gprs[i] = (__u64) user_sregs.regs.gprs[i];
memcpy(&current->thread.acrs, &user_sregs.regs.acrs,
sizeof(current->thread.acrs));
fpregs_load((_s390_fp_regs *)&user_sregs.fpregs, &current->thread.ufpu);
clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
return 0;
}
static int save_sigregs_ext32(struct pt_regs *regs,
_sigregs_ext32 __user *sregs_ext)
{
__u32 gprs_high[NUM_GPRS];
__u64 vxrs[__NUM_VXRS_LOW];
int i;
/* Save high gprs to signal stack */
for (i = 0; i < NUM_GPRS; i++)
gprs_high[i] = regs->gprs[i] >> 32;
if (__copy_to_user(&sregs_ext->gprs_high, &gprs_high,
sizeof(sregs_ext->gprs_high)))
return -EFAULT;
/* Save vector registers to signal stack */
if (cpu_has_vx()) {
for (i = 0; i < __NUM_VXRS_LOW; i++)
vxrs[i] = current->thread.ufpu.vxrs[i].low;
if (__copy_to_user(&sregs_ext->vxrs_low, vxrs,
sizeof(sregs_ext->vxrs_low)) ||
__copy_to_user(&sregs_ext->vxrs_high,
current->thread.ufpu.vxrs + __NUM_VXRS_LOW,
sizeof(sregs_ext->vxrs_high)))
return -EFAULT;
}
return 0;
}
static int restore_sigregs_ext32(struct pt_regs *regs,
_sigregs_ext32 __user *sregs_ext)
{
__u32 gprs_high[NUM_GPRS];
__u64 vxrs[__NUM_VXRS_LOW];
int i;
/* Restore high gprs from signal stack */
if (__copy_from_user(&gprs_high, &sregs_ext->gprs_high,
sizeof(sregs_ext->gprs_high)))
return -EFAULT;
for (i = 0; i < NUM_GPRS; i++)
*(__u32 *)&regs->gprs[i] = gprs_high[i];
/* Restore vector registers from signal stack */
if (cpu_has_vx()) {
if (__copy_from_user(vxrs, &sregs_ext->vxrs_low,
sizeof(sregs_ext->vxrs_low)) ||
__copy_from_user(current->thread.ufpu.vxrs + __NUM_VXRS_LOW,
&sregs_ext->vxrs_high,
sizeof(sregs_ext->vxrs_high)))
return -EFAULT;
for (i = 0; i < __NUM_VXRS_LOW; i++)
current->thread.ufpu.vxrs[i].low = vxrs[i];
}
return 0;
}
COMPAT_SYSCALL_DEFINE0(sigreturn)
{
struct pt_regs *regs = task_pt_regs(current);
sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
sigset_t set;
if (get_compat_sigset(&set, (compat_sigset_t __user *)frame->sc.oldmask))
goto badframe;
set_current_blocked(&set);
save_user_fpu_regs();
if (restore_sigregs32(regs, &frame->sregs))
goto badframe;
if (restore_sigregs_ext32(regs, &frame->sregs_ext))
goto badframe;
load_sigregs();
return regs->gprs[2];
badframe:
force_sig(SIGSEGV);
return 0;
}
COMPAT_SYSCALL_DEFINE0(rt_sigreturn)
{
struct pt_regs *regs = task_pt_regs(current);
rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
sigset_t set;
if (get_compat_sigset(&set, &frame->uc.uc_sigmask))
goto badframe;
set_current_blocked(&set);
if (compat_restore_altstack(&frame->uc.uc_stack))
goto badframe;
save_user_fpu_regs();
if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
goto badframe;
if (restore_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
goto badframe;
load_sigregs();
return regs->gprs[2];
badframe:
force_sig(SIGSEGV);
return 0;
}
/*
* Set up a signal frame.
*/
/*
* Determine which stack to use..
*/
static inline void __user *
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
{
unsigned long sp;
/* Default to using normal stack */
sp = (unsigned long) A(regs->gprs[15]);
/* Overflow on alternate signal stack gives SIGSEGV. */
if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
return (void __user *) -1UL;
/* This is the X/Open sanctioned signal stack switching. */
if (ka->sa.sa_flags & SA_ONSTACK) {
if (! sas_ss_flags(sp))
sp = current->sas_ss_sp + current->sas_ss_size;
}
return (void __user *)((sp - frame_size) & -8ul);
}
static int setup_frame32(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
int sig = ksig->sig;
sigframe32 __user *frame;
unsigned long restorer;
size_t frame_size;
/*
* gprs_high are always present for 31-bit compat tasks.
* The space for vector registers is only allocated if
* the machine supports it
*/
frame_size = sizeof(*frame) - sizeof(frame->sregs_ext.__reserved);
if (!cpu_has_vx())
frame_size -= sizeof(frame->sregs_ext.vxrs_low) +
sizeof(frame->sregs_ext.vxrs_high);
frame = get_sigframe(&ksig->ka, regs, frame_size);
if (frame == (void __user *) -1UL)
return -EFAULT;
/* Set up backchain. */
if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
return -EFAULT;
/* Create struct sigcontext32 on the signal stack */
if (put_compat_sigset((compat_sigset_t __user *)frame->sc.oldmask,
set, sizeof(compat_sigset_t)))
return -EFAULT;
if (__put_user(ptr_to_compat(&frame->sregs), &frame->sc.sregs))
return -EFAULT;
/* Store registers needed to create the signal frame */
store_sigregs();
/* Create _sigregs32 on the signal stack */
if (save_sigregs32(regs, &frame->sregs))
return -EFAULT;
/* Place signal number on stack to allow backtrace from handler. */
if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
return -EFAULT;
/* Create _sigregs_ext32 on the signal stack */
if (save_sigregs_ext32(regs, &frame->sregs_ext))
return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
restorer = (unsigned long __force)
ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
restorer = VDSO32_SYMBOL(current, sigreturn);
}
/* Set up registers for signal handler */
regs->gprs[14] = restorer;
regs->gprs[15] = (__force __u64) frame;
/* Force 31 bit amode and default user address space control. */
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__force __u64) ksig->ka.sa.sa_handler;
regs->gprs[2] = sig;
regs->gprs[3] = (__force __u64) &frame->sc;
/* We forgot to include these in the sigcontext.
To avoid breaking binary compatibility, they are passed as args. */
if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
sig == SIGTRAP || sig == SIGFPE) {
/* set extra registers only for synchronous signals */
regs->gprs[4] = regs->int_code & 127;
regs->gprs[5] = regs->int_parm_long;
regs->gprs[6] = current->thread.last_break;
}
return 0;
}
static int setup_rt_frame32(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs)
{
rt_sigframe32 __user *frame;
unsigned long restorer;
size_t frame_size;
u32 uc_flags;
frame_size = sizeof(*frame) -
sizeof(frame->uc.uc_mcontext_ext.__reserved);
/*
* gprs_high are always present for 31-bit compat tasks.
* The space for vector registers is only allocated if
* the machine supports it
*/
uc_flags = UC_GPRS_HIGH;
if (cpu_has_vx()) {
uc_flags |= UC_VXRS;
} else {
frame_size -= sizeof(frame->uc.uc_mcontext_ext.vxrs_low) +
sizeof(frame->uc.uc_mcontext_ext.vxrs_high);
}
frame = get_sigframe(&ksig->ka, regs, frame_size);
if (frame == (void __user *) -1UL)
return -EFAULT;
/* Set up backchain. */
if (__put_user(regs->gprs[15], (unsigned int __force __user *) frame))
return -EFAULT;
/* Set up to return from userspace. If provided, use a stub
already in userspace. */
if (ksig->ka.sa.sa_flags & SA_RESTORER) {
restorer = (unsigned long __force)
ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
} else {
restorer = VDSO32_SYMBOL(current, rt_sigreturn);
}
/* Create siginfo on the signal stack */
if (copy_siginfo_to_user32(&frame->info, &ksig->info))
return -EFAULT;
/* Store registers needed to create the signal frame */
store_sigregs();
/* Create ucontext on the signal stack. */
if (__put_user(uc_flags, &frame->uc.uc_flags) ||
__put_user(0, &frame->uc.uc_link) ||
__compat_save_altstack(&frame->uc.uc_stack, regs->gprs[15]) ||
save_sigregs32(regs, &frame->uc.uc_mcontext) ||
put_compat_sigset(&frame->uc.uc_sigmask, set, sizeof(compat_sigset_t)) ||
save_sigregs_ext32(regs, &frame->uc.uc_mcontext_ext))
return -EFAULT;
/* Set up registers for signal handler */
regs->gprs[14] = restorer;
regs->gprs[15] = (__force __u64) frame;
/* Force 31 bit amode and default user address space control. */
regs->psw.mask = PSW_MASK_BA |
(PSW_USER_BITS & PSW_MASK_ASC) |
(regs->psw.mask & ~PSW_MASK_ASC);
regs->psw.addr = (__u64 __force) ksig->ka.sa.sa_handler;
regs->gprs[2] = ksig->sig;
regs->gprs[3] = (__force __u64) &frame->info;
regs->gprs[4] = (__force __u64) &frame->uc;
regs->gprs[5] = current->thread.last_break;
return 0;
}
/*
* OK, we're invoking a handler
*/
void handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct pt_regs *regs)
{
int ret;
/* Set up the stack frame */
if (ksig->ka.sa.sa_flags & SA_SIGINFO)
ret = setup_rt_frame32(ksig, oldset, regs);
else
ret = setup_frame32(ksig, oldset, regs);
signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLE_STEP));
}

View File

@ -3,8 +3,7 @@
* Copyright IBM Corp. 2024
*/
#define KMSG_COMPONENT "cpacf"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "cpacf: " fmt
#include <linux/cpu.h>
#include <linux/device.h>

View File

@ -6,8 +6,7 @@
* Christian Borntraeger (cborntra@de.ibm.com),
*/
#define KMSG_COMPONENT "cpcmd"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "cpcmd: " fmt
#include <linux/kernel.h>
#include <linux/export.h>

View File

@ -10,8 +10,7 @@
* Bugreports to: <Linux390@de.ibm.com>
*/
#define KMSG_COMPONENT "s390dbf"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "s390dbf: " fmt
#include <linux/stddef.h>
#include <linux/kernel.h>

View File

@ -503,24 +503,27 @@ static int copy_from_regs(struct pt_regs *regs, void *dst, void *src, int len)
void show_code(struct pt_regs *regs)
{
char *mode = user_mode(regs) ? "User" : "Krnl";
unsigned long addr, pswaddr;
unsigned char code[64];
char buffer[128], *ptr;
unsigned long addr;
int start, end, opsize, hops, i;
pswaddr = regs->psw.addr;
if (test_pt_regs_flag(regs, PIF_PSW_ADDR_ADJUSTED))
pswaddr = __forward_psw(regs->psw, regs->int_code >> 16);
/* Get a snapshot of the 64 bytes surrounding the fault address. */
for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) {
addr = regs->psw.addr - 34 + start;
for (start = 32; start && pswaddr >= 34 - start; start -= 2) {
addr = pswaddr - 34 + start;
if (copy_from_regs(regs, code + start - 2, (void *)addr, 2))
break;
}
for (end = 32; end < 64; end += 2) {
addr = regs->psw.addr + end - 32;
addr = pswaddr + end - 32;
if (copy_from_regs(regs, code + end, (void *)addr, 2))
break;
}
/* Code snapshot usable ? */
if ((regs->psw.addr & 1) || start >= end) {
if ((pswaddr & 1) || start >= end) {
printk("%s Code: Bad PSW.\n", mode);
return;
}
@ -543,12 +546,12 @@ void show_code(struct pt_regs *regs)
while (start < end && hops < 8) {
opsize = insn_length(code[start]);
if (start + opsize == 32)
*ptr++ = '#';
*ptr++ = '*';
else if (start == 32)
*ptr++ = '>';
else
*ptr++ = ' ';
addr = regs->psw.addr + start - 32;
addr = pswaddr + start - 32;
ptr += sprintf(ptr, "%px: ", (void *)addr);
if (start + opsize >= end)
break;

View File

@ -155,12 +155,16 @@ static void show_last_breaking_event(struct pt_regs *regs)
void show_registers(struct pt_regs *regs)
{
struct psw_bits *psw = &psw_bits(regs->psw);
unsigned long pswaddr;
char *mode;
pswaddr = regs->psw.addr;
if (test_pt_regs_flag(regs, PIF_PSW_ADDR_ADJUSTED))
pswaddr = __forward_psw(regs->psw, regs->int_code >> 16);
mode = user_mode(regs) ? "User" : "Krnl";
printk("%s PSW : %px %px", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
printk("%s PSW : %px %px", mode, (void *)regs->psw.mask, (void *)pswaddr);
if (!user_mode(regs))
pr_cont(" (%pSR)", (void *)regs->psw.addr);
pr_cont(" (%pSR)", (void *)pswaddr);
pr_cont("\n");
printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
"P:%x AS:%x CC:%x PM:%x", psw->per, psw->dat, psw->io, psw->ext,

View File

@ -4,8 +4,7 @@
* Author(s): Hongjie Yang <hongjie@us.ibm.com>,
*/
#define KMSG_COMPONENT "setup"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "setup: " fmt
#include <linux/sched/debug.h>
#include <linux/cpufeature.h>
@ -120,21 +119,21 @@ static noinline __init void setup_arch_string(void)
EBCASC(mach->type, sizeof(mach->type));
EBCASC(mach->model, sizeof(mach->model));
EBCASC(mach->model_capacity, sizeof(mach->model_capacity));
sprintf(mstr, "%-16.16s %-4.4s %-16.16s %-16.16s",
mach->manufacturer, mach->type,
mach->model, mach->model_capacity);
scnprintf(mstr, sizeof(mstr), "%-16.16s %-4.4s %-16.16s %-16.16s",
mach->manufacturer, mach->type,
mach->model, mach->model_capacity);
strim_all(mstr);
if (stsi(vm, 3, 2, 2) == 0 && vm->count) {
EBCASC(vm->vm[0].cpi, sizeof(vm->vm[0].cpi));
sprintf(hvstr, "%-16.16s", vm->vm[0].cpi);
scnprintf(hvstr, sizeof(hvstr), "%-16.16s", vm->vm[0].cpi);
strim_all(hvstr);
} else {
sprintf(hvstr, "%s",
machine_is_lpar() ? "LPAR" :
machine_is_vm() ? "z/VM" :
machine_is_kvm() ? "KVM" : "unknown");
scnprintf(hvstr, sizeof(hvstr), "%s",
machine_is_lpar() ? "LPAR" :
machine_is_vm() ? "z/VM" :
machine_is_kvm() ? "KVM" : "unknown");
}
sprintf(arch_hw_string, "HW: %s (%s)", mstr, hvstr);
scnprintf(arch_hw_string, sizeof(arch_hw_string), "HW: %s (%s)", mstr, hvstr);
dump_stack_set_arch_desc("%s (%s)", mstr, hvstr);
}

View File

@ -162,9 +162,13 @@ SYM_FUNC_START(__switch_to_asm)
stg %r3,__LC_CURRENT(%r13) # store task struct of next
stg %r15,__LC_KERNEL_STACK(%r13) # store end of kernel stack
lg %r15,__THREAD_ksp(%r1,%r3) # load kernel stack of next
aghi %r3,__TASK_pid
mvc __LC_CURRENT_PID(4,%r13),0(%r3) # store pid of next
lay %r4,__TASK_pid(%r3)
mvc __LC_CURRENT_PID(4,%r13),0(%r4) # store pid of next
ALTERNATIVE "nop", "lpp _LPP_OFFSET(%r13)", ALT_FACILITY(40)
#ifdef CONFIG_STACKPROTECTOR
lg %r3,__TASK_stack_canary(%r3)
stg %r3,__LC_STACK_CANARY(%r13)
#endif
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
BR_EX %r14
SYM_FUNC_END(__switch_to_asm)
@ -606,20 +610,3 @@ SYM_DATA_START_LOCAL(daton_psw)
.quad PSW_KERNEL_BITS
.quad .Ldaton
SYM_DATA_END(daton_psw)
.section .rodata, "a"
.balign 8
#define SYSCALL(esame,emu) .quad __s390x_ ## esame
SYM_DATA_START(sys_call_table)
#include <asm/syscall_table.h>
SYM_DATA_END(sys_call_table)
#undef SYSCALL
#ifdef CONFIG_COMPAT
#define SYSCALL(esame,emu) .quad __s390_ ## emu
SYM_DATA_START(sys_call_table_emu)
#include <asm/syscall_table.h>
SYM_DATA_END(sys_call_table_emu)
#undef SYSCALL
#endif

View File

@ -3,8 +3,7 @@
* Copyright IBM Corp. 2024
*/
#define KMSG_COMPONENT "hd"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "hd: " fmt
/*
* Hiperdispatch:
@ -65,7 +64,7 @@
#define HD_DELAY_FACTOR (4)
#define HD_DELAY_INTERVAL (HZ / 4)
#define HD_STEAL_THRESHOLD 30
#define HD_STEAL_THRESHOLD 10
#define HD_STEAL_AVG_WEIGHT 16
static cpumask_t hd_vl_coremask; /* Mask containing all vertical low COREs */

View File

@ -22,12 +22,14 @@
#include <linux/bug.h>
#include <linux/memory.h>
#include <linux/execmem.h>
#include <asm/arch-stackprotector.h>
#include <asm/alternative.h>
#include <asm/nospec-branch.h>
#include <asm/facility.h>
#include <asm/ftrace.lds.h>
#include <asm/set_memory.h>
#include <asm/setup.h>
#include <asm/asm-offsets.h>
#if 0
#define DEBUGP printk
@ -495,9 +497,7 @@ int module_finalize(const Elf_Ehdr *hdr,
const Elf_Shdr *s;
char *secstrings, *secname;
void *aseg;
#ifdef CONFIG_FUNCTION_TRACER
int ret;
#endif
int rc = 0;
if (IS_ENABLED(CONFIG_EXPOLINE) &&
!nospec_disable && me->arch.plt_size) {
@ -527,14 +527,21 @@ int module_finalize(const Elf_Ehdr *hdr,
(str_has_prefix(secname, ".s390_return")))
nospec_revert(aseg, aseg + s->sh_size);
if (IS_ENABLED(CONFIG_STACKPROTECTOR) &&
(str_has_prefix(secname, "__stack_protector_loc"))) {
rc = stack_protector_apply(aseg, aseg + s->sh_size);
if (rc)
break;
}
#ifdef CONFIG_FUNCTION_TRACER
if (!strcmp(FTRACE_CALLSITE_SECTION, secname)) {
ret = module_alloc_ftrace_hotpatch_trampolines(me, s);
if (ret < 0)
return ret;
rc = module_alloc_ftrace_hotpatch_trampolines(me, s);
if (rc)
break;
}
#endif /* CONFIG_FUNCTION_TRACER */
}
return 0;
return rc;
}

View File

@ -184,7 +184,7 @@ static notrace void nmi_print_info(void)
sclp_emergency_printk(message);
}
static notrace void s390_handle_damage(void)
static notrace void __noreturn s390_handle_damage(void)
{
struct lowcore *lc = get_lowcore();
union ctlreg0 cr0, cr0_new;
@ -214,7 +214,6 @@ static notrace void s390_handle_damage(void)
lc->mcck_new_psw = psw_save;
local_ctl_load(0, &cr0.reg);
disabled_wait();
while (1);
}
NOKPROBE_SYMBOL(s390_handle_damage);

View File

@ -6,8 +6,7 @@
* Author(s): Michael Holzheu <holzheu@linux.vnet.ibm.com>
*/
#define KMSG_COMPONENT "os_info"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "os_info: " fmt
#include <linux/crash_dump.h>
#include <linux/kernel.h>

View File

@ -6,8 +6,7 @@
* Author(s): Hendrik Brueckner <brueckner@linux.ibm.com>
* Thomas Richter <tmricht@linux.ibm.com>
*/
#define KMSG_COMPONENT "cpum_cf"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "cpum_cf: " fmt
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
@ -1206,7 +1205,7 @@ static int __init cpumf_pmu_init(void)
}
/* Setup s390dbf facility */
cf_dbg = debug_register(KMSG_COMPONENT, 2, 1, 128);
cf_dbg = debug_register("cpum_cf", 2, 1, 128);
if (!cf_dbg) {
pr_err("Registration of s390dbf(cpum_cf) failed\n");
rc = -ENOMEM;
@ -1689,7 +1688,6 @@ static const struct file_operations cfset_fops = {
.open = cfset_open,
.release = cfset_release,
.unlocked_ioctl = cfset_ioctl,
.compat_ioctl = cfset_ioctl,
};
static struct miscdevice cfset_dev = {

View File

@ -5,8 +5,7 @@
* Copyright IBM Corp. 2013, 2018
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
*/
#define KMSG_COMPONENT "cpum_sf"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "cpum_sf: " fmt
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
@ -1093,7 +1092,7 @@ static void perf_event_count_update(struct perf_event *event, u64 count)
* combined-sampling data entry consists of a basic- and a diagnostic-sampling
* data entry. The sampling function is determined by the flags in the perf
* event hardware structure. The function always works with a combined-sampling
* data entry but ignores the the diagnostic portion if it is not available.
* data entry but ignores the diagnostic portion if it is not available.
*
* Note that the implementation focuses on basic-sampling data entries and, if
* such an entry is not valid, the entire combined-sampling data entry is
@ -2070,7 +2069,7 @@ static int __init init_cpum_sampling_pmu(void)
CPUMF_EVENT_PTR(SF, SF_CYCLES_BASIC_DIAG);
}
sfdbg = debug_register(KMSG_COMPONENT, 2, 1, 80);
sfdbg = debug_register("cpum_sf", 2, 1, 80);
if (!sfdbg) {
pr_err("Registering for s390dbf failed\n");
return -ENOMEM;

View File

@ -5,8 +5,7 @@
* Copyright IBM Corp. 2012, 2013
* Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
*/
#define KMSG_COMPONENT "perf"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "perf: " fmt
#include <linux/kernel.h>
#include <linux/perf_event.h>
@ -15,7 +14,6 @@
#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
#include <linux/sysfs.h>
#include <asm/stacktrace.h>
#include <asm/irq.h>

1230
arch/s390/kernel/perf_pai.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,843 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Performance event support - Processor Activity Instrumentation Facility
*
* Copyright IBM Corp. 2022
* Author(s): Thomas Richter <tmricht@linux.ibm.com>
*/
#define KMSG_COMPONENT "pai_crypto"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/percpu.h>
#include <linux/notifier.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/perf_event.h>
#include <asm/ctlreg.h>
#include <asm/pai.h>
#include <asm/debug.h>
static debug_info_t *cfm_dbg;
static unsigned int paicrypt_cnt; /* Size of the mapped counter sets */
/* extracted with QPACI instruction */
DEFINE_STATIC_KEY_FALSE(pai_key);
struct pai_userdata {
u16 num;
u64 value;
} __packed;
struct paicrypt_map {
unsigned long *page; /* Page for CPU to store counters */
struct pai_userdata *save; /* Page to store no-zero counters */
unsigned int active_events; /* # of PAI crypto users */
refcount_t refcnt; /* Reference count mapped buffers */
struct perf_event *event; /* Perf event for sampling */
struct list_head syswide_list; /* List system-wide sampling events */
};
struct paicrypt_mapptr {
struct paicrypt_map *mapptr;
};
static struct paicrypt_root { /* Anchor to per CPU data */
refcount_t refcnt; /* Overall active events */
struct paicrypt_mapptr __percpu *mapptr;
} paicrypt_root;
/* Free per CPU data when the last event is removed. */
static void paicrypt_root_free(void)
{
if (refcount_dec_and_test(&paicrypt_root.refcnt)) {
free_percpu(paicrypt_root.mapptr);
paicrypt_root.mapptr = NULL;
}
debug_sprintf_event(cfm_dbg, 5, "%s root.refcount %d\n", __func__,
refcount_read(&paicrypt_root.refcnt));
}
/*
* On initialization of first event also allocate per CPU data dynamically.
* Start with an array of pointers, the array size is the maximum number of
* CPUs possible, which might be larger than the number of CPUs currently
* online.
*/
static int paicrypt_root_alloc(void)
{
if (!refcount_inc_not_zero(&paicrypt_root.refcnt)) {
/* The memory is already zeroed. */
paicrypt_root.mapptr = alloc_percpu(struct paicrypt_mapptr);
if (!paicrypt_root.mapptr)
return -ENOMEM;
refcount_set(&paicrypt_root.refcnt, 1);
}
return 0;
}
/* Release the PMU if event is the last perf event */
static DEFINE_MUTEX(pai_reserve_mutex);
/* Free all memory allocated for event counting/sampling setup */
static void paicrypt_free(struct paicrypt_mapptr *mp)
{
free_page((unsigned long)mp->mapptr->page);
kvfree(mp->mapptr->save);
kfree(mp->mapptr);
mp->mapptr = NULL;
}
/* Adjust usage counters and remove allocated memory when all users are
* gone.
*/
static void paicrypt_event_destroy_cpu(struct perf_event *event, int cpu)
{
struct paicrypt_mapptr *mp = per_cpu_ptr(paicrypt_root.mapptr, cpu);
struct paicrypt_map *cpump = mp->mapptr;
mutex_lock(&pai_reserve_mutex);
debug_sprintf_event(cfm_dbg, 5, "%s event %#llx cpu %d users %d "
"refcnt %u\n", __func__, event->attr.config,
event->cpu, cpump->active_events,
refcount_read(&cpump->refcnt));
if (refcount_dec_and_test(&cpump->refcnt))
paicrypt_free(mp);
paicrypt_root_free();
mutex_unlock(&pai_reserve_mutex);
}
static void paicrypt_event_destroy(struct perf_event *event)
{
int cpu;
static_branch_dec(&pai_key);
free_page(PAI_SAVE_AREA(event));
if (event->cpu == -1) {
struct cpumask *mask = PAI_CPU_MASK(event);
for_each_cpu(cpu, mask)
paicrypt_event_destroy_cpu(event, cpu);
kfree(mask);
} else {
paicrypt_event_destroy_cpu(event, event->cpu);
}
}
static u64 paicrypt_getctr(unsigned long *page, int nr, bool kernel)
{
if (kernel)
nr += PAI_CRYPTO_MAXCTR;
return page[nr];
}
/* Read the counter values. Return value from location in CMP. For event
* CRYPTO_ALL sum up all events.
*/
static u64 paicrypt_getdata(struct perf_event *event, bool kernel)
{
struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
struct paicrypt_map *cpump = mp->mapptr;
u64 sum = 0;
int i;
if (event->attr.config != PAI_CRYPTO_BASE) {
return paicrypt_getctr(cpump->page,
event->attr.config - PAI_CRYPTO_BASE,
kernel);
}
for (i = 1; i <= paicrypt_cnt; i++) {
u64 val = paicrypt_getctr(cpump->page, i, kernel);
if (!val)
continue;
sum += val;
}
return sum;
}
static u64 paicrypt_getall(struct perf_event *event)
{
u64 sum = 0;
if (!event->attr.exclude_kernel)
sum += paicrypt_getdata(event, true);
if (!event->attr.exclude_user)
sum += paicrypt_getdata(event, false);
return sum;
}
/* Check concurrent access of counting and sampling for crypto events.
* This function is called in process context and it is save to block.
* When the event initialization functions fails, no other call back will
* be invoked.
*
* Allocate the memory for the event.
*/
static int paicrypt_alloc_cpu(struct perf_event *event, int cpu)
{
struct paicrypt_map *cpump = NULL;
struct paicrypt_mapptr *mp;
int rc;
mutex_lock(&pai_reserve_mutex);
/* Allocate root node */
rc = paicrypt_root_alloc();
if (rc)
goto unlock;
/* Allocate node for this event */
mp = per_cpu_ptr(paicrypt_root.mapptr, cpu);
cpump = mp->mapptr;
if (!cpump) { /* Paicrypt_map allocated? */
rc = -ENOMEM;
cpump = kzalloc(sizeof(*cpump), GFP_KERNEL);
if (!cpump)
goto undo;
/* Allocate memory for counter page and counter extraction.
* Only the first counting event has to allocate a page.
*/
mp->mapptr = cpump;
cpump->page = (unsigned long *)get_zeroed_page(GFP_KERNEL);
cpump->save = kvmalloc_array(paicrypt_cnt + 1,
sizeof(struct pai_userdata),
GFP_KERNEL);
if (!cpump->page || !cpump->save) {
paicrypt_free(mp);
goto undo;
}
INIT_LIST_HEAD(&cpump->syswide_list);
refcount_set(&cpump->refcnt, 1);
rc = 0;
} else {
refcount_inc(&cpump->refcnt);
}
undo:
if (rc) {
/* Error in allocation of event, decrement anchor. Since
* the event in not created, its destroy() function is never
* invoked. Adjust the reference counter for the anchor.
*/
paicrypt_root_free();
}
unlock:
mutex_unlock(&pai_reserve_mutex);
return rc;
}
static int paicrypt_alloc(struct perf_event *event)
{
struct cpumask *maskptr;
int cpu, rc = -ENOMEM;
maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL);
if (!maskptr)
goto out;
for_each_online_cpu(cpu) {
rc = paicrypt_alloc_cpu(event, cpu);
if (rc) {
for_each_cpu(cpu, maskptr)
paicrypt_event_destroy_cpu(event, cpu);
kfree(maskptr);
goto out;
}
cpumask_set_cpu(cpu, maskptr);
}
/*
* On error all cpumask are freed and all events have been destroyed.
* Save of which CPUs data structures have been allocated for.
* Release them in paicrypt_event_destroy call back function
* for this event.
*/
PAI_CPU_MASK(event) = maskptr;
rc = 0;
out:
return rc;
}
/* Might be called on different CPU than the one the event is intended for. */
static int paicrypt_event_init(struct perf_event *event)
{
struct perf_event_attr *a = &event->attr;
int rc = 0;
/* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */
if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type)
return -ENOENT;
/* PAI crypto event must be in valid range, try others if not */
if (a->config < PAI_CRYPTO_BASE ||
a->config > PAI_CRYPTO_BASE + paicrypt_cnt)
return -ENOENT;
/* Allow only CRYPTO_ALL for sampling */
if (a->sample_period && a->config != PAI_CRYPTO_BASE)
return -EINVAL;
/* Get a page to store last counter values for sampling */
if (a->sample_period) {
PAI_SAVE_AREA(event) = get_zeroed_page(GFP_KERNEL);
if (!PAI_SAVE_AREA(event)) {
rc = -ENOMEM;
goto out;
}
}
if (event->cpu >= 0)
rc = paicrypt_alloc_cpu(event, event->cpu);
else
rc = paicrypt_alloc(event);
if (rc) {
free_page(PAI_SAVE_AREA(event));
goto out;
}
event->destroy = paicrypt_event_destroy;
if (a->sample_period) {
a->sample_period = 1;
a->freq = 0;
/* Register for paicrypt_sched_task() to be called */
event->attach_state |= PERF_ATTACH_SCHED_CB;
/* Add raw data which contain the memory mapped counters */
a->sample_type |= PERF_SAMPLE_RAW;
/* Turn off inheritance */
a->inherit = 0;
}
static_branch_inc(&pai_key);
out:
return rc;
}
static void paicrypt_read(struct perf_event *event)
{
u64 prev, new, delta;
prev = local64_read(&event->hw.prev_count);
new = paicrypt_getall(event);
local64_set(&event->hw.prev_count, new);
delta = (prev <= new) ? new - prev
: (-1ULL - prev) + new + 1; /* overflow */
local64_add(delta, &event->count);
}
static void paicrypt_start(struct perf_event *event, int flags)
{
struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
struct paicrypt_map *cpump = mp->mapptr;
u64 sum;
if (!event->attr.sample_period) { /* Counting */
sum = paicrypt_getall(event); /* Get current value */
local64_set(&event->hw.prev_count, sum);
} else { /* Sampling */
memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE);
/* Enable context switch callback for system-wide sampling */
if (!(event->attach_state & PERF_ATTACH_TASK)) {
list_add_tail(PAI_SWLIST(event), &cpump->syswide_list);
perf_sched_cb_inc(event->pmu);
} else {
cpump->event = event;
}
}
}
static int paicrypt_add(struct perf_event *event, int flags)
{
struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
struct paicrypt_map *cpump = mp->mapptr;
unsigned long ccd;
if (++cpump->active_events == 1) {
ccd = virt_to_phys(cpump->page) | PAI_CRYPTO_KERNEL_OFFSET;
WRITE_ONCE(get_lowcore()->ccd, ccd);
local_ctl_set_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT);
}
if (flags & PERF_EF_START)
paicrypt_start(event, PERF_EF_RELOAD);
event->hw.state = 0;
return 0;
}
static void paicrypt_have_sample(struct perf_event *, struct paicrypt_map *);
static void paicrypt_stop(struct perf_event *event, int flags)
{
struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
struct paicrypt_map *cpump = mp->mapptr;
if (!event->attr.sample_period) { /* Counting */
paicrypt_read(event);
} else { /* Sampling */
if (!(event->attach_state & PERF_ATTACH_TASK)) {
perf_sched_cb_dec(event->pmu);
list_del(PAI_SWLIST(event));
} else {
paicrypt_have_sample(event, cpump);
cpump->event = NULL;
}
}
event->hw.state = PERF_HES_STOPPED;
}
static void paicrypt_del(struct perf_event *event, int flags)
{
struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
struct paicrypt_map *cpump = mp->mapptr;
paicrypt_stop(event, PERF_EF_UPDATE);
if (--cpump->active_events == 0) {
local_ctl_clear_bit(0, CR0_CRYPTOGRAPHY_COUNTER_BIT);
WRITE_ONCE(get_lowcore()->ccd, 0);
}
}
/* Create raw data and save it in buffer. Calculate the delta for each
* counter between this invocation and the last invocation.
* Returns number of bytes copied.
* Saves only entries with positive counter difference of the form
* 2 bytes: Number of counter
* 8 bytes: Value of counter
*/
static size_t paicrypt_copy(struct pai_userdata *userdata, unsigned long *page,
unsigned long *page_old, bool exclude_user,
bool exclude_kernel)
{
int i, outidx = 0;
for (i = 1; i <= paicrypt_cnt; i++) {
u64 val = 0, val_old = 0;
if (!exclude_kernel) {
val += paicrypt_getctr(page, i, true);
val_old += paicrypt_getctr(page_old, i, true);
}
if (!exclude_user) {
val += paicrypt_getctr(page, i, false);
val_old += paicrypt_getctr(page_old, i, false);
}
if (val >= val_old)
val -= val_old;
else
val = (~0ULL - val_old) + val + 1;
if (val) {
userdata[outidx].num = i;
userdata[outidx].value = val;
outidx++;
}
}
return outidx * sizeof(struct pai_userdata);
}
static int paicrypt_push_sample(size_t rawsize, struct paicrypt_map *cpump,
struct perf_event *event)
{
struct perf_sample_data data;
struct perf_raw_record raw;
struct pt_regs regs;
int overflow;
/* Setup perf sample */
memset(&regs, 0, sizeof(regs));
memset(&raw, 0, sizeof(raw));
memset(&data, 0, sizeof(data));
perf_sample_data_init(&data, 0, event->hw.last_period);
if (event->attr.sample_type & PERF_SAMPLE_TID) {
data.tid_entry.pid = task_tgid_nr(current);
data.tid_entry.tid = task_pid_nr(current);
}
if (event->attr.sample_type & PERF_SAMPLE_TIME)
data.time = event->clock();
if (event->attr.sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER))
data.id = event->id;
if (event->attr.sample_type & PERF_SAMPLE_CPU) {
data.cpu_entry.cpu = smp_processor_id();
data.cpu_entry.reserved = 0;
}
if (event->attr.sample_type & PERF_SAMPLE_RAW) {
raw.frag.size = rawsize;
raw.frag.data = cpump->save;
perf_sample_save_raw_data(&data, event, &raw);
}
overflow = perf_event_overflow(event, &data, &regs);
perf_event_update_userpage(event);
/* Save crypto counter lowcore page after reading event data. */
memcpy((void *)PAI_SAVE_AREA(event), cpump->page, PAGE_SIZE);
return overflow;
}
/* Check if there is data to be saved on schedule out of a task. */
static void paicrypt_have_sample(struct perf_event *event,
struct paicrypt_map *cpump)
{
size_t rawsize;
if (!event) /* No event active */
return;
rawsize = paicrypt_copy(cpump->save, cpump->page,
(unsigned long *)PAI_SAVE_AREA(event),
event->attr.exclude_user,
event->attr.exclude_kernel);
if (rawsize) /* No incremented counters */
paicrypt_push_sample(rawsize, cpump, event);
}
/* Check if there is data to be saved on schedule out of a task. */
static void paicrypt_have_samples(void)
{
struct paicrypt_mapptr *mp = this_cpu_ptr(paicrypt_root.mapptr);
struct paicrypt_map *cpump = mp->mapptr;
struct perf_event *event;
list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
paicrypt_have_sample(event, cpump);
}
/* Called on schedule-in and schedule-out. No access to event structure,
* but for sampling only event CRYPTO_ALL is allowed.
*/
static void paicrypt_sched_task(struct perf_event_pmu_context *pmu_ctx,
struct task_struct *task, bool sched_in)
{
/* We started with a clean page on event installation. So read out
* results on schedule_out and if page was dirty, save old values.
*/
if (!sched_in)
paicrypt_have_samples();
}
/* Attribute definitions for paicrypt interface. As with other CPU
* Measurement Facilities, there is one attribute per mapped counter.
* The number of mapped counters may vary per machine generation. Use
* the QUERY PROCESSOR ACTIVITY COUNTER INFORMATION (QPACI) instruction
* to determine the number of mapped counters. The instructions returns
* a positive number, which is the highest number of supported counters.
* All counters less than this number are also supported, there are no
* holes. A returned number of zero means no support for mapped counters.
*
* The identification of the counter is a unique number. The chosen range
* is 0x1000 + offset in mapped kernel page.
* All CPU Measurement Facility counters identifiers must be unique and
* the numbers from 0 to 496 are already used for the CPU Measurement
* Counter facility. Numbers 0xb0000, 0xbc000 and 0xbd000 are already
* used for the CPU Measurement Sampling facility.
*/
PMU_FORMAT_ATTR(event, "config:0-63");
static struct attribute *paicrypt_format_attr[] = {
&format_attr_event.attr,
NULL,
};
static struct attribute_group paicrypt_events_group = {
.name = "events",
.attrs = NULL /* Filled in attr_event_init() */
};
static struct attribute_group paicrypt_format_group = {
.name = "format",
.attrs = paicrypt_format_attr,
};
static const struct attribute_group *paicrypt_attr_groups[] = {
&paicrypt_events_group,
&paicrypt_format_group,
NULL,
};
/* Performance monitoring unit for mapped counters */
static struct pmu paicrypt = {
.task_ctx_nr = perf_hw_context,
.event_init = paicrypt_event_init,
.add = paicrypt_add,
.del = paicrypt_del,
.start = paicrypt_start,
.stop = paicrypt_stop,
.read = paicrypt_read,
.sched_task = paicrypt_sched_task,
.attr_groups = paicrypt_attr_groups
};
/* List of symbolic PAI counter names. */
static const char * const paicrypt_ctrnames[] = {
[0] = "CRYPTO_ALL",
[1] = "KM_DEA",
[2] = "KM_TDEA_128",
[3] = "KM_TDEA_192",
[4] = "KM_ENCRYPTED_DEA",
[5] = "KM_ENCRYPTED_TDEA_128",
[6] = "KM_ENCRYPTED_TDEA_192",
[7] = "KM_AES_128",
[8] = "KM_AES_192",
[9] = "KM_AES_256",
[10] = "KM_ENCRYPTED_AES_128",
[11] = "KM_ENCRYPTED_AES_192",
[12] = "KM_ENCRYPTED_AES_256",
[13] = "KM_XTS_AES_128",
[14] = "KM_XTS_AES_256",
[15] = "KM_XTS_ENCRYPTED_AES_128",
[16] = "KM_XTS_ENCRYPTED_AES_256",
[17] = "KMC_DEA",
[18] = "KMC_TDEA_128",
[19] = "KMC_TDEA_192",
[20] = "KMC_ENCRYPTED_DEA",
[21] = "KMC_ENCRYPTED_TDEA_128",
[22] = "KMC_ENCRYPTED_TDEA_192",
[23] = "KMC_AES_128",
[24] = "KMC_AES_192",
[25] = "KMC_AES_256",
[26] = "KMC_ENCRYPTED_AES_128",
[27] = "KMC_ENCRYPTED_AES_192",
[28] = "KMC_ENCRYPTED_AES_256",
[29] = "KMC_PRNG",
[30] = "KMA_GCM_AES_128",
[31] = "KMA_GCM_AES_192",
[32] = "KMA_GCM_AES_256",
[33] = "KMA_GCM_ENCRYPTED_AES_128",
[34] = "KMA_GCM_ENCRYPTED_AES_192",
[35] = "KMA_GCM_ENCRYPTED_AES_256",
[36] = "KMF_DEA",
[37] = "KMF_TDEA_128",
[38] = "KMF_TDEA_192",
[39] = "KMF_ENCRYPTED_DEA",
[40] = "KMF_ENCRYPTED_TDEA_128",
[41] = "KMF_ENCRYPTED_TDEA_192",
[42] = "KMF_AES_128",
[43] = "KMF_AES_192",
[44] = "KMF_AES_256",
[45] = "KMF_ENCRYPTED_AES_128",
[46] = "KMF_ENCRYPTED_AES_192",
[47] = "KMF_ENCRYPTED_AES_256",
[48] = "KMCTR_DEA",
[49] = "KMCTR_TDEA_128",
[50] = "KMCTR_TDEA_192",
[51] = "KMCTR_ENCRYPTED_DEA",
[52] = "KMCTR_ENCRYPTED_TDEA_128",
[53] = "KMCTR_ENCRYPTED_TDEA_192",
[54] = "KMCTR_AES_128",
[55] = "KMCTR_AES_192",
[56] = "KMCTR_AES_256",
[57] = "KMCTR_ENCRYPTED_AES_128",
[58] = "KMCTR_ENCRYPTED_AES_192",
[59] = "KMCTR_ENCRYPTED_AES_256",
[60] = "KMO_DEA",
[61] = "KMO_TDEA_128",
[62] = "KMO_TDEA_192",
[63] = "KMO_ENCRYPTED_DEA",
[64] = "KMO_ENCRYPTED_TDEA_128",
[65] = "KMO_ENCRYPTED_TDEA_192",
[66] = "KMO_AES_128",
[67] = "KMO_AES_192",
[68] = "KMO_AES_256",
[69] = "KMO_ENCRYPTED_AES_128",
[70] = "KMO_ENCRYPTED_AES_192",
[71] = "KMO_ENCRYPTED_AES_256",
[72] = "KIMD_SHA_1",
[73] = "KIMD_SHA_256",
[74] = "KIMD_SHA_512",
[75] = "KIMD_SHA3_224",
[76] = "KIMD_SHA3_256",
[77] = "KIMD_SHA3_384",
[78] = "KIMD_SHA3_512",
[79] = "KIMD_SHAKE_128",
[80] = "KIMD_SHAKE_256",
[81] = "KIMD_GHASH",
[82] = "KLMD_SHA_1",
[83] = "KLMD_SHA_256",
[84] = "KLMD_SHA_512",
[85] = "KLMD_SHA3_224",
[86] = "KLMD_SHA3_256",
[87] = "KLMD_SHA3_384",
[88] = "KLMD_SHA3_512",
[89] = "KLMD_SHAKE_128",
[90] = "KLMD_SHAKE_256",
[91] = "KMAC_DEA",
[92] = "KMAC_TDEA_128",
[93] = "KMAC_TDEA_192",
[94] = "KMAC_ENCRYPTED_DEA",
[95] = "KMAC_ENCRYPTED_TDEA_128",
[96] = "KMAC_ENCRYPTED_TDEA_192",
[97] = "KMAC_AES_128",
[98] = "KMAC_AES_192",
[99] = "KMAC_AES_256",
[100] = "KMAC_ENCRYPTED_AES_128",
[101] = "KMAC_ENCRYPTED_AES_192",
[102] = "KMAC_ENCRYPTED_AES_256",
[103] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_DEA",
[104] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_128",
[105] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_TDEA_192",
[106] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_DEA",
[107] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_128",
[108] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_TDEA_192",
[109] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_128",
[110] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_192",
[111] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_AES_256",
[112] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_128",
[113] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_192",
[114] = "PCC_COMPUTE_LAST_BLOCK_CMAC_USING_ENCRYPTED_AES_256",
[115] = "PCC_COMPUTE_XTS_PARAMETER_USING_AES_128",
[116] = "PCC_COMPUTE_XTS_PARAMETER_USING_AES_256",
[117] = "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_128",
[118] = "PCC_COMPUTE_XTS_PARAMETER_USING_ENCRYPTED_AES_256",
[119] = "PCC_SCALAR_MULTIPLY_P256",
[120] = "PCC_SCALAR_MULTIPLY_P384",
[121] = "PCC_SCALAR_MULTIPLY_P521",
[122] = "PCC_SCALAR_MULTIPLY_ED25519",
[123] = "PCC_SCALAR_MULTIPLY_ED448",
[124] = "PCC_SCALAR_MULTIPLY_X25519",
[125] = "PCC_SCALAR_MULTIPLY_X448",
[126] = "PRNO_SHA_512_DRNG",
[127] = "PRNO_TRNG_QUERY_RAW_TO_CONDITIONED_RATIO",
[128] = "PRNO_TRNG",
[129] = "KDSA_ECDSA_VERIFY_P256",
[130] = "KDSA_ECDSA_VERIFY_P384",
[131] = "KDSA_ECDSA_VERIFY_P521",
[132] = "KDSA_ECDSA_SIGN_P256",
[133] = "KDSA_ECDSA_SIGN_P384",
[134] = "KDSA_ECDSA_SIGN_P521",
[135] = "KDSA_ENCRYPTED_ECDSA_SIGN_P256",
[136] = "KDSA_ENCRYPTED_ECDSA_SIGN_P384",
[137] = "KDSA_ENCRYPTED_ECDSA_SIGN_P521",
[138] = "KDSA_EDDSA_VERIFY_ED25519",
[139] = "KDSA_EDDSA_VERIFY_ED448",
[140] = "KDSA_EDDSA_SIGN_ED25519",
[141] = "KDSA_EDDSA_SIGN_ED448",
[142] = "KDSA_ENCRYPTED_EDDSA_SIGN_ED25519",
[143] = "KDSA_ENCRYPTED_EDDSA_SIGN_ED448",
[144] = "PCKMO_ENCRYPT_DEA_KEY",
[145] = "PCKMO_ENCRYPT_TDEA_128_KEY",
[146] = "PCKMO_ENCRYPT_TDEA_192_KEY",
[147] = "PCKMO_ENCRYPT_AES_128_KEY",
[148] = "PCKMO_ENCRYPT_AES_192_KEY",
[149] = "PCKMO_ENCRYPT_AES_256_KEY",
[150] = "PCKMO_ENCRYPT_ECC_P256_KEY",
[151] = "PCKMO_ENCRYPT_ECC_P384_KEY",
[152] = "PCKMO_ENCRYPT_ECC_P521_KEY",
[153] = "PCKMO_ENCRYPT_ECC_ED25519_KEY",
[154] = "PCKMO_ENCRYPT_ECC_ED448_KEY",
[155] = "IBM_RESERVED_155",
[156] = "IBM_RESERVED_156",
[157] = "KM_FULL_XTS_AES_128",
[158] = "KM_FULL_XTS_AES_256",
[159] = "KM_FULL_XTS_ENCRYPTED_AES_128",
[160] = "KM_FULL_XTS_ENCRYPTED_AES_256",
[161] = "KMAC_HMAC_SHA_224",
[162] = "KMAC_HMAC_SHA_256",
[163] = "KMAC_HMAC_SHA_384",
[164] = "KMAC_HMAC_SHA_512",
[165] = "KMAC_HMAC_ENCRYPTED_SHA_224",
[166] = "KMAC_HMAC_ENCRYPTED_SHA_256",
[167] = "KMAC_HMAC_ENCRYPTED_SHA_384",
[168] = "KMAC_HMAC_ENCRYPTED_SHA_512",
[169] = "PCKMO_ENCRYPT_HMAC_512_KEY",
[170] = "PCKMO_ENCRYPT_HMAC_1024_KEY",
[171] = "PCKMO_ENCRYPT_AES_XTS_128",
[172] = "PCKMO_ENCRYPT_AES_XTS_256",
};
static void __init attr_event_free(struct attribute **attrs, int num)
{
struct perf_pmu_events_attr *pa;
int i;
for (i = 0; i < num; i++) {
struct device_attribute *dap;
dap = container_of(attrs[i], struct device_attribute, attr);
pa = container_of(dap, struct perf_pmu_events_attr, attr);
kfree(pa);
}
kfree(attrs);
}
static int __init attr_event_init_one(struct attribute **attrs, int num)
{
struct perf_pmu_events_attr *pa;
/* Index larger than array_size, no counter name available */
if (num >= ARRAY_SIZE(paicrypt_ctrnames)) {
attrs[num] = NULL;
return 0;
}
pa = kzalloc(sizeof(*pa), GFP_KERNEL);
if (!pa)
return -ENOMEM;
sysfs_attr_init(&pa->attr.attr);
pa->id = PAI_CRYPTO_BASE + num;
pa->attr.attr.name = paicrypt_ctrnames[num];
pa->attr.attr.mode = 0444;
pa->attr.show = cpumf_events_sysfs_show;
pa->attr.store = NULL;
attrs[num] = &pa->attr.attr;
return 0;
}
/* Create PMU sysfs event attributes on the fly. */
static int __init attr_event_init(void)
{
struct attribute **attrs;
int ret, i;
attrs = kmalloc_array(paicrypt_cnt + 2, sizeof(*attrs), GFP_KERNEL);
if (!attrs)
return -ENOMEM;
for (i = 0; i <= paicrypt_cnt; i++) {
ret = attr_event_init_one(attrs, i);
if (ret) {
attr_event_free(attrs, i);
return ret;
}
}
attrs[i] = NULL;
paicrypt_events_group.attrs = attrs;
return 0;
}
static int __init paicrypt_init(void)
{
struct qpaci_info_block ib;
int rc;
if (!test_facility(196))
return 0;
qpaci(&ib);
paicrypt_cnt = ib.num_cc;
if (paicrypt_cnt == 0)
return 0;
if (paicrypt_cnt >= PAI_CRYPTO_MAXCTR) {
pr_err("Too many PMU pai_crypto counters %d\n", paicrypt_cnt);
return -E2BIG;
}
rc = attr_event_init(); /* Export known PAI crypto events */
if (rc) {
pr_err("Creation of PMU pai_crypto /sysfs failed\n");
return rc;
}
/* Setup s390dbf facility */
cfm_dbg = debug_register(KMSG_COMPONENT, 2, 256, 128);
if (!cfm_dbg) {
pr_err("Registration of s390dbf pai_crypto failed\n");
return -ENOMEM;
}
debug_register_view(cfm_dbg, &debug_sprintf_view);
rc = perf_pmu_register(&paicrypt, "pai_crypto", -1);
if (rc) {
pr_err("Registering the pai_crypto PMU failed with rc=%i\n",
rc);
debug_unregister_view(cfm_dbg, &debug_sprintf_view);
debug_unregister(cfm_dbg);
return rc;
}
return 0;
}
device_initcall(paicrypt_init);

View File

@ -1,756 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Performance event support - Processor Activity Instrumentation Extension
* Facility
*
* Copyright IBM Corp. 2022
* Author(s): Thomas Richter <tmricht@linux.ibm.com>
*/
#define KMSG_COMPONENT "pai_ext"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#include <linux/kernel.h>
#include <linux/kernel_stat.h>
#include <linux/percpu.h>
#include <linux/notifier.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/perf_event.h>
#include <asm/ctlreg.h>
#include <asm/pai.h>
#include <asm/debug.h>
#define PAIE1_CB_SZ 0x200 /* Size of PAIE1 control block */
#define PAIE1_CTRBLOCK_SZ 0x400 /* Size of PAIE1 counter blocks */
static debug_info_t *paiext_dbg;
static unsigned int paiext_cnt; /* Extracted with QPACI instruction */
struct pai_userdata {
u16 num;
u64 value;
} __packed;
/* Create the PAI extension 1 control block area.
* The PAI extension control block 1 is pointed to by lowcore
* address 0x1508 for each CPU. This control block is 512 bytes in size
* and requires a 512 byte boundary alignment.
*/
struct paiext_cb { /* PAI extension 1 control block */
u64 header; /* Not used */
u64 reserved1;
u64 acc; /* Addr to analytics counter control block */
u8 reserved2[488];
} __packed;
struct paiext_map {
unsigned long *area; /* Area for CPU to store counters */
struct pai_userdata *save; /* Area to store non-zero counters */
unsigned int active_events; /* # of PAI Extension users */
refcount_t refcnt;
struct perf_event *event; /* Perf event for sampling */
struct paiext_cb *paiext_cb; /* PAI extension control block area */
struct list_head syswide_list; /* List system-wide sampling events */
};
struct paiext_mapptr {
struct paiext_map *mapptr;
};
static struct paiext_root { /* Anchor to per CPU data */
refcount_t refcnt; /* Overall active events */
struct paiext_mapptr __percpu *mapptr;
} paiext_root;
/* Free per CPU data when the last event is removed. */
static void paiext_root_free(void)
{
if (refcount_dec_and_test(&paiext_root.refcnt)) {
free_percpu(paiext_root.mapptr);
paiext_root.mapptr = NULL;
}
debug_sprintf_event(paiext_dbg, 5, "%s root.refcount %d\n", __func__,
refcount_read(&paiext_root.refcnt));
}
/* On initialization of first event also allocate per CPU data dynamically.
* Start with an array of pointers, the array size is the maximum number of
* CPUs possible, which might be larger than the number of CPUs currently
* online.
*/
static int paiext_root_alloc(void)
{
if (!refcount_inc_not_zero(&paiext_root.refcnt)) {
/* The memory is already zeroed. */
paiext_root.mapptr = alloc_percpu(struct paiext_mapptr);
if (!paiext_root.mapptr) {
/* Returning without refcnt adjustment is ok. The
* error code is handled by paiext_alloc() which
* decrements refcnt when an event can not be
* created.
*/
return -ENOMEM;
}
refcount_set(&paiext_root.refcnt, 1);
}
return 0;
}
/* Protects against concurrent increment of sampler and counter member
* increments at the same time and prohibits concurrent execution of
* counting and sampling events.
* Ensures that analytics counter block is deallocated only when the
* sampling and counting on that cpu is zero.
* For details see paiext_alloc().
*/
static DEFINE_MUTEX(paiext_reserve_mutex);
/* Free all memory allocated for event counting/sampling setup */
static void paiext_free(struct paiext_mapptr *mp)
{
kfree(mp->mapptr->area);
kfree(mp->mapptr->paiext_cb);
kvfree(mp->mapptr->save);
kfree(mp->mapptr);
mp->mapptr = NULL;
}
/* Release the PMU if event is the last perf event */
static void paiext_event_destroy_cpu(struct perf_event *event, int cpu)
{
struct paiext_mapptr *mp = per_cpu_ptr(paiext_root.mapptr, cpu);
struct paiext_map *cpump = mp->mapptr;
mutex_lock(&paiext_reserve_mutex);
if (refcount_dec_and_test(&cpump->refcnt)) /* Last reference gone */
paiext_free(mp);
paiext_root_free();
mutex_unlock(&paiext_reserve_mutex);
}
static void paiext_event_destroy(struct perf_event *event)
{
int cpu;
free_page(PAI_SAVE_AREA(event));
if (event->cpu == -1) {
struct cpumask *mask = PAI_CPU_MASK(event);
for_each_cpu(cpu, mask)
paiext_event_destroy_cpu(event, cpu);
kfree(mask);
} else {
paiext_event_destroy_cpu(event, event->cpu);
}
debug_sprintf_event(paiext_dbg, 4, "%s cpu %d\n", __func__,
event->cpu);
}
/* Used to avoid races in checking concurrent access of counting and
* sampling for pai_extension events.
*
* Only one instance of event pai_ext/NNPA_ALL/ for sampling is
* allowed and when this event is running, no counting event is allowed.
* Several counting events are allowed in parallel, but no sampling event
* is allowed while one (or more) counting events are running.
*
* This function is called in process context and it is safe to block.
* When the event initialization functions fails, no other call back will
* be invoked.
*
* Allocate the memory for the event.
*/
static int paiext_alloc_cpu(struct perf_event *event, int cpu)
{
struct paiext_mapptr *mp;
struct paiext_map *cpump;
int rc;
mutex_lock(&paiext_reserve_mutex);
rc = paiext_root_alloc();
if (rc)
goto unlock;
mp = per_cpu_ptr(paiext_root.mapptr, cpu);
cpump = mp->mapptr;
if (!cpump) { /* Paiext_map allocated? */
rc = -ENOMEM;
cpump = kzalloc(sizeof(*cpump), GFP_KERNEL);
if (!cpump)
goto undo;
/* Allocate memory for counter area and counter extraction.
* These are
* - a 512 byte block and requires 512 byte boundary alignment.
* - a 1KB byte block and requires 1KB boundary alignment.
* Only the first counting event has to allocate the area.
*
* Note: This works with commit 59bb47985c1d by default.
* Backporting this to kernels without this commit might
* need adjustment.
*/
mp->mapptr = cpump;
cpump->area = kzalloc(PAIE1_CTRBLOCK_SZ, GFP_KERNEL);
cpump->paiext_cb = kzalloc(PAIE1_CB_SZ, GFP_KERNEL);
cpump->save = kvmalloc_array(paiext_cnt + 1,
sizeof(struct pai_userdata),
GFP_KERNEL);
if (!cpump->save || !cpump->area || !cpump->paiext_cb) {
paiext_free(mp);
goto undo;
}
INIT_LIST_HEAD(&cpump->syswide_list);
refcount_set(&cpump->refcnt, 1);
rc = 0;
} else {
refcount_inc(&cpump->refcnt);
}
undo:
if (rc) {
/* Error in allocation of event, decrement anchor. Since
* the event in not created, its destroy() function is never
* invoked. Adjust the reference counter for the anchor.
*/
paiext_root_free();
}
unlock:
mutex_unlock(&paiext_reserve_mutex);
/* If rc is non-zero, no increment of counter/sampler was done. */
return rc;
}
static int paiext_alloc(struct perf_event *event)
{
struct cpumask *maskptr;
int cpu, rc = -ENOMEM;
maskptr = kzalloc(sizeof(*maskptr), GFP_KERNEL);
if (!maskptr)
goto out;
for_each_online_cpu(cpu) {
rc = paiext_alloc_cpu(event, cpu);
if (rc) {
for_each_cpu(cpu, maskptr)
paiext_event_destroy_cpu(event, cpu);
kfree(maskptr);
goto out;
}
cpumask_set_cpu(cpu, maskptr);
}
/*
* On error all cpumask are freed and all events have been destroyed.
* Save of which CPUs data structures have been allocated for.
* Release them in paicrypt_event_destroy call back function
* for this event.
*/
PAI_CPU_MASK(event) = maskptr;
rc = 0;
out:
return rc;
}
/* The PAI extension 1 control block supports up to 128 entries. Return
* the index within PAIE1_CB given the event number. Also validate event
* number.
*/
static int paiext_event_valid(struct perf_event *event)
{
u64 cfg = event->attr.config;
if (cfg >= PAI_NNPA_BASE && cfg <= PAI_NNPA_BASE + paiext_cnt) {
/* Offset NNPA in paiext_cb */
event->hw.config_base = offsetof(struct paiext_cb, acc);
return 0;
}
return -ENOENT;
}
/* Might be called on different CPU than the one the event is intended for. */
static int paiext_event_init(struct perf_event *event)
{
struct perf_event_attr *a = &event->attr;
int rc;
/* PMU pai_ext registered as PERF_TYPE_RAW, check event type */
if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type)
return -ENOENT;
/* PAI extension event must be valid and in supported range */
rc = paiext_event_valid(event);
if (rc)
return rc;
/* Allow only event NNPA_ALL for sampling. */
if (a->sample_period && a->config != PAI_NNPA_BASE)
return -EINVAL;
/* Prohibit exclude_user event selection */
if (a->exclude_user)
return -EINVAL;
/* Get a page to store last counter values for sampling */
if (a->sample_period) {
PAI_SAVE_AREA(event) = get_zeroed_page(GFP_KERNEL);
if (!PAI_SAVE_AREA(event))
return -ENOMEM;
}
if (event->cpu >= 0)
rc = paiext_alloc_cpu(event, event->cpu);
else
rc = paiext_alloc(event);
if (rc) {
free_page(PAI_SAVE_AREA(event));
return rc;
}
event->destroy = paiext_event_destroy;
if (a->sample_period) {
a->sample_period = 1;
a->freq = 0;
/* Register for paicrypt_sched_task() to be called */
event->attach_state |= PERF_ATTACH_SCHED_CB;
/* Add raw data which are the memory mapped counters */
a->sample_type |= PERF_SAMPLE_RAW;
/* Turn off inheritance */
a->inherit = 0;
}
return 0;
}
static u64 paiext_getctr(unsigned long *area, int nr)
{
return area[nr];
}
/* Read the counter values. Return value from location in buffer. For event
* NNPA_ALL sum up all events.
*/
static u64 paiext_getdata(struct perf_event *event)
{
struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
struct paiext_map *cpump = mp->mapptr;
u64 sum = 0;
int i;
if (event->attr.config != PAI_NNPA_BASE)
return paiext_getctr(cpump->area,
event->attr.config - PAI_NNPA_BASE);
for (i = 1; i <= paiext_cnt; i++)
sum += paiext_getctr(cpump->area, i);
return sum;
}
static u64 paiext_getall(struct perf_event *event)
{
return paiext_getdata(event);
}
static void paiext_read(struct perf_event *event)
{
u64 prev, new, delta;
prev = local64_read(&event->hw.prev_count);
new = paiext_getall(event);
local64_set(&event->hw.prev_count, new);
delta = new - prev;
local64_add(delta, &event->count);
}
static void paiext_start(struct perf_event *event, int flags)
{
struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
struct paiext_map *cpump = mp->mapptr;
u64 sum;
if (!event->attr.sample_period) { /* Counting */
sum = paiext_getall(event); /* Get current value */
local64_set(&event->hw.prev_count, sum);
} else { /* Sampling */
memcpy((void *)PAI_SAVE_AREA(event), cpump->area,
PAIE1_CTRBLOCK_SZ);
/* Enable context switch callback for system-wide sampling */
if (!(event->attach_state & PERF_ATTACH_TASK)) {
list_add_tail(PAI_SWLIST(event), &cpump->syswide_list);
perf_sched_cb_inc(event->pmu);
} else {
cpump->event = event;
}
}
}
static int paiext_add(struct perf_event *event, int flags)
{
struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
struct paiext_map *cpump = mp->mapptr;
struct paiext_cb *pcb = cpump->paiext_cb;
if (++cpump->active_events == 1) {
get_lowcore()->aicd = virt_to_phys(cpump->paiext_cb);
pcb->acc = virt_to_phys(cpump->area) | 0x1;
/* Enable CPU instruction lookup for PAIE1 control block */
local_ctl_set_bit(0, CR0_PAI_EXTENSION_BIT);
}
if (flags & PERF_EF_START)
paiext_start(event, PERF_EF_RELOAD);
event->hw.state = 0;
return 0;
}
static void paiext_have_sample(struct perf_event *, struct paiext_map *);
static void paiext_stop(struct perf_event *event, int flags)
{
struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
struct paiext_map *cpump = mp->mapptr;
if (!event->attr.sample_period) { /* Counting */
paiext_read(event);
} else { /* Sampling */
if (!(event->attach_state & PERF_ATTACH_TASK)) {
list_del(PAI_SWLIST(event));
perf_sched_cb_dec(event->pmu);
} else {
paiext_have_sample(event, cpump);
cpump->event = NULL;
}
}
event->hw.state = PERF_HES_STOPPED;
}
static void paiext_del(struct perf_event *event, int flags)
{
struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
struct paiext_map *cpump = mp->mapptr;
struct paiext_cb *pcb = cpump->paiext_cb;
paiext_stop(event, PERF_EF_UPDATE);
if (--cpump->active_events == 0) {
/* Disable CPU instruction lookup for PAIE1 control block */
local_ctl_clear_bit(0, CR0_PAI_EXTENSION_BIT);
pcb->acc = 0;
get_lowcore()->aicd = 0;
}
}
/* Create raw data and save it in buffer. Returns number of bytes copied.
* Saves only positive counter entries of the form
* 2 bytes: Number of counter
* 8 bytes: Value of counter
*/
static size_t paiext_copy(struct pai_userdata *userdata, unsigned long *area,
unsigned long *area_old)
{
int i, outidx = 0;
for (i = 1; i <= paiext_cnt; i++) {
u64 val = paiext_getctr(area, i);
u64 val_old = paiext_getctr(area_old, i);
if (val >= val_old)
val -= val_old;
else
val = (~0ULL - val_old) + val + 1;
if (val) {
userdata[outidx].num = i;
userdata[outidx].value = val;
outidx++;
}
}
return outidx * sizeof(*userdata);
}
/* Write sample when one or more counters values are nonzero.
*
* Note: The function paiext_sched_task() and paiext_push_sample() are not
* invoked after function paiext_del() has been called because of function
* perf_sched_cb_dec().
* The function paiext_sched_task() and paiext_push_sample() are only
* called when sampling is active. Function perf_sched_cb_inc()
* has been invoked to install function paiext_sched_task() as call back
* to run at context switch time (see paiext_add()).
*
* This causes function perf_event_context_sched_out() and
* perf_event_context_sched_in() to check whether the PMU has installed an
* sched_task() callback. That callback is not active after paiext_del()
* returns and has deleted the event on that CPU.
*/
static int paiext_push_sample(size_t rawsize, struct paiext_map *cpump,
struct perf_event *event)
{
struct perf_sample_data data;
struct perf_raw_record raw;
struct pt_regs regs;
int overflow;
/* Setup perf sample */
memset(&regs, 0, sizeof(regs));
memset(&raw, 0, sizeof(raw));
memset(&data, 0, sizeof(data));
perf_sample_data_init(&data, 0, event->hw.last_period);
if (event->attr.sample_type & PERF_SAMPLE_TID) {
data.tid_entry.pid = task_tgid_nr(current);
data.tid_entry.tid = task_pid_nr(current);
}
if (event->attr.sample_type & PERF_SAMPLE_TIME)
data.time = event->clock();
if (event->attr.sample_type & (PERF_SAMPLE_ID | PERF_SAMPLE_IDENTIFIER))
data.id = event->id;
if (event->attr.sample_type & PERF_SAMPLE_CPU)
data.cpu_entry.cpu = smp_processor_id();
if (event->attr.sample_type & PERF_SAMPLE_RAW) {
raw.frag.size = rawsize;
raw.frag.data = cpump->save;
perf_sample_save_raw_data(&data, event, &raw);
}
overflow = perf_event_overflow(event, &data, &regs);
perf_event_update_userpage(event);
/* Save NNPA lowcore area after read in event */
memcpy((void *)PAI_SAVE_AREA(event), cpump->area,
PAIE1_CTRBLOCK_SZ);
return overflow;
}
/* Check if there is data to be saved on schedule out of a task. */
static void paiext_have_sample(struct perf_event *event,
struct paiext_map *cpump)
{
size_t rawsize;
if (!event)
return;
rawsize = paiext_copy(cpump->save, cpump->area,
(unsigned long *)PAI_SAVE_AREA(event));
if (rawsize) /* Incremented counters */
paiext_push_sample(rawsize, cpump, event);
}
/* Check if there is data to be saved on schedule out of a task. */
static void paiext_have_samples(void)
{
struct paiext_mapptr *mp = this_cpu_ptr(paiext_root.mapptr);
struct paiext_map *cpump = mp->mapptr;
struct perf_event *event;
list_for_each_entry(event, &cpump->syswide_list, hw.tp_list)
paiext_have_sample(event, cpump);
}
/* Called on schedule-in and schedule-out. No access to event structure,
* but for sampling only event NNPA_ALL is allowed.
*/
static void paiext_sched_task(struct perf_event_pmu_context *pmu_ctx,
struct task_struct *task, bool sched_in)
{
/* We started with a clean page on event installation. So read out
* results on schedule_out and if page was dirty, save old values.
*/
if (!sched_in)
paiext_have_samples();
}
/* Attribute definitions for pai extension1 interface. As with other CPU
* Measurement Facilities, there is one attribute per mapped counter.
* The number of mapped counters may vary per machine generation. Use
* the QUERY PROCESSOR ACTIVITY COUNTER INFORMATION (QPACI) instruction
* to determine the number of mapped counters. The instructions returns
* a positive number, which is the highest number of supported counters.
* All counters less than this number are also supported, there are no
* holes. A returned number of zero means no support for mapped counters.
*
* The identification of the counter is a unique number. The chosen range
* is 0x1800 + offset in mapped kernel page.
* All CPU Measurement Facility counters identifiers must be unique and
* the numbers from 0 to 496 are already used for the CPU Measurement
* Counter facility. Number 0x1000 to 0x103e are used for PAI cryptography
* counters.
* Numbers 0xb0000, 0xbc000 and 0xbd000 are already
* used for the CPU Measurement Sampling facility.
*/
PMU_FORMAT_ATTR(event, "config:0-63");
static struct attribute *paiext_format_attr[] = {
&format_attr_event.attr,
NULL,
};
static struct attribute_group paiext_events_group = {
.name = "events",
.attrs = NULL, /* Filled in attr_event_init() */
};
static struct attribute_group paiext_format_group = {
.name = "format",
.attrs = paiext_format_attr,
};
static const struct attribute_group *paiext_attr_groups[] = {
&paiext_events_group,
&paiext_format_group,
NULL,
};
/* Performance monitoring unit for mapped counters */
static struct pmu paiext = {
.task_ctx_nr = perf_hw_context,
.event_init = paiext_event_init,
.add = paiext_add,
.del = paiext_del,
.start = paiext_start,
.stop = paiext_stop,
.read = paiext_read,
.sched_task = paiext_sched_task,
.attr_groups = paiext_attr_groups,
};
/* List of symbolic PAI extension 1 NNPA counter names. */
static const char * const paiext_ctrnames[] = {
[0] = "NNPA_ALL",
[1] = "NNPA_ADD",
[2] = "NNPA_SUB",
[3] = "NNPA_MUL",
[4] = "NNPA_DIV",
[5] = "NNPA_MIN",
[6] = "NNPA_MAX",
[7] = "NNPA_LOG",
[8] = "NNPA_EXP",
[9] = "NNPA_IBM_RESERVED_9",
[10] = "NNPA_RELU",
[11] = "NNPA_TANH",
[12] = "NNPA_SIGMOID",
[13] = "NNPA_SOFTMAX",
[14] = "NNPA_BATCHNORM",
[15] = "NNPA_MAXPOOL2D",
[16] = "NNPA_AVGPOOL2D",
[17] = "NNPA_LSTMACT",
[18] = "NNPA_GRUACT",
[19] = "NNPA_CONVOLUTION",
[20] = "NNPA_MATMUL_OP",
[21] = "NNPA_MATMUL_OP_BCAST23",
[22] = "NNPA_SMALLBATCH",
[23] = "NNPA_LARGEDIM",
[24] = "NNPA_SMALLTENSOR",
[25] = "NNPA_1MFRAME",
[26] = "NNPA_2GFRAME",
[27] = "NNPA_ACCESSEXCEPT",
[28] = "NNPA_TRANSFORM",
[29] = "NNPA_GELU",
[30] = "NNPA_MOMENTS",
[31] = "NNPA_LAYERNORM",
[32] = "NNPA_MATMUL_OP_BCAST1",
[33] = "NNPA_SQRT",
[34] = "NNPA_INVSQRT",
[35] = "NNPA_NORM",
[36] = "NNPA_REDUCE",
};
static void __init attr_event_free(struct attribute **attrs, int num)
{
struct perf_pmu_events_attr *pa;
struct device_attribute *dap;
int i;
for (i = 0; i < num; i++) {
dap = container_of(attrs[i], struct device_attribute, attr);
pa = container_of(dap, struct perf_pmu_events_attr, attr);
kfree(pa);
}
kfree(attrs);
}
static int __init attr_event_init_one(struct attribute **attrs, int num)
{
struct perf_pmu_events_attr *pa;
/* Index larger than array_size, no counter name available */
if (num >= ARRAY_SIZE(paiext_ctrnames)) {
attrs[num] = NULL;
return 0;
}
pa = kzalloc(sizeof(*pa), GFP_KERNEL);
if (!pa)
return -ENOMEM;
sysfs_attr_init(&pa->attr.attr);
pa->id = PAI_NNPA_BASE + num;
pa->attr.attr.name = paiext_ctrnames[num];
pa->attr.attr.mode = 0444;
pa->attr.show = cpumf_events_sysfs_show;
pa->attr.store = NULL;
attrs[num] = &pa->attr.attr;
return 0;
}
/* Create PMU sysfs event attributes on the fly. */
static int __init attr_event_init(void)
{
struct attribute **attrs;
int ret, i;
attrs = kmalloc_array(paiext_cnt + 2, sizeof(*attrs), GFP_KERNEL);
if (!attrs)
return -ENOMEM;
for (i = 0; i <= paiext_cnt; i++) {
ret = attr_event_init_one(attrs, i);
if (ret) {
attr_event_free(attrs, i);
return ret;
}
}
attrs[i] = NULL;
paiext_events_group.attrs = attrs;
return 0;
}
static int __init paiext_init(void)
{
struct qpaci_info_block ib;
int rc = -ENOMEM;
if (!test_facility(197))
return 0;
qpaci(&ib);
paiext_cnt = ib.num_nnpa;
if (paiext_cnt >= PAI_NNPA_MAXCTR)
paiext_cnt = PAI_NNPA_MAXCTR;
if (!paiext_cnt)
return 0;
rc = attr_event_init();
if (rc) {
pr_err("Creation of PMU " KMSG_COMPONENT " /sysfs failed\n");
return rc;
}
/* Setup s390dbf facility */
paiext_dbg = debug_register(KMSG_COMPONENT, 2, 256, 128);
if (!paiext_dbg) {
pr_err("Registration of s390dbf " KMSG_COMPONENT " failed\n");
rc = -ENOMEM;
goto out_init;
}
debug_register_view(paiext_dbg, &debug_sprintf_view);
rc = perf_pmu_register(&paiext, KMSG_COMPONENT, -1);
if (rc) {
pr_err("Registration of " KMSG_COMPONENT " PMU failed with "
"rc=%i\n", rc);
goto out_pmu;
}
return 0;
out_pmu:
debug_unregister_view(paiext_dbg, &debug_sprintf_view);
debug_unregister(paiext_dbg);
out_init:
attr_event_free(paiext_events_group.attrs,
ARRAY_SIZE(paiext_ctrnames) + 1);
return rc;
}
device_initcall(paiext_init);

View File

@ -44,9 +44,6 @@ int perf_reg_validate(u64 mask)
u64 perf_reg_abi(struct task_struct *task)
{
if (test_tsk_thread_flag(task, TIF_31BIT))
return PERF_SAMPLE_REGS_ABI_32;
return PERF_SAMPLE_REGS_ABI_64;
}

View File

@ -24,7 +24,6 @@
#include <linux/tick.h>
#include <linux/personality.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
#include <linux/kprobes.h>
#include <linux/random.h>
#include <linux/init_task.h>
@ -166,12 +165,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
/* Set a new TLS ? */
if (clone_flags & CLONE_SETTLS) {
if (is_compat_task()) {
p->thread.acrs[0] = (unsigned int)tls;
} else {
p->thread.acrs[0] = (unsigned int)(tls >> 32);
p->thread.acrs[1] = (unsigned int)tls;
}
p->thread.acrs[0] = (unsigned int)(tls >> 32);
p->thread.acrs[1] = (unsigned int)tls;
}
/*
* s390 stores the svc return address in arch_data when calling

View File

@ -4,8 +4,7 @@
* Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com)
*/
#define KMSG_COMPONENT "cpu"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "cpu: " fmt
#include <linux/stop_machine.h>
#include <linux/cpufeature.h>

View File

@ -22,7 +22,6 @@
#include <linux/elf.h>
#include <linux/regset.h>
#include <linux/seccomp.h>
#include <linux/compat.h>
#include <trace/syscall.h>
#include <asm/guarded_storage.h>
#include <asm/access-regs.h>
@ -38,10 +37,6 @@
#include "entry.h"
#ifdef CONFIG_COMPAT
#include "compat_ptrace.h"
#endif
void update_cr_regs(struct task_struct *task)
{
struct pt_regs *regs = task_pt_regs(task);
@ -507,308 +502,6 @@ long arch_ptrace(struct task_struct *child, long request,
}
}
#ifdef CONFIG_COMPAT
/*
* Now the fun part starts... a 31 bit program running in the
* 31 bit emulation tracing another program. PTRACE_PEEKTEXT,
* PTRACE_PEEKDATA, PTRACE_POKETEXT and PTRACE_POKEDATA are easy
* to handle, the difference to the 64 bit versions of the requests
* is that the access is done in multiples of 4 byte instead of
* 8 bytes (sizeof(unsigned long) on 31/64 bit).
* The ugly part are PTRACE_PEEKUSR, PTRACE_PEEKUSR_AREA,
* PTRACE_POKEUSR and PTRACE_POKEUSR_AREA. If the traced program
* is a 31 bit program too, the content of struct user can be
* emulated. A 31 bit program peeking into the struct user of
* a 64 bit program is a no-no.
*/
/*
* Same as peek_user_per but for a 31 bit program.
*/
static inline __u32 __peek_user_per_compat(struct task_struct *child,
addr_t addr)
{
if (addr == offsetof(struct compat_per_struct_kernel, cr9))
/* Control bits of the active per set. */
return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
PER_EVENT_IFETCH : child->thread.per_user.control;
else if (addr == offsetof(struct compat_per_struct_kernel, cr10))
/* Start address of the active per set. */
return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
0 : child->thread.per_user.start;
else if (addr == offsetof(struct compat_per_struct_kernel, cr11))
/* End address of the active per set. */
return test_thread_flag(TIF_SINGLE_STEP) ?
PSW32_ADDR_INSN : child->thread.per_user.end;
else if (addr == offsetof(struct compat_per_struct_kernel, bits))
/* Single-step bit. */
return (__u32) test_thread_flag(TIF_SINGLE_STEP) ?
0x80000000 : 0;
else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr))
/* Start address of the user specified per set. */
return (__u32) child->thread.per_user.start;
else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr))
/* End address of the user specified per set. */
return (__u32) child->thread.per_user.end;
else if (addr == offsetof(struct compat_per_struct_kernel, perc_atmid))
/* PER code, ATMID and AI of the last PER trap */
return (__u32) child->thread.per_event.cause << 16;
else if (addr == offsetof(struct compat_per_struct_kernel, address))
/* Address of the last PER trap */
return (__u32) child->thread.per_event.address;
else if (addr == offsetof(struct compat_per_struct_kernel, access_id))
/* Access id of the last PER trap */
return (__u32) child->thread.per_event.paid << 24;
return 0;
}
/*
* Same as peek_user but for a 31 bit program.
*/
static u32 __peek_user_compat(struct task_struct *child, addr_t addr)
{
addr_t offset;
__u32 tmp;
if (addr < offsetof(struct compat_user, regs.acrs)) {
struct pt_regs *regs = task_pt_regs(child);
/*
* psw and gprs are stored on the stack
*/
if (addr == offsetof(struct compat_user, regs.psw.mask)) {
/* Fake a 31 bit psw mask. */
tmp = (__u32)(regs->psw.mask >> 32);
tmp &= PSW32_MASK_USER | PSW32_MASK_RI;
tmp |= PSW32_USER_BITS;
} else if (addr == offsetof(struct compat_user, regs.psw.addr)) {
/* Fake a 31 bit psw address. */
tmp = (__u32) regs->psw.addr |
(__u32)(regs->psw.mask & PSW_MASK_BA);
} else {
/* gpr 0-15 */
tmp = *(__u32 *)((addr_t) &regs->psw + addr*2 + 4);
}
} else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) {
/*
* access registers are stored in the thread structure
*/
offset = addr - offsetof(struct compat_user, regs.acrs);
tmp = *(__u32*)((addr_t) &child->thread.acrs + offset);
} else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) {
/*
* orig_gpr2 is stored on the kernel stack
*/
tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4);
} else if (addr < offsetof(struct compat_user, regs.fp_regs)) {
/*
* prevent reads of padding hole between
* orig_gpr2 and fp_regs on s390.
*/
tmp = 0;
} else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) {
/*
* floating point control reg. is in the thread structure
*/
tmp = child->thread.ufpu.fpc;
} else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) {
/*
* floating point regs. are in the child->thread.ufpu.vxrs array
*/
offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs);
tmp = *(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset);
} else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) {
/*
* Handle access to the per_info structure.
*/
addr -= offsetof(struct compat_user, regs.per_info);
tmp = __peek_user_per_compat(child, addr);
} else
tmp = 0;
return tmp;
}
static int peek_user_compat(struct task_struct *child,
addr_t addr, addr_t data)
{
__u32 tmp;
if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3)
return -EIO;
tmp = __peek_user_compat(child, addr);
return put_user(tmp, (__u32 __user *) data);
}
/*
* Same as poke_user_per but for a 31 bit program.
*/
static inline void __poke_user_per_compat(struct task_struct *child,
addr_t addr, __u32 data)
{
if (addr == offsetof(struct compat_per_struct_kernel, cr9))
/* PER event mask of the user specified per set. */
child->thread.per_user.control =
data & (PER_EVENT_MASK | PER_CONTROL_MASK);
else if (addr == offsetof(struct compat_per_struct_kernel, starting_addr))
/* Starting address of the user specified per set. */
child->thread.per_user.start = data;
else if (addr == offsetof(struct compat_per_struct_kernel, ending_addr))
/* Ending address of the user specified per set. */
child->thread.per_user.end = data;
}
/*
* Same as poke_user but for a 31 bit program.
*/
static int __poke_user_compat(struct task_struct *child,
addr_t addr, addr_t data)
{
__u32 tmp = (__u32) data;
addr_t offset;
if (addr < offsetof(struct compat_user, regs.acrs)) {
struct pt_regs *regs = task_pt_regs(child);
/*
* psw, gprs, acrs and orig_gpr2 are stored on the stack
*/
if (addr == offsetof(struct compat_user, regs.psw.mask)) {
__u32 mask = PSW32_MASK_USER;
mask |= is_ri_task(child) ? PSW32_MASK_RI : 0;
/* Build a 64 bit psw mask from 31 bit mask. */
if ((tmp ^ PSW32_USER_BITS) & ~mask)
/* Invalid psw mask. */
return -EINVAL;
if ((data & PSW32_MASK_ASC) == PSW32_ASC_HOME)
/* Invalid address-space-control bits */
return -EINVAL;
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_USER) |
(regs->psw.mask & PSW_MASK_BA) |
(__u64)(tmp & mask) << 32;
} else if (addr == offsetof(struct compat_user, regs.psw.addr)) {
/* Build a 64 bit psw address from 31 bit address. */
regs->psw.addr = (__u64) tmp & PSW32_ADDR_INSN;
/* Transfer 31 bit amode bit to psw mask. */
regs->psw.mask = (regs->psw.mask & ~PSW_MASK_BA) |
(__u64)(tmp & PSW32_ADDR_AMODE);
} else {
if (test_pt_regs_flag(regs, PIF_SYSCALL) &&
addr == offsetof(struct compat_user, regs.gprs[2])) {
struct pt_regs *regs = task_pt_regs(child);
regs->int_code = 0x20000 | (data & 0xffff);
}
/* gpr 0-15 */
*(__u32*)((addr_t) &regs->psw + addr*2 + 4) = tmp;
}
} else if (addr < offsetof(struct compat_user, regs.orig_gpr2)) {
/*
* access registers are stored in the thread structure
*/
offset = addr - offsetof(struct compat_user, regs.acrs);
*(__u32*)((addr_t) &child->thread.acrs + offset) = tmp;
} else if (addr == offsetof(struct compat_user, regs.orig_gpr2)) {
/*
* orig_gpr2 is stored on the kernel stack
*/
*(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp;
} else if (addr < offsetof(struct compat_user, regs.fp_regs)) {
/*
* prevent writess of padding hole between
* orig_gpr2 and fp_regs on s390.
*/
return 0;
} else if (addr == offsetof(struct compat_user, regs.fp_regs.fpc)) {
/*
* floating point control reg. is in the thread structure
*/
child->thread.ufpu.fpc = data;
} else if (addr < offsetof(struct compat_user, regs.fp_regs) + sizeof(s390_fp_regs)) {
/*
* floating point regs. are in the child->thread.ufpu.vxrs array
*/
offset = addr - offsetof(struct compat_user, regs.fp_regs.fprs);
*(__u32 *)((addr_t)child->thread.ufpu.vxrs + 2 * offset) = tmp;
} else if (addr < offsetof(struct compat_user, regs.per_info) + sizeof(struct compat_per_struct_kernel)) {
/*
* Handle access to the per_info structure.
*/
addr -= offsetof(struct compat_user, regs.per_info);
__poke_user_per_compat(child, addr, data);
}
return 0;
}
static int poke_user_compat(struct task_struct *child,
addr_t addr, addr_t data)
{
if (!is_compat_task() || (addr & 3) ||
addr > sizeof(struct compat_user) - 3)
return -EIO;
return __poke_user_compat(child, addr, data);
}
long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
compat_ulong_t caddr, compat_ulong_t cdata)
{
unsigned long addr = caddr;
unsigned long data = cdata;
compat_ptrace_area parea;
int copied, ret;
switch (request) {
case PTRACE_PEEKUSR:
/* read the word at location addr in the USER area. */
return peek_user_compat(child, addr, data);
case PTRACE_POKEUSR:
/* write the word at location addr in the USER area */
return poke_user_compat(child, addr, data);
case PTRACE_PEEKUSR_AREA:
case PTRACE_POKEUSR_AREA:
if (copy_from_user(&parea, (void __force __user *) addr,
sizeof(parea)))
return -EFAULT;
addr = parea.kernel_addr;
data = parea.process_addr;
copied = 0;
while (copied < parea.len) {
if (request == PTRACE_PEEKUSR_AREA)
ret = peek_user_compat(child, addr, data);
else {
__u32 utmp;
if (get_user(utmp,
(__u32 __force __user *) data))
return -EFAULT;
ret = poke_user_compat(child, addr, utmp);
}
if (ret)
return ret;
addr += sizeof(unsigned int);
data += sizeof(unsigned int);
copied += sizeof(unsigned int);
}
return 0;
case PTRACE_GET_LAST_BREAK:
return put_user(child->thread.last_break, (unsigned int __user *)data);
}
return compat_ptrace_request(child, request, addr, data);
}
#endif
/*
* user_regset definitions.
*/
@ -1297,225 +990,8 @@ static const struct user_regset_view user_s390_view = {
.n = ARRAY_SIZE(s390_regsets)
};
#ifdef CONFIG_COMPAT
static int s390_compat_regs_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
{
unsigned n;
if (target == current)
save_access_regs(target->thread.acrs);
for (n = 0; n < sizeof(s390_compat_regs); n += sizeof(compat_ulong_t))
membuf_store(&to, __peek_user_compat(target, n));
return 0;
}
static int s390_compat_regs_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
int rc = 0;
if (target == current)
save_access_regs(target->thread.acrs);
if (kbuf) {
const compat_ulong_t *k = kbuf;
while (count > 0 && !rc) {
rc = __poke_user_compat(target, pos, *k++);
count -= sizeof(*k);
pos += sizeof(*k);
}
} else {
const compat_ulong_t __user *u = ubuf;
while (count > 0 && !rc) {
compat_ulong_t word;
rc = __get_user(word, u++);
if (rc)
break;
rc = __poke_user_compat(target, pos, word);
count -= sizeof(*u);
pos += sizeof(*u);
}
}
if (rc == 0 && target == current)
restore_access_regs(target->thread.acrs);
return rc;
}
static int s390_compat_regs_high_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
{
compat_ulong_t *gprs_high;
int i;
gprs_high = (compat_ulong_t *)task_pt_regs(target)->gprs;
for (i = 0; i < NUM_GPRS; i++, gprs_high += 2)
membuf_store(&to, *gprs_high);
return 0;
}
static int s390_compat_regs_high_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
compat_ulong_t *gprs_high;
int rc = 0;
gprs_high = (compat_ulong_t *)
&task_pt_regs(target)->gprs[pos / sizeof(compat_ulong_t)];
if (kbuf) {
const compat_ulong_t *k = kbuf;
while (count > 0) {
*gprs_high = *k++;
*gprs_high += 2;
count -= sizeof(*k);
}
} else {
const compat_ulong_t __user *u = ubuf;
while (count > 0 && !rc) {
unsigned long word;
rc = __get_user(word, u++);
if (rc)
break;
*gprs_high = word;
*gprs_high += 2;
count -= sizeof(*u);
}
}
return rc;
}
static int s390_compat_last_break_get(struct task_struct *target,
const struct user_regset *regset,
struct membuf to)
{
compat_ulong_t last_break = target->thread.last_break;
return membuf_store(&to, (unsigned long)last_break);
}
static int s390_compat_last_break_set(struct task_struct *target,
const struct user_regset *regset,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
return 0;
}
static const struct user_regset s390_compat_regsets[] = {
{
USER_REGSET_NOTE_TYPE(PRSTATUS),
.n = sizeof(s390_compat_regs) / sizeof(compat_long_t),
.size = sizeof(compat_long_t),
.align = sizeof(compat_long_t),
.regset_get = s390_compat_regs_get,
.set = s390_compat_regs_set,
},
{
USER_REGSET_NOTE_TYPE(PRFPREG),
.n = sizeof(s390_fp_regs) / sizeof(compat_long_t),
.size = sizeof(compat_long_t),
.align = sizeof(compat_long_t),
.regset_get = s390_fpregs_get,
.set = s390_fpregs_set,
},
{
USER_REGSET_NOTE_TYPE(S390_SYSTEM_CALL),
.n = 1,
.size = sizeof(compat_uint_t),
.align = sizeof(compat_uint_t),
.regset_get = s390_system_call_get,
.set = s390_system_call_set,
},
{
USER_REGSET_NOTE_TYPE(S390_LAST_BREAK),
.n = 1,
.size = sizeof(long),
.align = sizeof(long),
.regset_get = s390_compat_last_break_get,
.set = s390_compat_last_break_set,
},
{
USER_REGSET_NOTE_TYPE(S390_TDB),
.n = 1,
.size = 256,
.align = 1,
.regset_get = s390_tdb_get,
.set = s390_tdb_set,
},
{
USER_REGSET_NOTE_TYPE(S390_VXRS_LOW),
.n = __NUM_VXRS_LOW,
.size = sizeof(__u64),
.align = sizeof(__u64),
.regset_get = s390_vxrs_low_get,
.set = s390_vxrs_low_set,
},
{
USER_REGSET_NOTE_TYPE(S390_VXRS_HIGH),
.n = __NUM_VXRS_HIGH,
.size = sizeof(__vector128),
.align = sizeof(__vector128),
.regset_get = s390_vxrs_high_get,
.set = s390_vxrs_high_set,
},
{
USER_REGSET_NOTE_TYPE(S390_HIGH_GPRS),
.n = sizeof(s390_compat_regs_high) / sizeof(compat_long_t),
.size = sizeof(compat_long_t),
.align = sizeof(compat_long_t),
.regset_get = s390_compat_regs_high_get,
.set = s390_compat_regs_high_set,
},
{
USER_REGSET_NOTE_TYPE(S390_GS_CB),
.n = sizeof(struct gs_cb) / sizeof(__u64),
.size = sizeof(__u64),
.align = sizeof(__u64),
.regset_get = s390_gs_cb_get,
.set = s390_gs_cb_set,
},
{
USER_REGSET_NOTE_TYPE(S390_GS_BC),
.n = sizeof(struct gs_cb) / sizeof(__u64),
.size = sizeof(__u64),
.align = sizeof(__u64),
.regset_get = s390_gs_bc_get,
.set = s390_gs_bc_set,
},
{
USER_REGSET_NOTE_TYPE(S390_RI_CB),
.n = sizeof(struct runtime_instr_cb) / sizeof(__u64),
.size = sizeof(__u64),
.align = sizeof(__u64),
.regset_get = s390_runtime_instr_get,
.set = s390_runtime_instr_set,
},
};
static const struct user_regset_view user_s390_compat_view = {
.name = "s390",
.e_machine = EM_S390,
.regsets = s390_compat_regsets,
.n = ARRAY_SIZE(s390_compat_regsets)
};
#endif
const struct user_regset_view *task_user_regset_view(struct task_struct *task)
{
#ifdef CONFIG_COMPAT
if (test_tsk_thread_flag(task, TIF_31BIT))
return &user_s390_compat_view;
#endif
return &user_s390_view;
}

View File

@ -13,8 +13,7 @@
* This file handles the architecture-dependent parts of initialization
*/
#define KMSG_COMPONENT "setup"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "setup: " fmt
#include <linux/errno.h>
#include <linux/export.h>
@ -47,7 +46,6 @@
#include <linux/kexec.h>
#include <linux/crash_dump.h>
#include <linux/memory.h>
#include <linux/compat.h>
#include <linux/start_kernel.h>
#include <linux/hugetlb.h>
#include <linux/kmemleak.h>
@ -112,7 +110,7 @@ struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amod
* Because the AMODE31 sections are relocated below 2G at startup,
* the content of control registers CR2, CR5 and CR15 must be updated
* with new addresses after the relocation. The initial initialization of
* control registers occurs in head64.S and then gets updated again after AMODE31
* control registers occurs in head.S and then gets updated again after AMODE31
* relocation. We must access the relevant AMODE31 tables indirectly via
* pointers placed in the .amode31.refs linker section. Those pointers get
* updated automatically during AMODE31 relocation and always contain a valid

View File

@ -27,7 +27,6 @@
#include <linux/personality.h>
#include <linux/binfmts.h>
#include <linux/syscalls.h>
#include <linux/compat.h>
#include <asm/ucontext.h>
#include <linux/uaccess.h>
#include <asm/vdso-symbols.h>
@ -290,12 +289,6 @@ static int setup_frame(int sig, struct k_sigaction *ka,
unsigned long restorer;
size_t frame_size;
/*
* gprs_high are only present for a 31-bit task running on
* a 64-bit kernel (see compat_signal.c) but the space for
* gprs_high need to be allocated if vector registers are
* included in the signal frame on a 31-bit system.
*/
frame_size = sizeof(*frame) - sizeof(frame->sregs_ext);
if (cpu_has_vx())
frame_size += sizeof(frame->sregs_ext);
@ -333,7 +326,7 @@ static int setup_frame(int sig, struct k_sigaction *ka,
if (ka->sa.sa_flags & SA_RESTORER)
restorer = (unsigned long) ka->sa.sa_restorer;
else
restorer = VDSO64_SYMBOL(current, sigreturn);
restorer = VDSO_SYMBOL(current, sigreturn);
/* Set up registers for signal handler */
regs->gprs[14] = restorer;
@ -367,12 +360,6 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
size_t frame_size;
frame_size = sizeof(struct rt_sigframe) - sizeof(_sigregs_ext);
/*
* gprs_high are only present for a 31-bit task running on
* a 64-bit kernel (see compat_signal.c) but the space for
* gprs_high need to be allocated if vector registers are
* included in the signal frame on a 31-bit system.
*/
uc_flags = 0;
if (cpu_has_vx()) {
frame_size += sizeof(_sigregs_ext);
@ -391,7 +378,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
if (ksig->ka.sa.sa_flags & SA_RESTORER)
restorer = (unsigned long) ksig->ka.sa.sa_restorer;
else
restorer = VDSO64_SYMBOL(current, rt_sigreturn);
restorer = VDSO_SYMBOL(current, rt_sigreturn);
/* Create siginfo on the signal stack */
if (copy_siginfo_to_user(&frame->info, &ksig->info))
@ -490,10 +477,7 @@ void arch_do_signal_or_restart(struct pt_regs *regs)
clear_pt_regs_flag(regs, PIF_SYSCALL);
rseq_signal_deliver(&ksig, regs);
if (is_compat_task())
handle_signal32(&ksig, oldset, regs);
else
handle_signal(&ksig, oldset, regs);
handle_signal(&ksig, oldset, regs);
return;
}
@ -506,10 +490,7 @@ void arch_do_signal_or_restart(struct pt_regs *regs)
/* Restart with sys_restart_syscall */
regs->gprs[2] = regs->orig_gpr2;
current->restart_block.arch_data = regs->psw.addr;
if (is_compat_task())
regs->psw.addr = VDSO32_SYMBOL(current, restart_syscall);
else
regs->psw.addr = VDSO64_SYMBOL(current, restart_syscall);
regs->psw.addr = VDSO_SYMBOL(current, restart_syscall);
if (test_thread_flag(TIF_SINGLE_STEP))
clear_thread_flag(TIF_PER_TRAP);
break;

View File

@ -15,8 +15,7 @@
* operates on physical cpu numbers needs to go into smp.c.
*/
#define KMSG_COMPONENT "cpu"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "cpu: " fmt
#include <linux/cpufeature.h>
#include <linux/workqueue.h>
@ -281,6 +280,9 @@ static void pcpu_attach_task(int cpu, struct task_struct *tsk)
lc->hardirq_timer = tsk->thread.hardirq_timer;
lc->softirq_timer = tsk->thread.softirq_timer;
lc->steal_timer = 0;
#ifdef CONFIG_STACKPROTECTOR
lc->stack_canary = tsk->stack_canary;
#endif
}
static void pcpu_start_fn(int cpu, void (*func)(void *), void *data)
@ -305,9 +307,9 @@ static void __pcpu_delegate(pcpu_delegate_fn *func, void *data)
func(data); /* should not return */
}
static void pcpu_delegate(struct pcpu *pcpu, int cpu,
pcpu_delegate_fn *func,
void *data, unsigned long stack)
static void __noreturn pcpu_delegate(struct pcpu *pcpu, int cpu,
pcpu_delegate_fn *func,
void *data, unsigned long stack)
{
struct lowcore *lc, *abs_lc;
unsigned int source_cpu;
@ -370,7 +372,7 @@ static int pcpu_set_smt(unsigned int mtid)
/*
* Call function on the ipl CPU.
*/
void smp_call_ipl_cpu(void (*func)(void *), void *data)
void __noreturn smp_call_ipl_cpu(void (*func)(void *), void *data)
{
struct lowcore *lc = lowcore_ptr[0];
@ -697,6 +699,7 @@ static void __ref smp_get_core_info(struct sclp_core_info *info, int early)
continue;
info->core[info->configured].core_id =
address >> smp_cpu_mt_shift;
info->core[info->configured].type = boot_core_type;
info->configured++;
}
info->combined = info->configured;

View File

@ -0,0 +1,156 @@
// SPDX-License-Identifier: GPL-2.0
#ifndef pr_fmt
#define pr_fmt(fmt) "stackprot: " fmt
#endif
#include <linux/export.h>
#include <linux/uaccess.h>
#include <linux/printk.h>
#include <asm/abs_lowcore.h>
#include <asm/sections.h>
#include <asm/machine.h>
#include <asm/asm-offsets.h>
#include <asm/arch-stackprotector.h>
#ifdef __DECOMPRESSOR
#define DEBUGP boot_debug
#define EMERGP boot_emerg
#define PANIC boot_panic
#else /* __DECOMPRESSOR */
#define DEBUGP pr_debug
#define EMERGP pr_emerg
#define PANIC panic
#endif /* __DECOMPRESSOR */
int __bootdata_preserved(stack_protector_debug);
unsigned long __stack_chk_guard;
EXPORT_SYMBOL(__stack_chk_guard);
struct insn_ril {
u8 opc1 : 8;
u8 r1 : 4;
u8 opc2 : 4;
u32 imm;
} __packed;
/*
* Convert a virtual instruction address to a real instruction address. The
* decompressor needs to patch instructions within the kernel image based on
* their virtual addresses, while dynamic address translation is still
* disabled. Therefore a translation from virtual kernel image addresses to
* the corresponding physical addresses is required.
*
* After dynamic address translation is enabled and when the kernel needs to
* patch instructions such a translation is not required since the addresses
* are identical.
*/
static struct insn_ril *vaddress_to_insn(unsigned long vaddress)
{
#ifdef __DECOMPRESSOR
return (struct insn_ril *)__kernel_pa(vaddress);
#else
return (struct insn_ril *)vaddress;
#endif
}
static unsigned long insn_to_vaddress(struct insn_ril *insn)
{
#ifdef __DECOMPRESSOR
return (unsigned long)__kernel_va(insn);
#else
return (unsigned long)insn;
#endif
}
#define INSN_RIL_STRING_SIZE (sizeof(struct insn_ril) * 2 + 1)
static void insn_ril_to_string(char *str, struct insn_ril *insn)
{
u8 *ptr = (u8 *)insn;
int i;
for (i = 0; i < sizeof(*insn); i++)
hex_byte_pack(&str[2 * i], ptr[i]);
str[2 * i] = 0;
}
static void stack_protector_dump(struct insn_ril *old, struct insn_ril *new)
{
char ostr[INSN_RIL_STRING_SIZE];
char nstr[INSN_RIL_STRING_SIZE];
insn_ril_to_string(ostr, old);
insn_ril_to_string(nstr, new);
DEBUGP("%016lx: %s -> %s\n", insn_to_vaddress(old), ostr, nstr);
}
static int stack_protector_verify(struct insn_ril *insn, unsigned long kernel_start)
{
char istr[INSN_RIL_STRING_SIZE];
unsigned long vaddress, offset;
/* larl */
if (insn->opc1 == 0xc0 && insn->opc2 == 0x0)
return 0;
/* lgrl */
if (insn->opc1 == 0xc4 && insn->opc2 == 0x8)
return 0;
insn_ril_to_string(istr, insn);
vaddress = insn_to_vaddress(insn);
if (__is_defined(__DECOMPRESSOR)) {
offset = (unsigned long)insn - kernel_start + TEXT_OFFSET;
EMERGP("Unexpected instruction at %016lx/%016lx: %s\n", vaddress, offset, istr);
PANIC("Stackprotector error\n");
} else {
EMERGP("Unexpected instruction at %016lx: %s\n", vaddress, istr);
}
return -EINVAL;
}
int __stack_protector_apply(unsigned long *start, unsigned long *end, unsigned long kernel_start)
{
unsigned long canary, *loc;
struct insn_ril *insn, new;
int rc;
/*
* Convert LARL/LGRL instructions to LLILF so register R1 contains the
* address of the per-cpu / per-process stack canary:
*
* LARL/LGRL R1,__stack_chk_guard => LLILF R1,__lc_stack_canary
*/
canary = __LC_STACK_CANARY;
if (machine_has_relocated_lowcore())
canary += LOWCORE_ALT_ADDRESS;
for (loc = start; loc < end; loc++) {
insn = vaddress_to_insn(*loc);
rc = stack_protector_verify(insn, kernel_start);
if (rc)
return rc;
new = *insn;
new.opc1 = 0xc0;
new.opc2 = 0xf;
new.imm = canary;
if (stack_protector_debug)
stack_protector_dump(insn, &new);
s390_kernel_write(insn, &new, sizeof(*insn));
}
return 0;
}
#ifdef __DECOMPRESSOR
void __stack_protector_apply_early(unsigned long kernel_start)
{
unsigned long *start, *end;
start = (unsigned long *)vmlinux.stack_prot_start;
end = (unsigned long *)vmlinux.stack_prot_end;
__stack_protector_apply(start, end, kernel_start);
}
#endif

View File

@ -8,7 +8,6 @@
#include <linux/perf_event.h>
#include <linux/stacktrace.h>
#include <linux/uaccess.h>
#include <linux/compat.h>
#include <asm/asm-offsets.h>
#include <asm/stacktrace.h>
#include <asm/unwind.h>
@ -107,8 +106,6 @@ void arch_stack_walk_user_common(stack_trace_consume_fn consume_entry, void *coo
unsigned long ip, sp;
bool first = true;
if (is_compat_task())
return;
if (!current->mm)
return;
ip = instruction_pointer(regs);

View File

@ -253,7 +253,7 @@ static void fill_diag_mac(struct sthyi_sctns *sctns,
sctns->mac.infmval1 |= MAC_CNT_VLD;
}
/* Returns a pointer to the the next partition block. */
/* Returns a pointer to the next partition block. */
static struct diag204_x_part_block *lpar_cpu_inf(struct lpar_cpu_inf *part_inf,
bool this_lpar,
void *diag224_buf,

View File

@ -39,6 +39,16 @@
#include "entry.h"
#define __SYSCALL(nr, sym) long __s390x_##sym(struct pt_regs *);
#include <asm/syscall_table.h>
#undef __SYSCALL
#define __SYSCALL(nr, sym) [nr] = (__s390x_##sym),
const sys_call_ptr_t sys_call_table[__NR_syscalls] = {
#include <asm/syscall_table.h>
};
#undef __SYSCALL
#ifdef CONFIG_SYSVIPC
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls.
@ -122,7 +132,7 @@ void noinstr __do_syscall(struct pt_regs *regs, int per_trap)
goto out;
regs->gprs[2] = -ENOSYS;
if (likely(nr < NR_syscalls))
regs->gprs[2] = current->thread.sys_call_table[nr](regs);
regs->gprs[2] = sys_call_table[nr](regs);
out:
syscall_exit_to_user_mode(regs);
}

View File

@ -1,48 +1,32 @@
# SPDX-License-Identifier: GPL-2.0
kapi := arch/$(SRCARCH)/include/generated/asm
uapi := arch/$(SRCARCH)/include/generated/uapi/asm
gen := arch/$(ARCH)/include/generated
kapi := $(gen)/asm
uapi := $(gen)/uapi/asm
syscall := $(src)/syscall.tbl
systbl := $(src)/syscalltbl
gen-y := $(kapi)/syscall_table.h
kapi-hdrs-y := $(kapi)/unistd_nr.h
uapi-hdrs-y := $(uapi)/unistd_32.h
uapi-hdrs-y += $(uapi)/unistd_64.h
targets += $(addprefix ../../../../,$(gen-y) $(kapi-hdrs-y) $(uapi-hdrs-y))
PHONY += kapi uapi
kapi: $(gen-y) $(kapi-hdrs-y)
uapi: $(uapi-hdrs-y)
# Create output directory if not already present
$(shell mkdir -p $(uapi) $(kapi))
syscall := $(src)/syscall.tbl
syshdr := $(srctree)/scripts/syscallhdr.sh
systbl := $(srctree)/scripts/syscalltbl.sh
quiet_cmd_syshdr = SYSHDR $@
cmd_syshdr = $(CONFIG_SHELL) '$(systbl)' -H -a $(syshdr_abi_$(basetarget)) -f "$@" < $< > $@
cmd_syshdr = $(CONFIG_SHELL) $(syshdr) --emit-nr --abis common,$* $< $@
quiet_cmd_sysnr = SYSNR $@
cmd_sysnr = $(CONFIG_SHELL) '$(systbl)' -N -a $(sysnr_abi_$(basetarget)) < $< > $@
quiet_cmd_systbl = SYSTBL $@
cmd_systbl = $(CONFIG_SHELL) $(systbl) --abis common,$* $< $@
quiet_cmd_syscalls = SYSTBL $@
cmd_syscalls = $(CONFIG_SHELL) '$(systbl)' -S < $< > $@
syshdr_abi_unistd_32 := common,32
$(uapi)/unistd_32.h: $(syscall) $(systbl) FORCE
$(call if_changed,syshdr)
syshdr_abi_unistd_64 := common,64
$(uapi)/unistd_64.h: $(syscall) $(systbl) FORCE
$(uapi)/unistd_%.h: $(syscall) $(syshdr) FORCE
$(call if_changed,syshdr)
$(kapi)/syscall_table.h: $(syscall) $(systbl) FORCE
$(call if_changed,syscalls)
$(call if_changed,systbl)
sysnr_abi_unistd_nr := common,32,64
$(kapi)/unistd_nr.h: $(syscall) $(systbl) FORCE
$(call if_changed,sysnr)
uapisyshdr-y += unistd_64.h
kapisyshdr-y += syscall_table.h
uapisyshdr-y := $(addprefix $(uapi)/, $(uapisyshdr-y))
kapisyshdr-y := $(addprefix $(kapi)/, $(kapisyshdr-y))
targets += $(addprefix ../../../../, $(uapisyshdr-y) $(kapisyshdr-y))
PHONY += all
all: $(uapisyshdr-y) $(kapisyshdr-y)
@:

View File

@ -3,473 +3,397 @@
# System call table for s390
#
# Format:
# <nr> <abi> <syscall> <entry>
#
# <nr> <abi> <syscall> <entry-64bit> <compat-entry>
#
# where <abi> can be common, 64, or 32
# <abi> is always common.
1 common exit sys_exit sys_exit
2 common fork sys_fork sys_fork
3 common read sys_read compat_sys_s390_read
4 common write sys_write compat_sys_s390_write
5 common open sys_open compat_sys_open
6 common close sys_close sys_close
7 common restart_syscall sys_restart_syscall sys_restart_syscall
8 common creat sys_creat sys_creat
9 common link sys_link sys_link
10 common unlink sys_unlink sys_unlink
11 common execve sys_execve compat_sys_execve
12 common chdir sys_chdir sys_chdir
13 32 time - sys_time32
14 common mknod sys_mknod sys_mknod
15 common chmod sys_chmod sys_chmod
16 32 lchown - sys_lchown16
19 common lseek sys_lseek compat_sys_lseek
20 common getpid sys_getpid sys_getpid
21 common mount sys_mount sys_mount
22 common umount sys_oldumount sys_oldumount
23 32 setuid - sys_setuid16
24 32 getuid - sys_getuid16
25 32 stime - sys_stime32
26 common ptrace sys_ptrace compat_sys_ptrace
27 common alarm sys_alarm sys_alarm
29 common pause sys_pause sys_pause
30 common utime sys_utime sys_utime32
33 common access sys_access sys_access
34 common nice sys_nice sys_nice
36 common sync sys_sync sys_sync
37 common kill sys_kill sys_kill
38 common rename sys_rename sys_rename
39 common mkdir sys_mkdir sys_mkdir
40 common rmdir sys_rmdir sys_rmdir
41 common dup sys_dup sys_dup
42 common pipe sys_pipe sys_pipe
43 common times sys_times compat_sys_times
45 common brk sys_brk sys_brk
46 32 setgid - sys_setgid16
47 32 getgid - sys_getgid16
48 common signal sys_signal sys_signal
49 32 geteuid - sys_geteuid16
50 32 getegid - sys_getegid16
51 common acct sys_acct sys_acct
52 common umount2 sys_umount sys_umount
54 common ioctl sys_ioctl compat_sys_ioctl
55 common fcntl sys_fcntl compat_sys_fcntl
57 common setpgid sys_setpgid sys_setpgid
60 common umask sys_umask sys_umask
61 common chroot sys_chroot sys_chroot
62 common ustat sys_ustat compat_sys_ustat
63 common dup2 sys_dup2 sys_dup2
64 common getppid sys_getppid sys_getppid
65 common getpgrp sys_getpgrp sys_getpgrp
66 common setsid sys_setsid sys_setsid
67 common sigaction sys_sigaction compat_sys_sigaction
70 32 setreuid - sys_setreuid16
71 32 setregid - sys_setregid16
72 common sigsuspend sys_sigsuspend sys_sigsuspend
73 common sigpending sys_sigpending compat_sys_sigpending
74 common sethostname sys_sethostname sys_sethostname
75 common setrlimit sys_setrlimit compat_sys_setrlimit
76 32 getrlimit - compat_sys_old_getrlimit
77 common getrusage sys_getrusage compat_sys_getrusage
78 common gettimeofday sys_gettimeofday compat_sys_gettimeofday
79 common settimeofday sys_settimeofday compat_sys_settimeofday
80 32 getgroups - sys_getgroups16
81 32 setgroups - sys_setgroups16
83 common symlink sys_symlink sys_symlink
85 common readlink sys_readlink sys_readlink
86 common uselib sys_uselib sys_uselib
87 common swapon sys_swapon sys_swapon
88 common reboot sys_reboot sys_reboot
89 common readdir - compat_sys_old_readdir
90 common mmap sys_old_mmap compat_sys_s390_old_mmap
91 common munmap sys_munmap sys_munmap
92 common truncate sys_truncate compat_sys_truncate
93 common ftruncate sys_ftruncate compat_sys_ftruncate
94 common fchmod sys_fchmod sys_fchmod
95 32 fchown - sys_fchown16
96 common getpriority sys_getpriority sys_getpriority
97 common setpriority sys_setpriority sys_setpriority
99 common statfs sys_statfs compat_sys_statfs
100 common fstatfs sys_fstatfs compat_sys_fstatfs
101 32 ioperm - -
102 common socketcall sys_socketcall compat_sys_socketcall
103 common syslog sys_syslog sys_syslog
104 common setitimer sys_setitimer compat_sys_setitimer
105 common getitimer sys_getitimer compat_sys_getitimer
106 common stat sys_newstat compat_sys_newstat
107 common lstat sys_newlstat compat_sys_newlstat
108 common fstat sys_newfstat compat_sys_newfstat
110 common lookup_dcookie - -
111 common vhangup sys_vhangup sys_vhangup
112 common idle - -
114 common wait4 sys_wait4 compat_sys_wait4
115 common swapoff sys_swapoff sys_swapoff
116 common sysinfo sys_sysinfo compat_sys_sysinfo
117 common ipc sys_s390_ipc compat_sys_s390_ipc
118 common fsync sys_fsync sys_fsync
119 common sigreturn sys_sigreturn compat_sys_sigreturn
120 common clone sys_clone sys_clone
121 common setdomainname sys_setdomainname sys_setdomainname
122 common uname sys_newuname sys_newuname
124 common adjtimex sys_adjtimex sys_adjtimex_time32
125 common mprotect sys_mprotect sys_mprotect
126 common sigprocmask sys_sigprocmask compat_sys_sigprocmask
127 common create_module - -
128 common init_module sys_init_module sys_init_module
129 common delete_module sys_delete_module sys_delete_module
130 common get_kernel_syms - -
131 common quotactl sys_quotactl sys_quotactl
132 common getpgid sys_getpgid sys_getpgid
133 common fchdir sys_fchdir sys_fchdir
134 common bdflush sys_ni_syscall sys_ni_syscall
135 common sysfs sys_sysfs sys_sysfs
136 common personality sys_s390_personality sys_s390_personality
137 common afs_syscall - -
138 32 setfsuid - sys_setfsuid16
139 32 setfsgid - sys_setfsgid16
140 32 _llseek - sys_llseek
141 common getdents sys_getdents compat_sys_getdents
142 32 _newselect - compat_sys_select
142 64 select sys_select -
143 common flock sys_flock sys_flock
144 common msync sys_msync sys_msync
145 common readv sys_readv sys_readv
146 common writev sys_writev sys_writev
147 common getsid sys_getsid sys_getsid
148 common fdatasync sys_fdatasync sys_fdatasync
149 common _sysctl - -
150 common mlock sys_mlock sys_mlock
151 common munlock sys_munlock sys_munlock
152 common mlockall sys_mlockall sys_mlockall
153 common munlockall sys_munlockall sys_munlockall
154 common sched_setparam sys_sched_setparam sys_sched_setparam
155 common sched_getparam sys_sched_getparam sys_sched_getparam
156 common sched_setscheduler sys_sched_setscheduler sys_sched_setscheduler
157 common sched_getscheduler sys_sched_getscheduler sys_sched_getscheduler
158 common sched_yield sys_sched_yield sys_sched_yield
159 common sched_get_priority_max sys_sched_get_priority_max sys_sched_get_priority_max
160 common sched_get_priority_min sys_sched_get_priority_min sys_sched_get_priority_min
161 common sched_rr_get_interval sys_sched_rr_get_interval sys_sched_rr_get_interval_time32
162 common nanosleep sys_nanosleep sys_nanosleep_time32
163 common mremap sys_mremap sys_mremap
164 32 setresuid - sys_setresuid16
165 32 getresuid - sys_getresuid16
167 common query_module - -
168 common poll sys_poll sys_poll
169 common nfsservctl - -
170 32 setresgid - sys_setresgid16
171 32 getresgid - sys_getresgid16
172 common prctl sys_prctl sys_prctl
173 common rt_sigreturn sys_rt_sigreturn compat_sys_rt_sigreturn
174 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
175 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask
176 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
177 common rt_sigtimedwait sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time32
178 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
179 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
180 common pread64 sys_pread64 compat_sys_s390_pread64
181 common pwrite64 sys_pwrite64 compat_sys_s390_pwrite64
182 32 chown - sys_chown16
183 common getcwd sys_getcwd sys_getcwd
184 common capget sys_capget sys_capget
185 common capset sys_capset sys_capset
186 common sigaltstack sys_sigaltstack compat_sys_sigaltstack
187 common sendfile sys_sendfile64 compat_sys_sendfile
188 common getpmsg - -
189 common putpmsg - -
190 common vfork sys_vfork sys_vfork
191 32 ugetrlimit - compat_sys_getrlimit
191 64 getrlimit sys_getrlimit -
192 32 mmap2 - compat_sys_s390_mmap2
193 32 truncate64 - compat_sys_s390_truncate64
194 32 ftruncate64 - compat_sys_s390_ftruncate64
195 32 stat64 - compat_sys_s390_stat64
196 32 lstat64 - compat_sys_s390_lstat64
197 32 fstat64 - compat_sys_s390_fstat64
198 32 lchown32 - sys_lchown
198 64 lchown sys_lchown -
199 32 getuid32 - sys_getuid
199 64 getuid sys_getuid -
200 32 getgid32 - sys_getgid
200 64 getgid sys_getgid -
201 32 geteuid32 - sys_geteuid
201 64 geteuid sys_geteuid -
202 32 getegid32 - sys_getegid
202 64 getegid sys_getegid -
203 32 setreuid32 - sys_setreuid
203 64 setreuid sys_setreuid -
204 32 setregid32 - sys_setregid
204 64 setregid sys_setregid -
205 32 getgroups32 - sys_getgroups
205 64 getgroups sys_getgroups -
206 32 setgroups32 - sys_setgroups
206 64 setgroups sys_setgroups -
207 32 fchown32 - sys_fchown
207 64 fchown sys_fchown -
208 32 setresuid32 - sys_setresuid
208 64 setresuid sys_setresuid -
209 32 getresuid32 - sys_getresuid
209 64 getresuid sys_getresuid -
210 32 setresgid32 - sys_setresgid
210 64 setresgid sys_setresgid -
211 32 getresgid32 - sys_getresgid
211 64 getresgid sys_getresgid -
212 32 chown32 - sys_chown
212 64 chown sys_chown -
213 32 setuid32 - sys_setuid
213 64 setuid sys_setuid -
214 32 setgid32 - sys_setgid
214 64 setgid sys_setgid -
215 32 setfsuid32 - sys_setfsuid
215 64 setfsuid sys_setfsuid -
216 32 setfsgid32 - sys_setfsgid
216 64 setfsgid sys_setfsgid -
217 common pivot_root sys_pivot_root sys_pivot_root
218 common mincore sys_mincore sys_mincore
219 common madvise sys_madvise sys_madvise
220 common getdents64 sys_getdents64 sys_getdents64
221 32 fcntl64 - compat_sys_fcntl64
222 common readahead sys_readahead compat_sys_s390_readahead
223 32 sendfile64 - compat_sys_sendfile64
224 common setxattr sys_setxattr sys_setxattr
225 common lsetxattr sys_lsetxattr sys_lsetxattr
226 common fsetxattr sys_fsetxattr sys_fsetxattr
227 common getxattr sys_getxattr sys_getxattr
228 common lgetxattr sys_lgetxattr sys_lgetxattr
229 common fgetxattr sys_fgetxattr sys_fgetxattr
230 common listxattr sys_listxattr sys_listxattr
231 common llistxattr sys_llistxattr sys_llistxattr
232 common flistxattr sys_flistxattr sys_flistxattr
233 common removexattr sys_removexattr sys_removexattr
234 common lremovexattr sys_lremovexattr sys_lremovexattr
235 common fremovexattr sys_fremovexattr sys_fremovexattr
236 common gettid sys_gettid sys_gettid
237 common tkill sys_tkill sys_tkill
238 common futex sys_futex sys_futex_time32
239 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity
240 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity
241 common tgkill sys_tgkill sys_tgkill
243 common io_setup sys_io_setup compat_sys_io_setup
244 common io_destroy sys_io_destroy sys_io_destroy
245 common io_getevents sys_io_getevents sys_io_getevents_time32
246 common io_submit sys_io_submit compat_sys_io_submit
247 common io_cancel sys_io_cancel sys_io_cancel
248 common exit_group sys_exit_group sys_exit_group
249 common epoll_create sys_epoll_create sys_epoll_create
250 common epoll_ctl sys_epoll_ctl sys_epoll_ctl
251 common epoll_wait sys_epoll_wait sys_epoll_wait
252 common set_tid_address sys_set_tid_address sys_set_tid_address
253 common fadvise64 sys_fadvise64_64 compat_sys_s390_fadvise64
254 common timer_create sys_timer_create compat_sys_timer_create
255 common timer_settime sys_timer_settime sys_timer_settime32
256 common timer_gettime sys_timer_gettime sys_timer_gettime32
257 common timer_getoverrun sys_timer_getoverrun sys_timer_getoverrun
258 common timer_delete sys_timer_delete sys_timer_delete
259 common clock_settime sys_clock_settime sys_clock_settime32
260 common clock_gettime sys_clock_gettime sys_clock_gettime32
261 common clock_getres sys_clock_getres sys_clock_getres_time32
262 common clock_nanosleep sys_clock_nanosleep sys_clock_nanosleep_time32
264 32 fadvise64_64 - compat_sys_s390_fadvise64_64
265 common statfs64 sys_statfs64 compat_sys_statfs64
266 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64
267 common remap_file_pages sys_remap_file_pages sys_remap_file_pages
268 common mbind sys_mbind sys_mbind
269 common get_mempolicy sys_get_mempolicy sys_get_mempolicy
270 common set_mempolicy sys_set_mempolicy sys_set_mempolicy
271 common mq_open sys_mq_open compat_sys_mq_open
272 common mq_unlink sys_mq_unlink sys_mq_unlink
273 common mq_timedsend sys_mq_timedsend sys_mq_timedsend_time32
274 common mq_timedreceive sys_mq_timedreceive sys_mq_timedreceive_time32
275 common mq_notify sys_mq_notify compat_sys_mq_notify
276 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr
277 common kexec_load sys_kexec_load compat_sys_kexec_load
278 common add_key sys_add_key sys_add_key
279 common request_key sys_request_key sys_request_key
280 common keyctl sys_keyctl compat_sys_keyctl
281 common waitid sys_waitid compat_sys_waitid
282 common ioprio_set sys_ioprio_set sys_ioprio_set
283 common ioprio_get sys_ioprio_get sys_ioprio_get
284 common inotify_init sys_inotify_init sys_inotify_init
285 common inotify_add_watch sys_inotify_add_watch sys_inotify_add_watch
286 common inotify_rm_watch sys_inotify_rm_watch sys_inotify_rm_watch
287 common migrate_pages sys_migrate_pages sys_migrate_pages
288 common openat sys_openat compat_sys_openat
289 common mkdirat sys_mkdirat sys_mkdirat
290 common mknodat sys_mknodat sys_mknodat
291 common fchownat sys_fchownat sys_fchownat
292 common futimesat sys_futimesat sys_futimesat_time32
293 32 fstatat64 - compat_sys_s390_fstatat64
293 64 newfstatat sys_newfstatat -
294 common unlinkat sys_unlinkat sys_unlinkat
295 common renameat sys_renameat sys_renameat
296 common linkat sys_linkat sys_linkat
297 common symlinkat sys_symlinkat sys_symlinkat
298 common readlinkat sys_readlinkat sys_readlinkat
299 common fchmodat sys_fchmodat sys_fchmodat
300 common faccessat sys_faccessat sys_faccessat
301 common pselect6 sys_pselect6 compat_sys_pselect6_time32
302 common ppoll sys_ppoll compat_sys_ppoll_time32
303 common unshare sys_unshare sys_unshare
304 common set_robust_list sys_set_robust_list compat_sys_set_robust_list
305 common get_robust_list sys_get_robust_list compat_sys_get_robust_list
306 common splice sys_splice sys_splice
307 common sync_file_range sys_sync_file_range compat_sys_s390_sync_file_range
308 common tee sys_tee sys_tee
309 common vmsplice sys_vmsplice sys_vmsplice
310 common move_pages sys_move_pages sys_move_pages
311 common getcpu sys_getcpu sys_getcpu
312 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait
313 common utimes sys_utimes sys_utimes_time32
314 common fallocate sys_fallocate compat_sys_s390_fallocate
315 common utimensat sys_utimensat sys_utimensat_time32
316 common signalfd sys_signalfd compat_sys_signalfd
317 common timerfd - -
318 common eventfd sys_eventfd sys_eventfd
319 common timerfd_create sys_timerfd_create sys_timerfd_create
320 common timerfd_settime sys_timerfd_settime sys_timerfd_settime32
321 common timerfd_gettime sys_timerfd_gettime sys_timerfd_gettime32
322 common signalfd4 sys_signalfd4 compat_sys_signalfd4
323 common eventfd2 sys_eventfd2 sys_eventfd2
324 common inotify_init1 sys_inotify_init1 sys_inotify_init1
325 common pipe2 sys_pipe2 sys_pipe2
326 common dup3 sys_dup3 sys_dup3
327 common epoll_create1 sys_epoll_create1 sys_epoll_create1
328 common preadv sys_preadv compat_sys_preadv
329 common pwritev sys_pwritev compat_sys_pwritev
330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
331 common perf_event_open sys_perf_event_open sys_perf_event_open
332 common fanotify_init sys_fanotify_init sys_fanotify_init
333 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark
334 common prlimit64 sys_prlimit64 sys_prlimit64
335 common name_to_handle_at sys_name_to_handle_at sys_name_to_handle_at
336 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at
337 common clock_adjtime sys_clock_adjtime sys_clock_adjtime32
338 common syncfs sys_syncfs sys_syncfs
339 common setns sys_setns sys_setns
340 common process_vm_readv sys_process_vm_readv sys_process_vm_readv
341 common process_vm_writev sys_process_vm_writev sys_process_vm_writev
342 common s390_runtime_instr sys_s390_runtime_instr sys_s390_runtime_instr
343 common kcmp sys_kcmp sys_kcmp
344 common finit_module sys_finit_module sys_finit_module
345 common sched_setattr sys_sched_setattr sys_sched_setattr
346 common sched_getattr sys_sched_getattr sys_sched_getattr
347 common renameat2 sys_renameat2 sys_renameat2
348 common seccomp sys_seccomp sys_seccomp
349 common getrandom sys_getrandom sys_getrandom
350 common memfd_create sys_memfd_create sys_memfd_create
351 common bpf sys_bpf sys_bpf
352 common s390_pci_mmio_write sys_s390_pci_mmio_write sys_s390_pci_mmio_write
353 common s390_pci_mmio_read sys_s390_pci_mmio_read sys_s390_pci_mmio_read
354 common execveat sys_execveat compat_sys_execveat
355 common userfaultfd sys_userfaultfd sys_userfaultfd
356 common membarrier sys_membarrier sys_membarrier
357 common recvmmsg sys_recvmmsg compat_sys_recvmmsg_time32
358 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
359 common socket sys_socket sys_socket
360 common socketpair sys_socketpair sys_socketpair
361 common bind sys_bind sys_bind
362 common connect sys_connect sys_connect
363 common listen sys_listen sys_listen
364 common accept4 sys_accept4 sys_accept4
365 common getsockopt sys_getsockopt sys_getsockopt
366 common setsockopt sys_setsockopt sys_setsockopt
367 common getsockname sys_getsockname sys_getsockname
368 common getpeername sys_getpeername sys_getpeername
369 common sendto sys_sendto sys_sendto
370 common sendmsg sys_sendmsg compat_sys_sendmsg
371 common recvfrom sys_recvfrom compat_sys_recvfrom
372 common recvmsg sys_recvmsg compat_sys_recvmsg
373 common shutdown sys_shutdown sys_shutdown
374 common mlock2 sys_mlock2 sys_mlock2
375 common copy_file_range sys_copy_file_range sys_copy_file_range
376 common preadv2 sys_preadv2 compat_sys_preadv2
377 common pwritev2 sys_pwritev2 compat_sys_pwritev2
378 common s390_guarded_storage sys_s390_guarded_storage sys_s390_guarded_storage
379 common statx sys_statx sys_statx
380 common s390_sthyi sys_s390_sthyi sys_s390_sthyi
381 common kexec_file_load sys_kexec_file_load sys_kexec_file_load
382 common io_pgetevents sys_io_pgetevents compat_sys_io_pgetevents
383 common rseq sys_rseq sys_rseq
384 common pkey_mprotect sys_pkey_mprotect sys_pkey_mprotect
385 common pkey_alloc sys_pkey_alloc sys_pkey_alloc
386 common pkey_free sys_pkey_free sys_pkey_free
1 common exit sys_exit
2 common fork sys_fork
3 common read sys_read
4 common write sys_write
5 common open sys_open
6 common close sys_close
7 common restart_syscall sys_restart_syscall
8 common creat sys_creat
9 common link sys_link
10 common unlink sys_unlink
11 common execve sys_execve
12 common chdir sys_chdir
14 common mknod sys_mknod
15 common chmod sys_chmod
19 common lseek sys_lseek
20 common getpid sys_getpid
21 common mount sys_mount
22 common umount sys_oldumount
26 common ptrace sys_ptrace
27 common alarm sys_alarm
29 common pause sys_pause
30 common utime sys_utime
33 common access sys_access
34 common nice sys_nice
36 common sync sys_sync
37 common kill sys_kill
38 common rename sys_rename
39 common mkdir sys_mkdir
40 common rmdir sys_rmdir
41 common dup sys_dup
42 common pipe sys_pipe
43 common times sys_times
45 common brk sys_brk
48 common signal sys_signal
51 common acct sys_acct
52 common umount2 sys_umount
54 common ioctl sys_ioctl
55 common fcntl sys_fcntl
57 common setpgid sys_setpgid
60 common umask sys_umask
61 common chroot sys_chroot
62 common ustat sys_ustat
63 common dup2 sys_dup2
64 common getppid sys_getppid
65 common getpgrp sys_getpgrp
66 common setsid sys_setsid
67 common sigaction sys_sigaction
72 common sigsuspend sys_sigsuspend
73 common sigpending sys_sigpending
74 common sethostname sys_sethostname
75 common setrlimit sys_setrlimit
77 common getrusage sys_getrusage
78 common gettimeofday sys_gettimeofday
79 common settimeofday sys_settimeofday
83 common symlink sys_symlink
85 common readlink sys_readlink
86 common uselib sys_uselib
87 common swapon sys_swapon
88 common reboot sys_reboot
89 common readdir sys_ni_syscall
90 common mmap sys_old_mmap
91 common munmap sys_munmap
92 common truncate sys_truncate
93 common ftruncate sys_ftruncate
94 common fchmod sys_fchmod
96 common getpriority sys_getpriority
97 common setpriority sys_setpriority
99 common statfs sys_statfs
100 common fstatfs sys_fstatfs
102 common socketcall sys_socketcall
103 common syslog sys_syslog
104 common setitimer sys_setitimer
105 common getitimer sys_getitimer
106 common stat sys_newstat
107 common lstat sys_newlstat
108 common fstat sys_newfstat
110 common lookup_dcookie sys_ni_syscall
111 common vhangup sys_vhangup
112 common idle sys_ni_syscall
114 common wait4 sys_wait4
115 common swapoff sys_swapoff
116 common sysinfo sys_sysinfo
117 common ipc sys_s390_ipc
118 common fsync sys_fsync
119 common sigreturn sys_sigreturn
120 common clone sys_clone
121 common setdomainname sys_setdomainname
122 common uname sys_newuname
124 common adjtimex sys_adjtimex
125 common mprotect sys_mprotect
126 common sigprocmask sys_sigprocmask
127 common create_module sys_ni_syscall
128 common init_module sys_init_module
129 common delete_module sys_delete_module
130 common get_kernel_syms sys_ni_syscall
131 common quotactl sys_quotactl
132 common getpgid sys_getpgid
133 common fchdir sys_fchdir
134 common bdflush sys_ni_syscall
135 common sysfs sys_sysfs
136 common personality sys_s390_personality
137 common afs_syscall sys_ni_syscall
141 common getdents sys_getdents
142 common select sys_select
143 common flock sys_flock
144 common msync sys_msync
145 common readv sys_readv
146 common writev sys_writev
147 common getsid sys_getsid
148 common fdatasync sys_fdatasync
149 common _sysctl sys_ni_syscall
150 common mlock sys_mlock
151 common munlock sys_munlock
152 common mlockall sys_mlockall
153 common munlockall sys_munlockall
154 common sched_setparam sys_sched_setparam
155 common sched_getparam sys_sched_getparam
156 common sched_setscheduler sys_sched_setscheduler
157 common sched_getscheduler sys_sched_getscheduler
158 common sched_yield sys_sched_yield
159 common sched_get_priority_max sys_sched_get_priority_max
160 common sched_get_priority_min sys_sched_get_priority_min
161 common sched_rr_get_interval sys_sched_rr_get_interval
162 common nanosleep sys_nanosleep
163 common mremap sys_mremap
167 common query_module sys_ni_syscall
168 common poll sys_poll
169 common nfsservctl sys_ni_syscall
172 common prctl sys_prctl
173 common rt_sigreturn sys_rt_sigreturn
174 common rt_sigaction sys_rt_sigaction
175 common rt_sigprocmask sys_rt_sigprocmask
176 common rt_sigpending sys_rt_sigpending
177 common rt_sigtimedwait sys_rt_sigtimedwait
178 common rt_sigqueueinfo sys_rt_sigqueueinfo
179 common rt_sigsuspend sys_rt_sigsuspend
180 common pread64 sys_pread64
181 common pwrite64 sys_pwrite64
183 common getcwd sys_getcwd
184 common capget sys_capget
185 common capset sys_capset
186 common sigaltstack sys_sigaltstack
187 common sendfile sys_sendfile64
188 common getpmsg sys_ni_syscall
189 common putpmsg sys_ni_syscall
190 common vfork sys_vfork
191 common getrlimit sys_getrlimit
198 common lchown sys_lchown
199 common getuid sys_getuid
200 common getgid sys_getgid
201 common geteuid sys_geteuid
202 common getegid sys_getegid
203 common setreuid sys_setreuid
204 common setregid sys_setregid
205 common getgroups sys_getgroups
206 common setgroups sys_setgroups
207 common fchown sys_fchown
208 common setresuid sys_setresuid
209 common getresuid sys_getresuid
210 common setresgid sys_setresgid
211 common getresgid sys_getresgid
212 common chown sys_chown
213 common setuid sys_setuid
214 common setgid sys_setgid
215 common setfsuid sys_setfsuid
216 common setfsgid sys_setfsgid
217 common pivot_root sys_pivot_root
218 common mincore sys_mincore
219 common madvise sys_madvise
220 common getdents64 sys_getdents64
222 common readahead sys_readahead
224 common setxattr sys_setxattr
225 common lsetxattr sys_lsetxattr
226 common fsetxattr sys_fsetxattr
227 common getxattr sys_getxattr
228 common lgetxattr sys_lgetxattr
229 common fgetxattr sys_fgetxattr
230 common listxattr sys_listxattr
231 common llistxattr sys_llistxattr
232 common flistxattr sys_flistxattr
233 common removexattr sys_removexattr
234 common lremovexattr sys_lremovexattr
235 common fremovexattr sys_fremovexattr
236 common gettid sys_gettid
237 common tkill sys_tkill
238 common futex sys_futex
239 common sched_setaffinity sys_sched_setaffinity
240 common sched_getaffinity sys_sched_getaffinity
241 common tgkill sys_tgkill
243 common io_setup sys_io_setup
244 common io_destroy sys_io_destroy
245 common io_getevents sys_io_getevents
246 common io_submit sys_io_submit
247 common io_cancel sys_io_cancel
248 common exit_group sys_exit_group
249 common epoll_create sys_epoll_create
250 common epoll_ctl sys_epoll_ctl
251 common epoll_wait sys_epoll_wait
252 common set_tid_address sys_set_tid_address
253 common fadvise64 sys_fadvise64_64
254 common timer_create sys_timer_create
255 common timer_settime sys_timer_settime
256 common timer_gettime sys_timer_gettime
257 common timer_getoverrun sys_timer_getoverrun
258 common timer_delete sys_timer_delete
259 common clock_settime sys_clock_settime
260 common clock_gettime sys_clock_gettime
261 common clock_getres sys_clock_getres
262 common clock_nanosleep sys_clock_nanosleep
265 common statfs64 sys_statfs64
266 common fstatfs64 sys_fstatfs64
267 common remap_file_pages sys_remap_file_pages
268 common mbind sys_mbind
269 common get_mempolicy sys_get_mempolicy
270 common set_mempolicy sys_set_mempolicy
271 common mq_open sys_mq_open
272 common mq_unlink sys_mq_unlink
273 common mq_timedsend sys_mq_timedsend
274 common mq_timedreceive sys_mq_timedreceive
275 common mq_notify sys_mq_notify
276 common mq_getsetattr sys_mq_getsetattr
277 common kexec_load sys_kexec_load
278 common add_key sys_add_key
279 common request_key sys_request_key
280 common keyctl sys_keyctl
281 common waitid sys_waitid
282 common ioprio_set sys_ioprio_set
283 common ioprio_get sys_ioprio_get
284 common inotify_init sys_inotify_init
285 common inotify_add_watch sys_inotify_add_watch
286 common inotify_rm_watch sys_inotify_rm_watch
287 common migrate_pages sys_migrate_pages
288 common openat sys_openat
289 common mkdirat sys_mkdirat
290 common mknodat sys_mknodat
291 common fchownat sys_fchownat
292 common futimesat sys_futimesat
293 common newfstatat sys_newfstatat
294 common unlinkat sys_unlinkat
295 common renameat sys_renameat
296 common linkat sys_linkat
297 common symlinkat sys_symlinkat
298 common readlinkat sys_readlinkat
299 common fchmodat sys_fchmodat
300 common faccessat sys_faccessat
301 common pselect6 sys_pselect6
302 common ppoll sys_ppoll
303 common unshare sys_unshare
304 common set_robust_list sys_set_robust_list
305 common get_robust_list sys_get_robust_list
306 common splice sys_splice
307 common sync_file_range sys_sync_file_range
308 common tee sys_tee
309 common vmsplice sys_vmsplice
310 common move_pages sys_move_pages
311 common getcpu sys_getcpu
312 common epoll_pwait sys_epoll_pwait
313 common utimes sys_utimes
314 common fallocate sys_fallocate
315 common utimensat sys_utimensat
316 common signalfd sys_signalfd
317 common timerfd sys_ni_syscall
318 common eventfd sys_eventfd
319 common timerfd_create sys_timerfd_create
320 common timerfd_settime sys_timerfd_settime
321 common timerfd_gettime sys_timerfd_gettime
322 common signalfd4 sys_signalfd4
323 common eventfd2 sys_eventfd2
324 common inotify_init1 sys_inotify_init1
325 common pipe2 sys_pipe2
326 common dup3 sys_dup3
327 common epoll_create1 sys_epoll_create1
328 common preadv sys_preadv
329 common pwritev sys_pwritev
330 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo
331 common perf_event_open sys_perf_event_open
332 common fanotify_init sys_fanotify_init
333 common fanotify_mark sys_fanotify_mark
334 common prlimit64 sys_prlimit64
335 common name_to_handle_at sys_name_to_handle_at
336 common open_by_handle_at sys_open_by_handle_at
337 common clock_adjtime sys_clock_adjtime
338 common syncfs sys_syncfs
339 common setns sys_setns
340 common process_vm_readv sys_process_vm_readv
341 common process_vm_writev sys_process_vm_writev
342 common s390_runtime_instr sys_s390_runtime_instr
343 common kcmp sys_kcmp
344 common finit_module sys_finit_module
345 common sched_setattr sys_sched_setattr
346 common sched_getattr sys_sched_getattr
347 common renameat2 sys_renameat2
348 common seccomp sys_seccomp
349 common getrandom sys_getrandom
350 common memfd_create sys_memfd_create
351 common bpf sys_bpf
352 common s390_pci_mmio_write sys_s390_pci_mmio_write
353 common s390_pci_mmio_read sys_s390_pci_mmio_read
354 common execveat sys_execveat
355 common userfaultfd sys_userfaultfd
356 common membarrier sys_membarrier
357 common recvmmsg sys_recvmmsg
358 common sendmmsg sys_sendmmsg
359 common socket sys_socket
360 common socketpair sys_socketpair
361 common bind sys_bind
362 common connect sys_connect
363 common listen sys_listen
364 common accept4 sys_accept4
365 common getsockopt sys_getsockopt
366 common setsockopt sys_setsockopt
367 common getsockname sys_getsockname
368 common getpeername sys_getpeername
369 common sendto sys_sendto
370 common sendmsg sys_sendmsg
371 common recvfrom sys_recvfrom
372 common recvmsg sys_recvmsg
373 common shutdown sys_shutdown
374 common mlock2 sys_mlock2
375 common copy_file_range sys_copy_file_range
376 common preadv2 sys_preadv2
377 common pwritev2 sys_pwritev2
378 common s390_guarded_storage sys_s390_guarded_storage
379 common statx sys_statx
380 common s390_sthyi sys_s390_sthyi
381 common kexec_file_load sys_kexec_file_load
382 common io_pgetevents sys_io_pgetevents
383 common rseq sys_rseq
384 common pkey_mprotect sys_pkey_mprotect
385 common pkey_alloc sys_pkey_alloc
386 common pkey_free sys_pkey_free
# room for arch specific syscalls
392 64 semtimedop sys_semtimedop -
393 common semget sys_semget sys_semget
394 common semctl sys_semctl compat_sys_semctl
395 common shmget sys_shmget sys_shmget
396 common shmctl sys_shmctl compat_sys_shmctl
397 common shmat sys_shmat compat_sys_shmat
398 common shmdt sys_shmdt sys_shmdt
399 common msgget sys_msgget sys_msgget
400 common msgsnd sys_msgsnd compat_sys_msgsnd
401 common msgrcv sys_msgrcv compat_sys_msgrcv
402 common msgctl sys_msgctl compat_sys_msgctl
403 32 clock_gettime64 - sys_clock_gettime
404 32 clock_settime64 - sys_clock_settime
405 32 clock_adjtime64 - sys_clock_adjtime
406 32 clock_getres_time64 - sys_clock_getres
407 32 clock_nanosleep_time64 - sys_clock_nanosleep
408 32 timer_gettime64 - sys_timer_gettime
409 32 timer_settime64 - sys_timer_settime
410 32 timerfd_gettime64 - sys_timerfd_gettime
411 32 timerfd_settime64 - sys_timerfd_settime
412 32 utimensat_time64 - sys_utimensat
413 32 pselect6_time64 - compat_sys_pselect6_time64
414 32 ppoll_time64 - compat_sys_ppoll_time64
416 32 io_pgetevents_time64 - compat_sys_io_pgetevents_time64
417 32 recvmmsg_time64 - compat_sys_recvmmsg_time64
418 32 mq_timedsend_time64 - sys_mq_timedsend
419 32 mq_timedreceive_time64 - sys_mq_timedreceive
420 32 semtimedop_time64 - sys_semtimedop
421 32 rt_sigtimedwait_time64 - compat_sys_rt_sigtimedwait_time64
422 32 futex_time64 - sys_futex
423 32 sched_rr_get_interval_time64 - sys_sched_rr_get_interval
424 common pidfd_send_signal sys_pidfd_send_signal sys_pidfd_send_signal
425 common io_uring_setup sys_io_uring_setup sys_io_uring_setup
426 common io_uring_enter sys_io_uring_enter sys_io_uring_enter
427 common io_uring_register sys_io_uring_register sys_io_uring_register
428 common open_tree sys_open_tree sys_open_tree
429 common move_mount sys_move_mount sys_move_mount
430 common fsopen sys_fsopen sys_fsopen
431 common fsconfig sys_fsconfig sys_fsconfig
432 common fsmount sys_fsmount sys_fsmount
433 common fspick sys_fspick sys_fspick
434 common pidfd_open sys_pidfd_open sys_pidfd_open
435 common clone3 sys_clone3 sys_clone3
436 common close_range sys_close_range sys_close_range
437 common openat2 sys_openat2 sys_openat2
438 common pidfd_getfd sys_pidfd_getfd sys_pidfd_getfd
439 common faccessat2 sys_faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2 compat_sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr sys_mount_setattr
443 common quotactl_fd sys_quotactl_fd sys_quotactl_fd
444 common landlock_create_ruleset sys_landlock_create_ruleset sys_landlock_create_ruleset
445 common landlock_add_rule sys_landlock_add_rule sys_landlock_add_rule
446 common landlock_restrict_self sys_landlock_restrict_self sys_landlock_restrict_self
447 common memfd_secret sys_memfd_secret sys_memfd_secret
448 common process_mrelease sys_process_mrelease sys_process_mrelease
449 common futex_waitv sys_futex_waitv sys_futex_waitv
450 common set_mempolicy_home_node sys_set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2 sys_fchmodat2
453 common map_shadow_stack sys_map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue sys_futex_requeue
457 common statmount sys_statmount sys_statmount
458 common listmount sys_listmount sys_listmount
459 common lsm_get_self_attr sys_lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal sys_mseal
463 common setxattrat sys_setxattrat sys_setxattrat
464 common getxattrat sys_getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr sys_file_setattr
470 common listns sys_listns sys_listns
392 common semtimedop sys_semtimedop
393 common semget sys_semget
394 common semctl sys_semctl
395 common shmget sys_shmget
396 common shmctl sys_shmctl
397 common shmat sys_shmat
398 common shmdt sys_shmdt
399 common msgget sys_msgget
400 common msgsnd sys_msgsnd
401 common msgrcv sys_msgrcv
402 common msgctl sys_msgctl
424 common pidfd_send_signal sys_pidfd_send_signal
425 common io_uring_setup sys_io_uring_setup
426 common io_uring_enter sys_io_uring_enter
427 common io_uring_register sys_io_uring_register
428 common open_tree sys_open_tree
429 common move_mount sys_move_mount
430 common fsopen sys_fsopen
431 common fsconfig sys_fsconfig
432 common fsmount sys_fsmount
433 common fspick sys_fspick
434 common pidfd_open sys_pidfd_open
435 common clone3 sys_clone3
436 common close_range sys_close_range
437 common openat2 sys_openat2
438 common pidfd_getfd sys_pidfd_getfd
439 common faccessat2 sys_faccessat2
440 common process_madvise sys_process_madvise
441 common epoll_pwait2 sys_epoll_pwait2
442 common mount_setattr sys_mount_setattr
443 common quotactl_fd sys_quotactl_fd
444 common landlock_create_ruleset sys_landlock_create_ruleset
445 common landlock_add_rule sys_landlock_add_rule
446 common landlock_restrict_self sys_landlock_restrict_self
447 common memfd_secret sys_memfd_secret
448 common process_mrelease sys_process_mrelease
449 common futex_waitv sys_futex_waitv
450 common set_mempolicy_home_node sys_set_mempolicy_home_node
451 common cachestat sys_cachestat
452 common fchmodat2 sys_fchmodat2
453 common map_shadow_stack sys_map_shadow_stack
454 common futex_wake sys_futex_wake
455 common futex_wait sys_futex_wait
456 common futex_requeue sys_futex_requeue
457 common statmount sys_statmount
458 common listmount sys_listmount
459 common lsm_get_self_attr sys_lsm_get_self_attr
460 common lsm_set_self_attr sys_lsm_set_self_attr
461 common lsm_list_modules sys_lsm_list_modules
462 common mseal sys_mseal
463 common setxattrat sys_setxattrat
464 common getxattrat sys_getxattrat
465 common listxattrat sys_listxattrat
466 common removexattrat sys_removexattrat
467 common open_tree_attr sys_open_tree_attr
468 common file_getattr sys_file_getattr
469 common file_setattr sys_file_setattr
470 common listns sys_listns

View File

@ -1,232 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# Generate system call table and header files
#
# Copyright IBM Corp. 2018
# Author(s): Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
#
# File path to the system call table definition.
# You can set the path with the -i option. If omitted,
# system call table definitions are read from standard input.
#
SYSCALL_TBL=""
create_syscall_table_entries()
{
local nr abi name entry64 entry32 _ignore
local temp=$(mktemp ${TMPDIR:-/tmp}/syscalltbl-common.XXXXXXXXX)
(
#
# Initialize with 0 to create an NI_SYSCALL for 0
#
local prev_nr=0 prev_32=sys_ni_syscall prev_64=sys_ni_syscall
while read nr abi name entry64 entry32 _ignore; do
test x$entry32 = x- && entry32=sys_ni_syscall
test x$entry64 = x- && entry64=sys_ni_syscall
if test $prev_nr -eq $nr; then
#
# Same syscall but different ABI, just update
# the respective entry point
#
case $abi in
32)
prev_32=$entry32
;;
64)
prev_64=$entry64
;;
esac
continue;
else
printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32
fi
prev_nr=$nr
prev_64=$entry64
prev_32=$entry32
done
printf "%d\t%s\t%s\n" $prev_nr $prev_64 $prev_32
) >> $temp
#
# Check for duplicate syscall numbers
#
if ! cat $temp |cut -f1 |uniq -d 2>&1; then
echo "Error: generated system call table contains duplicate entries: $temp" >&2
exit 1
fi
#
# Generate syscall table
#
prev_nr=0
while read nr entry64 entry32; do
while test $prev_nr -lt $((nr - 1)); do
printf "NI_SYSCALL\n"
prev_nr=$((prev_nr + 1))
done
if test x$entry64 = xsys_ni_syscall &&
test x$entry32 = xsys_ni_syscall; then
printf "NI_SYSCALL\n"
else
printf "SYSCALL(%s,%s)\n" $entry64 $entry32
fi
prev_nr=$nr
done < $temp
rm $temp
}
generate_syscall_table()
{
cat <<-EoHEADER
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Definitions for sys_call_table, each line represents an
* entry in the table in the form
* SYSCALL(64 bit syscall, 31 bit emulated syscall)
*
* This file is meant to be included from entry.S.
*/
#define NI_SYSCALL SYSCALL(sys_ni_syscall,sys_ni_syscall)
EoHEADER
grep -Ev '^(#|[[:blank:]]*$)' $SYSCALL_TBL \
|sort -k1 -n \
|create_syscall_table_entries
}
create_header_defines()
{
local nr abi name _ignore
while read nr abi name _ignore; do
printf "#define __NR_%s %d\n" $name $nr
done
}
normalize_fileguard()
{
local fileguard="$1"
echo "$1" |tr '[[:lower:]]' '[[:upper:]]' \
|sed -e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'
}
generate_syscall_header()
{
local abis=$(echo "($1)" | tr ',' '|')
local filename="$2"
local fileguard suffix
if test "$filename"; then
fileguard=$(normalize_fileguard "__UAPI_ASM_S390_$2")
else
case "$abis" in
*64*) suffix=64 ;;
*32*) suffix=32 ;;
esac
fileguard=$(normalize_fileguard "__UAPI_ASM_S390_SYSCALLS_$suffix")
fi
cat <<-EoHEADER
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef ${fileguard}
#define ${fileguard}
EoHEADER
grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL \
|sort -k1 -n \
|create_header_defines
cat <<-EoFOOTER
#endif /* ${fileguard} */
EoFOOTER
}
__max_syscall_nr()
{
local abis=$(echo "($1)" | tr ',' '|')
grep -E "^[[:digit:]]+[[:space:]]+${abis}" $SYSCALL_TBL \
|sed -ne 's/^\([[:digit:]]*\)[[:space:]].*/\1/p' \
|sort -n \
|tail -1
}
generate_syscall_nr()
{
local abis="$1"
local max_syscall_nr num_syscalls
max_syscall_nr=$(__max_syscall_nr "$abis")
num_syscalls=$((max_syscall_nr + 1))
cat <<-EoHEADER
/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
#ifndef __ASM_S390_SYSCALLS_NR
#define __ASM_S390_SYSCALLS_NR
#define NR_syscalls ${num_syscalls}
#endif /* __ASM_S390_SYSCALLS_NR */
EoHEADER
}
#
# Parse command line arguments
#
do_syscall_header=""
do_syscall_table=""
do_syscall_nr=""
output_file=""
abi_list="common,64"
filename=""
while getopts ":HNSXi:a:f:" arg; do
case $arg in
a)
abi_list="$OPTARG"
;;
i)
SYSCALL_TBL="$OPTARG"
;;
f)
filename=${OPTARG##*/}
;;
H)
do_syscall_header=1
;;
N)
do_syscall_nr=1
;;
S)
do_syscall_table=1
;;
X)
set -x
;;
:)
echo "Missing argument for -$OPTARG" >&2
exit 1
;;
\?)
echo "Invalid option specified" >&2
exit 1
;;
esac
done
test "$do_syscall_header" && generate_syscall_header "$abi_list" "$filename"
test "$do_syscall_table" && generate_syscall_table
test "$do_syscall_nr" && generate_syscall_nr "$abi_list"
exit 0

View File

@ -526,7 +526,7 @@ static __init int stsi_init_debugfs(void)
if (IS_ENABLED(CONFIG_SCHED_TOPOLOGY) && cpu_has_topology()) {
char link_to[10];
sprintf(link_to, "15_1_%d", topology_mnest_limit());
snprintf(link_to, sizeof(link_to), "15_1_%d", topology_mnest_limit());
debugfs_create_symlink("topology", stsi_root, link_to);
}
return 0;

View File

@ -12,8 +12,7 @@
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*/
#define KMSG_COMPONENT "time"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "time: " fmt
#include <linux/kernel_stat.h>
#include <linux/errno.h>

View File

@ -3,8 +3,7 @@
* Copyright IBM Corp. 2007, 2011
*/
#define KMSG_COMPONENT "cpu"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "cpu: " fmt
#include <linux/cpufeature.h>
#include <linux/workqueue.h>

View File

@ -8,7 +8,6 @@
#include <linux/uaccess.h>
#include <linux/uprobes.h>
#include <linux/compat.h>
#include <linux/kdebug.h>
#include <linux/sched/task_stack.h>
@ -29,7 +28,7 @@ int arch_uprobe_pre_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
{
if (psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT)
return -EINVAL;
if (!is_compat_task() && psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT)
if (psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT)
return -EINVAL;
clear_thread_flag(TIF_PER_TRAP);
auprobe->saved_per = psw_bits(regs->psw).per;
@ -161,11 +160,6 @@ bool arch_uretprobe_is_alive(struct return_instance *ret, enum rp_check ctx,
/* Instruction Emulation */
static void adjust_psw_addr(psw_t *psw, unsigned long len)
{
psw->addr = __rewind_psw(*psw, -len);
}
#define EMU_ILLEGAL_OP 1
#define EMU_SPECIFICATION 2
#define EMU_ADDRESSING 3
@ -353,7 +347,7 @@ static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs)
}
break;
}
adjust_psw_addr(&regs->psw, ilen);
regs->psw.addr = __forward_psw(regs->psw, ilen);
switch (rc) {
case EMU_ILLEGAL_OP:
regs->int_code = ilen << 16 | 0x0001;
@ -373,8 +367,7 @@ static void handle_insn_ril(struct arch_uprobe *auprobe, struct pt_regs *regs)
bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs)
{
if ((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_24BIT) ||
((psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT) &&
!is_compat_task())) {
(psw_bits(regs->psw).eaba == PSW_BITS_AMODE_31BIT)) {
regs->psw.addr = __rewind_psw(regs->psw, UPROBE_SWBP_INSN_SIZE);
do_report_trap(regs, SIGILL, ILL_ILLADR, NULL);
return true;

View File

@ -4,8 +4,7 @@
*
* Copyright IBM Corp. 2019, 2024
*/
#define KMSG_COMPONENT "prot_virt"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
#define pr_fmt(fmt) "prot_virt: " fmt
#include <linux/export.h>
#include <linux/kernel.h>

Some files were not shown because too many files have changed in this diff Show More