mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
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 ...
This commit is contained in:
@@ -109,3 +109,7 @@ Virtual memory layout
|
||||
| KASAN shadow | KASAN untracked
|
||||
| |
|
||||
+------------------+ ASCE limit
|
||||
| |
|
||||
| CONFIG_ILLEGAL_POINTER_VALUE causes memory access fault
|
||||
| |
|
||||
+------------------+
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
| parisc: | TODO |
|
||||
| powerpc: | ok |
|
||||
| riscv: | ok |
|
||||
| s390: | TODO |
|
||||
| s390: | ok |
|
||||
| sh: | ok |
|
||||
| sparc: | TODO |
|
||||
| um: | TODO |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 ||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
+106
-39
@@ -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_FLAGS(cond_str, flags) \
|
||||
asm_inline volatile(__stringify(ASM_BUG_FLAGS(cond_str, flags)));
|
||||
|
||||
#define __WARN_FLAGS(cond_str, flags) \
|
||||
do { \
|
||||
__BUG_FLAGS(cond_str, BUGFLAG_WARNING|(flags)); \
|
||||
#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() \
|
||||
do { \
|
||||
__BUG_FLAGS("", 0); \
|
||||
unreachable(); \
|
||||
#define BUG() \
|
||||
do { \
|
||||
__BUG_ASM("", 0); \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define __WARN_FLAGS(cond_str, flags) \
|
||||
do { \
|
||||
__BUG_ASM(cond_str, BUGFLAG_WARNING | (flags)); \
|
||||
} while (0)
|
||||
|
||||
#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>
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -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 regs_get_register(struct pt_regs *regs, unsigned int offset)
|
||||
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(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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -270,8 +270,10 @@ void *kexec_file_add_components(struct kimage *image,
|
||||
if (image->kernel_buf_len < minsize + max_command_line_size)
|
||||
goto out;
|
||||
|
||||
if (image->cmdline_buf_len >= max_command_line_size)
|
||||
if (image->cmdline_buf_len >= max_command_line_size) {
|
||||
pr_err("Kernel command line exceeds supported limit of %lu", max_command_line_size);
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(data.parm->command_line, image->cmdline_buf,
|
||||
image->cmdline_buf_len);
|
||||
|
||||
@@ -841,7 +841,7 @@ static bool is_callchain_event(struct perf_event *event)
|
||||
u64 sample_type = event->attr.sample_type;
|
||||
|
||||
return sample_type & (PERF_SAMPLE_CALLCHAIN | PERF_SAMPLE_REGS_USER |
|
||||
PERF_SAMPLE_STACK_USER);
|
||||
PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_STACK_USER);
|
||||
}
|
||||
|
||||
static int cpumsf_pmu_event_init(struct perf_event *event)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/entry-common.h>
|
||||
#include <linux/kmsan.h>
|
||||
#include <linux/bug.h>
|
||||
#include <asm/asm-extable.h>
|
||||
#include <asm/irqflags.h>
|
||||
#include <asm/ptrace.h>
|
||||
@@ -220,11 +221,48 @@ static void space_switch_exception(struct pt_regs *regs)
|
||||
do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BUG) && defined(CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS)
|
||||
|
||||
void *__warn_args(struct arch_va_list *args, struct pt_regs *regs)
|
||||
{
|
||||
struct stack_frame *stack_frame;
|
||||
|
||||
/*
|
||||
* Generate va_list from pt_regs. See ELF Application Binary Interface
|
||||
* s390x Supplement documentation for details.
|
||||
*
|
||||
* - __overflow_arg_area needs to point to the parameter area, which
|
||||
* is right above the standard stack frame (160 bytes)
|
||||
*
|
||||
* - __reg_save_area needs to point to a register save area where
|
||||
* general registers (%r2 - %r6) can be found at offset 16. Which
|
||||
* means that the gprs save area of pt_regs can be used
|
||||
*
|
||||
* - __gpr must be set to one, since the first parameter has been
|
||||
* processed (pointer to bug_entry)
|
||||
*/
|
||||
stack_frame = (struct stack_frame *)regs->gprs[15];
|
||||
args->__overflow_arg_area = stack_frame + 1;
|
||||
args->__reg_save_area = regs->gprs;
|
||||
args->__gpr = 1;
|
||||
return args;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BUG && CONFIG_CC_HAS_ASM_IMMEDIATE_STRINGS */
|
||||
|
||||
static void monitor_event_exception(struct pt_regs *regs)
|
||||
{
|
||||
enum bug_trap_type btt;
|
||||
|
||||
if (user_mode(regs))
|
||||
return;
|
||||
switch (report_bug(regs->psw.addr - (regs->int_code >> 16), regs)) {
|
||||
if (regs->monitor_code == MONCODE_BUG_ARG) {
|
||||
regs->psw.addr = regs->gprs[14];
|
||||
btt = report_bug_entry((struct bug_entry *)regs->gprs[2], regs);
|
||||
} else {
|
||||
btt = report_bug(regs->psw.addr - (regs->int_code >> 16), regs);
|
||||
}
|
||||
switch (btt) {
|
||||
case BUG_TRAP_TYPE_NONE:
|
||||
fixup_exception(regs);
|
||||
break;
|
||||
@@ -258,11 +296,12 @@ static void __init test_monitor_call(void)
|
||||
if (!IS_ENABLED(CONFIG_BUG))
|
||||
return;
|
||||
asm_inline volatile(
|
||||
" mc 0,0\n"
|
||||
" mc %[monc](%%r0),0\n"
|
||||
"0: lhi %[val],0\n"
|
||||
"1:\n"
|
||||
EX_TABLE(0b, 1b)
|
||||
: [val] "+d" (val));
|
||||
: [val] "+d" (val)
|
||||
: [monc] "i" (MONCODE_BUG));
|
||||
if (!val)
|
||||
panic("Monitor call doesn't work!\n");
|
||||
}
|
||||
@@ -297,6 +336,7 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
|
||||
teid.val = lc->trans_exc_code;
|
||||
regs->int_code = lc->pgm_int_code;
|
||||
regs->int_parm_long = teid.val;
|
||||
regs->monitor_code = lc->monitor_code;
|
||||
/*
|
||||
* In case of a guest fault, short-circuit the fault handler and return.
|
||||
* This way the sie64a() function will return 0; fault address and
|
||||
|
||||
+25
-10
@@ -231,24 +231,33 @@ int zpci_fmb_disable_device(struct zpci_dev *zdev)
|
||||
static int zpci_cfg_load(struct zpci_dev *zdev, int offset, u32 *val, u8 len)
|
||||
{
|
||||
u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
|
||||
int rc = -ENODEV;
|
||||
u64 data;
|
||||
int rc;
|
||||
|
||||
if (!zdev_enabled(zdev))
|
||||
goto out_err;
|
||||
|
||||
rc = __zpci_load(&data, req, offset);
|
||||
if (!rc) {
|
||||
data = le64_to_cpu((__force __le64) data);
|
||||
data >>= (8 - len) * 8;
|
||||
*val = (u32) data;
|
||||
} else
|
||||
*val = 0xffffffff;
|
||||
if (rc)
|
||||
goto out_err;
|
||||
data = le64_to_cpu((__force __le64)data);
|
||||
data >>= (8 - len) * 8;
|
||||
*val = (u32)data;
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
PCI_SET_ERROR_RESPONSE(val);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int zpci_cfg_store(struct zpci_dev *zdev, int offset, u32 val, u8 len)
|
||||
{
|
||||
u64 req = ZPCI_CREATE_REQ(zdev->fh, ZPCI_PCIAS_CFGSPC, len);
|
||||
int rc = -ENODEV;
|
||||
u64 data = val;
|
||||
int rc;
|
||||
|
||||
if (!zdev_enabled(zdev))
|
||||
return rc;
|
||||
|
||||
data <<= (8 - len) * 8;
|
||||
data = (__force u64) cpu_to_le64(data);
|
||||
@@ -397,7 +406,9 @@ static int pci_read(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
{
|
||||
struct zpci_dev *zdev = zdev_from_bus(bus, devfn);
|
||||
|
||||
return (zdev) ? zpci_cfg_load(zdev, where, val, size) : -ENODEV;
|
||||
if (!zdev || zpci_cfg_load(zdev, where, val, size))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
@@ -405,7 +416,9 @@ static int pci_write(struct pci_bus *bus, unsigned int devfn, int where,
|
||||
{
|
||||
struct zpci_dev *zdev = zdev_from_bus(bus, devfn);
|
||||
|
||||
return (zdev) ? zpci_cfg_store(zdev, where, val, size) : -ENODEV;
|
||||
if (!zdev || zpci_cfg_store(zdev, where, val, size))
|
||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||
return PCIBIOS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
static struct pci_ops pci_root_ops = {
|
||||
@@ -1052,6 +1065,8 @@ static int zpci_mem_init(void)
|
||||
{
|
||||
BUILD_BUG_ON(!is_power_of_2(__alignof__(struct zpci_fmb)) ||
|
||||
__alignof__(struct zpci_fmb) < sizeof(struct zpci_fmb));
|
||||
BUILD_BUG_ON((CONFIG_ILLEGAL_POINTER_VALUE + 0x10000 > ZPCI_IOMAP_ADDR_BASE) &&
|
||||
(CONFIG_ILLEGAL_POINTER_VALUE <= ZPCI_IOMAP_ADDR_MAX));
|
||||
|
||||
zdev_fmb_cache = kmem_cache_create("PCI_FMB_cache", sizeof(struct zpci_fmb),
|
||||
__alignof__(struct zpci_fmb), 0, NULL);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user