summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-02-09 20:17:03 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2026-02-09 20:17:03 -0800
commitc48953d81972bfe16a9e3551883992aa6efe541a (patch)
treef59a8a296e4b5e6239267465a46c83bfbbf22346
parent861ea34546dcde8600878d5e7f746795f22fc818 (diff)
parent5ae76830c76cf38708399245606e4e07a33fe51c (diff)
downloadlinux-c48953d81972bfe16a9e3551883992aa6efe541a.tar.gz
linux-c48953d81972bfe16a9e3551883992aa6efe541a.tar.bz2
linux-c48953d81972bfe16a9e3551883992aa6efe541a.zip
Merge tag 's390-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Heiko Carstens: - Drop support for outdated 3590/3592 and 3480 tape devices, and limit support to virtualized 3490E types devices - Implement exception based WARN() and WARN_ONCE() similar to x86 - Slightly optimize preempt primitives like __preempt_count_add() and __preempt_count_dec_and_test() - A couple of small fixes and improvements * tag 's390-7.0-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (35 commits) s390/tape: Consolidate tape config options and modules s390/cio: Fix device lifecycle handling in css_alloc_subchannel() s390/tape: Rename tape_34xx.c to tape_3490.c s390/tape: Cleanup sense data analysis and error handling s390/tape: Remove 3480 tape device type s390/tape: Remove unused command definitions s390/tape: Remove special block id handling s390/tape: Remove tape load display support s390/tape: Remove support for 3590/3592 models s390/kexec: Emit an error message when cmdline is too long s390/configs: Enable BLK_DEV_NULL_BLK as module s390: Document s390 stackprotector support s390/perf: Disable register readout on sampling events s390/Kconfig: Define non-zero ILLEGAL_POINTER_VALUE s390/bug: Prevent tail-call optimization s390/bug: Skip __WARN_trap() in call traces s390/bug: Implement WARN_ONCE() s390/bug: Implement __WARN_printf() s390/traps: Copy monitor code to pt_regs s390/bug: Introduce and use monitor code macro ...
-rw-r--r--Documentation/arch/s390/mm.rst4
-rw-r--r--Documentation/features/debug/stackprotector/arch-support.txt2
-rw-r--r--arch/s390/Kconfig19
-rw-r--r--arch/s390/boot/Makefile1
-rw-r--r--arch/s390/boot/startup.c1
-rw-r--r--arch/s390/configs/debug_defconfig1
-rw-r--r--arch/s390/configs/defconfig1
-rw-r--r--arch/s390/include/asm/ap.h2
-rw-r--r--arch/s390/include/asm/asm-prototypes.h1
-rw-r--r--arch/s390/include/asm/asm.h2
-rw-r--r--arch/s390/include/asm/bug.h141
-rw-r--r--arch/s390/include/asm/pci_io.h1
-rw-r--r--arch/s390/include/asm/preempt.h47
-rw-r--r--arch/s390/include/asm/ptrace.h42
-rw-r--r--arch/s390/include/uapi/asm/tape390.h103
-rw-r--r--arch/s390/kernel/entry.S11
-rw-r--r--arch/s390/kernel/machine_kexec_file.c4
-rw-r--r--arch/s390/kernel/perf_cpum_sf.c2
-rw-r--r--arch/s390/kernel/traps.c46
-rw-r--r--arch/s390/pci/pci.c35
-rw-r--r--arch/s390/purgatory/Makefile1
-rw-r--r--drivers/s390/char/Kconfig33
-rw-r--r--drivers/s390/char/Makefile6
-rw-r--r--drivers/s390/char/tape.h13
-rw-r--r--drivers/s390/char/tape_3490.c825
-rw-r--r--drivers/s390/char/tape_34xx.c1204
-rw-r--r--drivers/s390/char/tape_3590.c1612
-rw-r--r--drivers/s390/char/tape_3590.h175
-rw-r--r--drivers/s390/char/tape_char.c5
-rw-r--r--drivers/s390/char/tape_class.c15
-rw-r--r--drivers/s390/char/tape_class.h2
-rw-r--r--drivers/s390/char/tape_core.c14
-rw-r--r--drivers/s390/char/tape_std.c32
-rw-r--r--drivers/s390/char/tape_std.h45
-rw-r--r--drivers/s390/cio/css.c2
-rw-r--r--drivers/s390/crypto/ap_bus.c12
-rw-r--r--drivers/s390/crypto/zcrypt_api.c2
37 files changed, 1156 insertions, 3308 deletions
diff --git a/Documentation/arch/s390/mm.rst b/Documentation/arch/s390/mm.rst
index 084adad5eef9..19681157c6f2 100644
--- a/Documentation/arch/s390/mm.rst
+++ b/Documentation/arch/s390/mm.rst
@@ -109,3 +109,7 @@ Virtual memory layout
| KASAN shadow | KASAN untracked
| |
+------------------+ ASCE limit
+ | |
+ | CONFIG_ILLEGAL_POINTER_VALUE causes memory access fault
+ | |
+ +------------------+
diff --git a/Documentation/features/debug/stackprotector/arch-support.txt b/Documentation/features/debug/stackprotector/arch-support.txt
index de8f43f2e5d6..43e49c71612e 100644
--- a/Documentation/features/debug/stackprotector/arch-support.txt
+++ b/Documentation/features/debug/stackprotector/arch-support.txt
@@ -21,7 +21,7 @@
| parisc: | TODO |
| powerpc: | ok |
| riscv: | ok |
- | s390: | TODO |
+ | s390: | ok |
| sh: | ok |
| sparc: | TODO |
| um: | TODO |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 0e5fad5f06ca..cda697a03abf 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -69,6 +69,12 @@ 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_ASM_IMMEDIATE_STRINGS
+ def_bool !(CC_IS_GCC && GCC_VERSION < 90000)
+ help
+ GCC versions before 9.0.0 cannot handle strings as immediate
+ input operands in inline assemblies.
+
config CC_HAS_STACKPROTECTOR_GLOBAL
def_bool $(cc-option, -mstack-protector-guard=global -mstack-protector-guard-record)
@@ -85,6 +91,7 @@ config S390
select ARCH_ENABLE_MEMORY_HOTREMOVE
select ARCH_ENABLE_SPLIT_PMD_PTLOCK if PGTABLE_LEVELS > 2
select ARCH_ENABLE_THP_MIGRATION if TRANSPARENT_HUGEPAGE
+ select ARCH_HAS_CC_CAN_LINK
select ARCH_HAS_CPU_FINALIZE_INIT
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_DEBUG_VIRTUAL
@@ -294,6 +301,14 @@ config PGTABLE_LEVELS
source "kernel/livepatch/Kconfig"
+config ARCH_CC_CAN_LINK
+ bool
+ default $(cc_can_link_user,-m64)
+
+config ARCH_USERFLAGS
+ string
+ default "-m64"
+
config ARCH_SUPPORTS_KEXEC
def_bool y
@@ -704,6 +719,10 @@ config ARCH_SPARSEMEM_ENABLE
config ARCH_SPARSEMEM_DEFAULT
def_bool y
+config ILLEGAL_POINTER_VALUE
+ hex
+ default 0xdead000000000000
+
config MAX_PHYSMEM_BITS
int "Maximum size of supported physical memory in bits (42-53)"
range 42 53
diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index 490167faba7a..a1e719a79d38 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -21,6 +21,7 @@ KBUILD_AFLAGS := $(filter-out $(CC_FLAGS_MARCH),$(KBUILD_AFLAGS_DECOMPRESSOR))
KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_MARCH),$(KBUILD_CFLAGS_DECOMPRESSOR))
KBUILD_AFLAGS += $(CC_FLAGS_MARCH_MINIMUM) -D__DISABLE_EXPORTS
KBUILD_CFLAGS += $(CC_FLAGS_MARCH_MINIMUM) -D__DISABLE_EXPORTS
+KBUILD_CFLAGS += $(call cc-option, -Wno-default-const-init-unsafe)
CFLAGS_sclp_early_core.o += -I$(srctree)/drivers/s390/char
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index f77067dfc2a8..7f3343493ab9 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -336,6 +336,7 @@ static unsigned long setup_kernel_memory_layout(unsigned long kernel_size)
BUILD_BUG_ON(!IS_ALIGNED(TEXT_OFFSET, THREAD_SIZE));
BUILD_BUG_ON(!IS_ALIGNED(__NO_KASLR_START_KERNEL, THREAD_SIZE));
BUILD_BUG_ON(__NO_KASLR_END_KERNEL > _REGION1_SIZE);
+ BUILD_BUG_ON(CONFIG_ILLEGAL_POINTER_VALUE < _REGION1_SIZE);
vsize = get_vmem_size(ident_map_size, vmemmap_size, vmalloc_size, _REGION3_SIZE);
boot_debug("vmem size estimated: 0x%016lx\n", vsize);
if (IS_ENABLED(CONFIG_KASAN) || __NO_KASLR_END_KERNEL > _REGION2_SIZE ||
diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig
index 0713914b25b4..7a91d300c549 100644
--- a/arch/s390/configs/debug_defconfig
+++ b/arch/s390/configs/debug_defconfig
@@ -446,6 +446,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_RBD=m
CONFIG_BLK_DEV_NVME=m
+CONFIG_BLK_DEV_NULL_BLK=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_GENWQE=m
CONFIG_RAID_ATTRS=m
diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig
index c064e0cacc98..3bb2aa8ecd13 100644
--- a/arch/s390/configs/defconfig
+++ b/arch/s390/configs/defconfig
@@ -436,6 +436,7 @@ CONFIG_BLK_DEV_RAM_SIZE=32768
CONFIG_VIRTIO_BLK=y
CONFIG_BLK_DEV_RBD=m
CONFIG_BLK_DEV_NVME=m
+CONFIG_BLK_DEV_NULL_BLK=m
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_GENWQE=m
CONFIG_RAID_ATTRS=m
diff --git a/arch/s390/include/asm/ap.h b/arch/s390/include/asm/ap.h
index b24459f692fa..3b95c6531a67 100644
--- a/arch/s390/include/asm/ap.h
+++ b/arch/s390/include/asm/ap.h
@@ -78,7 +78,7 @@ union ap_queue_status_reg {
};
/**
- * ap_intructions_available() - Test if AP instructions are available.
+ * ap_instructions_available() - Test if AP instructions are available.
*
* Returns true if the AP instructions are installed, otherwise false.
*/
diff --git a/arch/s390/include/asm/asm-prototypes.h b/arch/s390/include/asm/asm-prototypes.h
index f662eb4b9246..7bd1801cf241 100644
--- a/arch/s390/include/asm/asm-prototypes.h
+++ b/arch/s390/include/asm/asm-prototypes.h
@@ -3,6 +3,7 @@
#include <linux/kvm_host.h>
#include <linux/ftrace.h>
+#include <asm/bug.h>
#include <asm/fpu.h>
#include <asm/nospec-branch.h>
#include <asm-generic/asm-prototypes.h>
diff --git a/arch/s390/include/asm/asm.h b/arch/s390/include/asm/asm.h
index e9062b01e2a2..510901c2a5f9 100644
--- a/arch/s390/include/asm/asm.h
+++ b/arch/s390/include/asm/asm.h
@@ -30,7 +30,7 @@
*/
#if defined(__GCC_ASM_FLAG_OUTPUTS__) && !(IS_ENABLED(CONFIG_CC_ASM_FLAG_OUTPUT_BROKEN))
-#define __HAVE_ASM_FLAG_OUTPUTS__
+#define __HAVE_ASM_FLAG_OUTPUTS__ 1
#define CC_IPM(sym)
#define CC_OUT(sym, var) "=@cc" (var)
diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h
index ee9221bb5d18..59017fd3d935 100644
--- a/arch/s390/include/asm/bug.h
+++ b/arch/s390/include/asm/bug.h
@@ -2,60 +2,127 @@
#ifndef _ASM_S390_BUG_H
#define _ASM_S390_BUG_H
-#include <linux/stringify.h>
+#include <linux/compiler.h>
+#include <linux/const.h>
-#ifdef CONFIG_BUG
+#define MONCODE_BUG _AC(0, U)
+#define MONCODE_BUG_ARG _AC(1, U)
-#ifndef CONFIG_DEBUG_BUGVERBOSE
-#define _BUGVERBOSE_LOCATION(file, line)
+#ifndef __ASSEMBLER__
+#if defined(CONFIG_BUG) && defined(CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS)
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#define __BUG_ENTRY_VERBOSE(format, file, line) \
+ " .long " format " - . # bug_entry::format\n" \
+ " .long " file " - . # bug_entry::file\n" \
+ " .short " line " # bug_entry::line\n"
#else
-#define __BUGVERBOSE_LOCATION(file, line) \
- .pushsection .rodata.str, "aMS", @progbits, 1; \
- .align 2; \
- 10002: .ascii file "\0"; \
- .popsection; \
- \
- .long 10002b - .; \
- .short line;
-#define _BUGVERBOSE_LOCATION(file, line) __BUGVERBOSE_LOCATION(file, line)
+#define __BUG_ENTRY_VERBOSE(format, file, line)
#endif
-#ifndef CONFIG_GENERIC_BUG
-#define __BUG_ENTRY(cond_str, flags)
+#ifdef CONFIG_DEBUG_BUGVERBOSE_DETAILED
+#define WARN_CONDITION_STR(cond_str) cond_str
#else
-#define __BUG_ENTRY(cond_str, flags) \
- .pushsection __bug_table, "aw"; \
- .align 4; \
- 10000: .long 10001f - .; \
- _BUGVERBOSE_LOCATION(WARN_CONDITION_STR(cond_str) __FILE__, __LINE__) \
- .short flags; \
- .popsection; \
- 10001:
+#define WARN_CONDITION_STR(cond_str) ""
#endif
-#define ASM_BUG_FLAGS(cond_str, flags) \
- __BUG_ENTRY(cond_str, flags) \
- mc 0,0
+#define __BUG_ENTRY(format, file, line, flags, size) \
+ " .section __bug_table,\"aw\"\n" \
+ "1: .long 0b - . # bug_entry::bug_addr\n" \
+ __BUG_ENTRY_VERBOSE(format, file, line) \
+ " .short "flags" # bug_entry::flags\n" \
+ " .org 1b+"size"\n" \
+ " .previous"
-#define ASM_BUG() ASM_BUG_FLAGS("", 0)
+#define __BUG_ASM(cond_str, flags) \
+do { \
+ asm_inline volatile("\n" \
+ "0: mc %[monc](%%r0),0\n" \
+ __BUG_ENTRY("%[frmt]", "%[file]", "%[line]", \
+ "%[flgs]", "%[size]") \
+ : \
+ : [monc] "i" (MONCODE_BUG), \
+ [frmt] "i" (WARN_CONDITION_STR(cond_str)), \
+ [file] "i" (__FILE__), \
+ [line] "i" (__LINE__), \
+ [flgs] "i" (flags), \
+ [size] "i" (sizeof(struct bug_entry))); \
+} while (0)
-#define __BUG_FLAGS(cond_str, flags) \
- asm_inline volatile(__stringify(ASM_BUG_FLAGS(cond_str, flags)));
+#define BUG() \
+do { \
+ __BUG_ASM("", 0); \
+ unreachable(); \
+} while (0)
-#define __WARN_FLAGS(cond_str, flags) \
-do { \
- __BUG_FLAGS(cond_str, BUGFLAG_WARNING|(flags)); \
+#define __WARN_FLAGS(cond_str, flags) \
+do { \
+ __BUG_ASM(cond_str, BUGFLAG_WARNING | (flags)); \
} while (0)
-#define BUG() \
-do { \
- __BUG_FLAGS("", 0); \
- unreachable(); \
+#define __WARN_bug_entry(flags, format) \
+({ \
+ struct bug_entry *bug; \
+ \
+ asm_inline volatile("\n" \
+ "0: larl %[bug],1f\n" \
+ __BUG_ENTRY("%[frmt]", "%[file]", "%[line]", \
+ "%[flgs]", "%[size]") \
+ : [bug] "=d" (bug) \
+ : [frmt] "i" (format), \
+ [file] "i" (__FILE__), \
+ [line] "i" (__LINE__), \
+ [flgs] "i" (flags), \
+ [size] "i" (sizeof(struct bug_entry))); \
+ bug; \
+})
+
+/*
+ * Variable Argument List (va_list) as defined in ELF Application
+ * Binary Interface s390x Supplement documentation.
+ */
+struct arch_va_list {
+ long __gpr;
+ long __fpr;
+ void *__overflow_arg_area;
+ void *__reg_save_area;
+};
+
+struct bug_entry;
+struct pt_regs;
+
+void *__warn_args(struct arch_va_list *args, struct pt_regs *regs);
+void __WARN_trap(struct bug_entry *bug, ...);
+
+#define __WARN_print_arg(flags, format, arg...) \
+do { \
+ int __flags = (flags) | BUGFLAG_WARNING | BUGFLAG_ARGS; \
+ \
+ __WARN_trap(__WARN_bug_entry(__flags, format), ## arg); \
+ /* prevent tail-call optimization */ \
+ asm(""); \
} while (0)
+#define __WARN_printf(taint, fmt, arg...) \
+ __WARN_print_arg(BUGFLAG_TAINT(taint), fmt, ## arg)
+
+#define WARN_ONCE(cond, format, arg...) \
+({ \
+ int __ret_warn_on = !!(cond); \
+ \
+ if (unlikely(__ret_warn_on)) { \
+ __WARN_print_arg(BUGFLAG_ONCE|BUGFLAG_TAINT(TAINT_WARN),\
+ format, ## arg); \
+ } \
+ __ret_warn_on; \
+})
+
#define HAVE_ARCH_BUG
+#define HAVE_ARCH_BUG_FORMAT
+#define HAVE_ARCH_BUG_FORMAT_ARGS
-#endif /* CONFIG_BUG */
+#endif /* CONFIG_BUG && CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS */
+#endif /* __ASSEMBLER__ */
#include <asm-generic/bug.h>
diff --git a/arch/s390/include/asm/pci_io.h b/arch/s390/include/asm/pci_io.h
index 43a5ea4ee20f..f3bef5bc7223 100644
--- a/arch/s390/include/asm/pci_io.h
+++ b/arch/s390/include/asm/pci_io.h
@@ -18,6 +18,7 @@
#define ZPCI_IOMAP_SHIFT 48
#define ZPCI_IOMAP_ADDR_SHIFT 62
#define ZPCI_IOMAP_ADDR_BASE (1UL << ZPCI_IOMAP_ADDR_SHIFT)
+#define ZPCI_IOMAP_ADDR_MAX ((1UL << (ZPCI_IOMAP_ADDR_SHIFT + 1)) - 1)
#define ZPCI_IOMAP_ADDR_OFF_MASK ((1UL << ZPCI_IOMAP_SHIFT) - 1)
#define ZPCI_IOMAP_MAX_ENTRIES \
(1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT))
diff --git a/arch/s390/include/asm/preempt.h b/arch/s390/include/asm/preempt.h
index 6ccd033acfe5..6e5821bb047e 100644
--- a/arch/s390/include/asm/preempt.h
+++ b/arch/s390/include/asm/preempt.h
@@ -8,7 +8,10 @@
#include <asm/cmpxchg.h>
#include <asm/march.h>
-/* We use the MSB mostly because its available */
+/*
+ * Use MSB so it is possible to read preempt_count with LLGT which
+ * reads the least significant 31 bits with a single instruction.
+ */
#define PREEMPT_NEED_RESCHED 0x80000000
/*
@@ -23,7 +26,20 @@
*/
static __always_inline int preempt_count(void)
{
- return READ_ONCE(get_lowcore()->preempt_count) & ~PREEMPT_NEED_RESCHED;
+ unsigned long lc_preempt, count;
+
+ BUILD_BUG_ON(sizeof_field(struct lowcore, preempt_count) != sizeof(int));
+ lc_preempt = offsetof(struct lowcore, preempt_count);
+ /* READ_ONCE(get_lowcore()->preempt_count) & ~PREEMPT_NEED_RESCHED */
+ asm_inline(
+ ALTERNATIVE("llgt %[count],%[offzero](%%r0)\n",
+ "llgt %[count],%[offalt](%%r0)\n",
+ ALT_FEATURE(MFEATURE_LOWCORE))
+ : [count] "=d" (count)
+ : [offzero] "i" (lc_preempt),
+ [offalt] "i" (lc_preempt + LOWCORE_ALT_ADDRESS),
+ "m" (((struct lowcore *)0)->preempt_count));
+ return count;
}
static __always_inline void preempt_count_set(int pc)
@@ -68,7 +84,17 @@ static __always_inline void __preempt_count_add(int val)
*/
if (!IS_ENABLED(CONFIG_PROFILE_ALL_BRANCHES)) {
if (__builtin_constant_p(val) && (val >= -128) && (val <= 127)) {
- __atomic_add_const(val, &get_lowcore()->preempt_count);
+ unsigned long lc_preempt;
+
+ lc_preempt = offsetof(struct lowcore, preempt_count);
+ asm_inline(
+ ALTERNATIVE("asi %[offzero](%%r0),%[val]\n",
+ "asi %[offalt](%%r0),%[val]\n",
+ ALT_FEATURE(MFEATURE_LOWCORE))
+ : "+m" (((struct lowcore *)0)->preempt_count)
+ : [offzero] "i" (lc_preempt), [val] "i" (val),
+ [offalt] "i" (lc_preempt + LOWCORE_ALT_ADDRESS)
+ : "cc");
return;
}
}
@@ -87,7 +113,22 @@ static __always_inline void __preempt_count_sub(int val)
*/
static __always_inline bool __preempt_count_dec_and_test(void)
{
+#ifdef __HAVE_ASM_FLAG_OUTPUTS__
+ unsigned long lc_preempt;
+ int cc;
+
+ lc_preempt = offsetof(struct lowcore, preempt_count);
+ asm_inline(
+ ALTERNATIVE("alsi %[offzero](%%r0),%[val]\n",
+ "alsi %[offalt](%%r0),%[val]\n",
+ ALT_FEATURE(MFEATURE_LOWCORE))
+ : "=@cc" (cc), "+m" (((struct lowcore *)0)->preempt_count)
+ : [offzero] "i" (lc_preempt), [val] "i" (-1),
+ [offalt] "i" (lc_preempt + LOWCORE_ALT_ADDRESS));
+ return (cc == 0) || (cc == 2);
+#else
return __atomic_add_const_and_test(-1, &get_lowcore()->preempt_count);
+#endif
}
/*
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h
index 962cf042c66d..aaceb1d9110a 100644
--- a/arch/s390/include/asm/ptrace.h
+++ b/arch/s390/include/asm/ptrace.h
@@ -120,7 +120,10 @@ struct pt_regs {
unsigned long gprs[NUM_GPRS];
};
};
- unsigned long orig_gpr2;
+ union {
+ unsigned long orig_gpr2;
+ unsigned long monitor_code;
+ };
union {
struct {
unsigned int int_code;
@@ -214,16 +217,23 @@ void update_cr_regs(struct task_struct *task);
#define arch_has_single_step() (1)
#define arch_has_block_step() (1)
-#define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0)
-#define instruction_pointer(regs) ((regs)->psw.addr)
-#define user_stack_pointer(regs)((regs)->gprs[15])
#define profile_pc(regs) instruction_pointer(regs)
-static inline long regs_return_value(struct pt_regs *regs)
+static __always_inline bool user_mode(const struct pt_regs *regs)
+{
+ return psw_bits(regs->psw).pstate;
+}
+
+static inline long regs_return_value(const struct pt_regs *regs)
{
return regs->gprs[2];
}
+static __always_inline unsigned long instruction_pointer(const struct pt_regs *regs)
+{
+ return regs->psw.addr;
+}
+
static inline void instruction_pointer_set(struct pt_regs *regs,
unsigned long val)
{
@@ -233,19 +243,26 @@ static inline void instruction_pointer_set(struct pt_regs *regs,
int regs_query_register_offset(const char *name);
const char *regs_query_register_name(unsigned int offset);
-static __always_inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
+static __always_inline unsigned long kernel_stack_pointer(const struct pt_regs *regs)
+{
+ return regs->gprs[15];
+}
+
+static __always_inline unsigned long user_stack_pointer(const struct pt_regs *regs)
{
return regs->gprs[15];
}
-static __always_inline unsigned long regs_get_register(struct pt_regs *regs, unsigned int offset)
+static __always_inline unsigned long regs_get_register(const struct pt_regs *regs,
+ unsigned int offset)
{
if (offset >= NUM_GPRS)
return 0;
return regs->gprs[offset];
}
-static __always_inline int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr)
+static __always_inline int regs_within_kernel_stack(const struct pt_regs *regs,
+ unsigned long addr)
{
unsigned long ksp = kernel_stack_pointer(regs);
@@ -261,7 +278,8 @@ static __always_inline int regs_within_kernel_stack(struct pt_regs *regs, unsign
* is specifined by @regs. If the @n th entry is NOT in the kernel stack,
* this returns 0.
*/
-static __always_inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n)
+static __always_inline unsigned long regs_get_kernel_stack_nth(const struct pt_regs *regs,
+ unsigned int n)
{
unsigned long addr;
@@ -278,8 +296,8 @@ static __always_inline unsigned long regs_get_kernel_stack_nth(struct pt_regs *r
*
* regs_get_kernel_argument() returns @n th argument of the function call.
*/
-static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
- unsigned int n)
+static __always_inline unsigned long regs_get_kernel_argument(const struct pt_regs *regs,
+ unsigned int n)
{
unsigned int argoffset = STACK_FRAME_OVERHEAD / sizeof(long);
@@ -290,7 +308,7 @@ static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs,
return regs_get_kernel_stack_nth(regs, argoffset + n);
}
-static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
+static __always_inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
{
regs->gprs[2] = rc;
}
diff --git a/arch/s390/include/uapi/asm/tape390.h b/arch/s390/include/uapi/asm/tape390.h
deleted file mode 100644
index 90266c696486..000000000000
--- a/arch/s390/include/uapi/asm/tape390.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
-/*************************************************************************
- *
- * enables user programs to display messages and control encryption
- * on s390 tape devices
- *
- * Copyright IBM Corp. 2001, 2006
- * Author(s): Michael Holzheu <holzheu@de.ibm.com>
- *
- *************************************************************************/
-
-#ifndef _TAPE390_H
-#define _TAPE390_H
-
-#define TAPE390_DISPLAY _IOW('d', 1, struct display_struct)
-
-/*
- * The TAPE390_DISPLAY ioctl calls the Load Display command
- * which transfers 17 bytes of data from the channel to the subsystem:
- * - 1 format control byte, and
- * - two 8-byte messages
- *
- * Format control byte:
- * 0-2: New Message Overlay
- * 3: Alternate Messages
- * 4: Blink Message
- * 5: Display Low/High Message
- * 6: Reserved
- * 7: Automatic Load Request
- *
- */
-
-typedef struct display_struct {
- char cntrl;
- char message1[8];
- char message2[8];
-} display_struct;
-
-/*
- * Tape encryption support
- */
-
-struct tape390_crypt_info {
- char capability;
- char status;
- char medium_status;
-} __attribute__ ((packed));
-
-
-/* Macros for "capable" field */
-#define TAPE390_CRYPT_SUPPORTED_MASK 0x01
-#define TAPE390_CRYPT_SUPPORTED(x) \
- ((x.capability & TAPE390_CRYPT_SUPPORTED_MASK))
-
-/* Macros for "status" field */
-#define TAPE390_CRYPT_ON_MASK 0x01
-#define TAPE390_CRYPT_ON(x) (((x.status) & TAPE390_CRYPT_ON_MASK))
-
-/* Macros for "medium status" field */
-#define TAPE390_MEDIUM_LOADED_MASK 0x01
-#define TAPE390_MEDIUM_ENCRYPTED_MASK 0x02
-#define TAPE390_MEDIUM_ENCRYPTED(x) \
- (((x.medium_status) & TAPE390_MEDIUM_ENCRYPTED_MASK))
-#define TAPE390_MEDIUM_LOADED(x) \
- (((x.medium_status) & TAPE390_MEDIUM_LOADED_MASK))
-
-/*
- * The TAPE390_CRYPT_SET ioctl is used to switch on/off encryption.
- * The "encryption_capable" and "tape_status" fields are ignored for this ioctl!
- */
-#define TAPE390_CRYPT_SET _IOW('d', 2, struct tape390_crypt_info)
-
-/*
- * The TAPE390_CRYPT_QUERY ioctl is used to query the encryption state.
- */
-#define TAPE390_CRYPT_QUERY _IOR('d', 3, struct tape390_crypt_info)
-
-/* Values for "kekl1/2_type" and "kekl1/2_type_on_tape" fields */
-#define TAPE390_KEKL_TYPE_NONE 0
-#define TAPE390_KEKL_TYPE_LABEL 1
-#define TAPE390_KEKL_TYPE_HASH 2
-
-struct tape390_kekl {
- unsigned char type;
- unsigned char type_on_tape;
- char label[65];
-} __attribute__ ((packed));
-
-struct tape390_kekl_pair {
- struct tape390_kekl kekl[2];
-} __attribute__ ((packed));
-
-/*
- * The TAPE390_KEKL_SET ioctl is used to set Key Encrypting Key labels.
- */
-#define TAPE390_KEKL_SET _IOW('d', 4, struct tape390_kekl_pair)
-
-/*
- * The TAPE390_KEKL_QUERY ioctl is used to query Key Encrypting Key labels.
- */
-#define TAPE390_KEKL_QUERY _IOR('d', 5, struct tape390_kekl_pair)
-
-#endif
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b7f1553d9ee5..4873fe9d891b 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -23,6 +23,7 @@
#include <asm/unistd.h>
#include <asm/page.h>
#include <asm/sigp.h>
+#include <asm/bug.h>
#include <asm/irq.h>
#include <asm/fpu-insn.h>
#include <asm/setup.h>
@@ -173,6 +174,16 @@ SYM_FUNC_START(__switch_to_asm)
BR_EX %r14
SYM_FUNC_END(__switch_to_asm)
+#if defined(CONFIG_BUG) && defined(CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS)
+
+SYM_FUNC_START(__WARN_trap)
+ mc MONCODE_BUG_ARG(%r0),0
+ BR_EX %r14
+SYM_FUNC_END(__WARN_trap)
+EXPORT_SYMBOL(__WARN_trap)
+
+#endif /* CONFIG_BUG && CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS */
+
#if IS_ENABLED(CONFIG_KVM)
/*
* __sie64a calling convention:
diff --git a/arch/s390/kernel/machine_kexec_file.c b/arch/s390/kernel/machine_kexec_file.c
index a36d7311c668..1bf59c3f0e2b 100644
--- a/arch/s390/kernel/machine_kexec_file.c
+++ b/