diff options
| author | Mark Brown <broonie@kernel.org> | 2026-05-29 18:09:26 +0100 |
|---|---|---|
| committer | Mark Brown <broonie@kernel.org> | 2026-05-29 18:09:26 +0100 |
| commit | 6a2f8c339e219a7e4d9939f54c9bba8625c5fa58 (patch) | |
| tree | d29b606f59ebc13fc04067affa99833d0c3cb0ab /arch | |
| parent | 25d928ed202826ffe8ee0f7944b80be922c5d081 (diff) | |
| parent | 6f2bf64ba8ad6f8ea4f2b2207952814d9f3edcc2 (diff) | |
| download | linux-next-history-6a2f8c339e219a7e4d9939f54c9bba8625c5fa58.tar.gz | |
Merge branch 'for-next' of https://git.kernel.org/pub/scm/linux/kernel/git/s390/linux.git
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/s390/Kconfig | 9 | ||||
| -rw-r--r-- | arch/s390/appldata/appldata_base.c | 3 | ||||
| -rw-r--r-- | arch/s390/include/asm/barrier.h | 12 | ||||
| -rw-r--r-- | arch/s390/include/asm/debug.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/asm/processor.h | 3 | ||||
| -rw-r--r-- | arch/s390/include/asm/sclp.h | 1 | ||||
| -rw-r--r-- | arch/s390/include/asm/trace_clock.h | 13 | ||||
| -rw-r--r-- | arch/s390/include/asm/vdso/processor.h | 4 | ||||
| -rw-r--r-- | arch/s390/kernel/Makefile | 1 | ||||
| -rw-r--r-- | arch/s390/kernel/debug.c | 129 | ||||
| -rw-r--r-- | arch/s390/kernel/process.c | 3 | ||||
| -rw-r--r-- | arch/s390/kernel/trace_clock.c | 12 | ||||
| -rw-r--r-- | arch/s390/kernel/vmlinux.lds.S | 7 | ||||
| -rw-r--r-- | arch/s390/mm/init.c | 2 |
14 files changed, 162 insertions, 38 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index ecbcbb781e40a..771f738fe8bda 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -179,6 +179,7 @@ config S390 select GENERIC_SMP_IDLE_THREAD select GENERIC_TIME_VSYSCALL select GENERIC_IOREMAP if PCI + select GLOB select HAVE_ALIGNED_STRUCT_PAGE select HAVE_ARCH_AUDITSYSCALL select HAVE_ARCH_GET_SECUREBOOT @@ -999,9 +1000,8 @@ config S390_MODULES_SANITY_TEST_HELPERS menu "Selftests" config S390_UNWIND_SELFTEST - def_tristate n + def_tristate KUNIT_ALL_TESTS depends on KUNIT - default KUNIT_ALL_TESTS prompt "Test unwind functions" help This option enables s390 specific stack unwinder testing kernel @@ -1011,7 +1011,7 @@ config S390_UNWIND_SELFTEST Say N if you are unsure. config S390_KPROBES_SANITY_TEST - def_tristate n + def_tristate KUNIT_ALL_TESTS prompt "Enable s390 specific kprobes tests" depends on KPROBES depends on KUNIT @@ -1023,9 +1023,8 @@ config S390_KPROBES_SANITY_TEST Say N if you are unsure. config S390_MODULES_SANITY_TEST - def_tristate n + def_tristate KUNIT_ALL_TESTS depends on KUNIT && m - default KUNIT_ALL_TESTS prompt "Enable s390 specific modules tests" select S390_MODULES_SANITY_TEST_HELPERS help diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index edbedbb2a773a..9cba4633c3f3b 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c @@ -51,7 +51,6 @@ static int appldata_timer_handler(const struct ctl_table *ctl, int write, static int appldata_interval_handler(const struct ctl_table *ctl, int write, void *buffer, size_t *lenp, loff_t *ppos); -static struct ctl_table_header *appldata_sysctl_header; static const struct ctl_table appldata_table[] = { { .procname = "timer", @@ -406,7 +405,7 @@ static int __init appldata_init(void) appldata_wq = alloc_ordered_workqueue("appldata", 0); if (!appldata_wq) return -ENOMEM; - appldata_sysctl_header = register_sysctl(appldata_proc_name, appldata_table); + register_sysctl(appldata_proc_name, appldata_table); return 0; } diff --git a/arch/s390/include/asm/barrier.h b/arch/s390/include/asm/barrier.h index dad02f5b3c8d3..d1e4201f38506 100644 --- a/arch/s390/include/asm/barrier.h +++ b/arch/s390/include/asm/barrier.h @@ -8,6 +8,7 @@ #ifndef __ASM_BARRIER_H #define __ASM_BARRIER_H +#include <asm/alternative.h> #include <asm/march.h> /* @@ -16,16 +17,11 @@ * to devices. */ -#ifdef MARCH_HAS_Z196_FEATURES -/* Fast-BCR without checkpoint synchronization */ -#define __ASM_BCR_SERIALIZE "bcr 14,0" -#else -#define __ASM_BCR_SERIALIZE "bcr 15,0" -#endif - static __always_inline void bcr_serialize(void) { - asm volatile(__ASM_BCR_SERIALIZE : : : "memory"); + asm_inline volatile( + ALTERNATIVE("bcr 15,0", "bcr 14,0", ALT_FACILITY(45)) + : : : "memory"); } #define __mb() bcr_serialize() diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h index c5440b3ee53d7..39d484c597748 100644 --- a/arch/s390/include/asm/debug.h +++ b/arch/s390/include/asm/debug.h @@ -490,6 +490,7 @@ arch_initcall(VNAME(var, reg)) __DEFINE_STATIC_AREA(var); \ static debug_info_t __refdata var = \ __DEBUG_INFO_INIT(var, (name), (buf_size)); \ +static debug_info_t __used __section(".s390dbf_info") *VNAME(var, info) = &var; \ __REGISTER_STATIC_DEBUG_INFO(var, name, pages, nr_areas, view) void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas); diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 78195ee5e99f6..ecd3341686eb6 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -33,6 +33,7 @@ #include <linux/irqflags.h> #include <linux/instruction_pointer.h> #include <linux/bitops.h> +#include <asm/vdso/processor.h> #include <asm/fpu-types.h> #include <asm/cpu.h> #include <asm/page.h> @@ -282,8 +283,6 @@ static __always_inline unsigned short stap(void) return cpu_address; } -#define cpu_relax() barrier() - #define ECAG_CACHE_ATTRIBUTE 0 #define ECAG_CPU_ATTRIBUTE 1 diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index 0f184dbdbe5e0..d928a9ddfe402 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h @@ -20,6 +20,7 @@ #define SCLP_ERRNOTIFY_AQ_REPAIR 1 #define SCLP_ERRNOTIFY_AQ_INFO_LOG 2 #define SCLP_ERRNOTIFY_AQ_OPTICS_DATA 3 +#define SCLP_ERRNOTIFY_AQ_NVME_SMART_LOG 4 #ifndef __ASSEMBLER__ #include <linux/uio.h> diff --git a/arch/s390/include/asm/trace_clock.h b/arch/s390/include/asm/trace_clock.h new file mode 100644 index 0000000000000..273e05cbdae02 --- /dev/null +++ b/arch/s390/include/asm/trace_clock.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _ASM_S390_TRACE_CLOCK_H +#define _ASM_S390_TRACE_CLOCK_H + +#include <linux/compiler.h> +#include <linux/types.h> + +u64 notrace trace_clock_s390_tod(void); + +#define ARCH_TRACE_CLOCKS \ + { trace_clock_s390_tod, "s390-tod", .in_ns = 0 }, + +#endif /* _ASM_S390_TRACE_CLOCK_H */ diff --git a/arch/s390/include/asm/vdso/processor.h b/arch/s390/include/asm/vdso/processor.h index cfcc3e117c4c9..6775621e5a5a3 100644 --- a/arch/s390/include/asm/vdso/processor.h +++ b/arch/s390/include/asm/vdso/processor.h @@ -2,6 +2,8 @@ #ifndef __ASM_VDSO_PROCESSOR_H #define __ASM_VDSO_PROCESSOR_H -#define cpu_relax() barrier() +#include <asm/barrier.h> + +#define cpu_relax() bcr_serialize() #endif /* __ASM_VDSO_PROCESSOR_H */ diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 137e4793ec117..6c88476d79a31 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_KPROBES) += mcount.o obj-$(CONFIG_RETHOOK) += rethook.o obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o +obj-$(CONFIG_TRACING) += trace_clock.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o obj-$(CONFIG_KEXEC_CORE) += machine_kexec.o relocate_kernel.o obj-$(CONFIG_VMCORE_INFO) += vmcore_info.o diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c index 7650f2adb5cf8..dbf430f479bdf 100644 --- a/arch/s390/kernel/debug.c +++ b/arch/s390/kernel/debug.c @@ -26,6 +26,8 @@ #include <linux/math.h> #include <linux/minmax.h> #include <linux/debugfs.h> +#include <linux/glob.h> +#include <linux/stringify.h> #include <asm/debug.h> @@ -154,6 +156,7 @@ static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION; static debug_info_t *debug_area_first; static debug_info_t *debug_area_last; static DEFINE_MUTEX(debug_mutex); +extern debug_info_t *__s390dbf_info[], *__s390dbf_info_end[]; static int initialized; static int debug_critical; @@ -168,7 +171,91 @@ static const struct file_operations debug_file_ops = { static struct dentry *debug_debugfs_root_entry; +/* List of debug area parameters to override */ +#define PARAM_UNSET -2 +#define PARAM_NUM 16 +static struct debug_param_t { + char name[DEBUG_MAX_NAME_LEN + 1]; + int level; + int pages; +} debug_param[PARAM_NUM]; +static int debug_param_num; + /* functions */ +static void debug_get_param(const char *name, int *level, int *pages) +{ + struct debug_param_t *p; + int i; + + for (i = 0; i < debug_param_num; i++) { + p = &debug_param[i]; + if (!glob_match(p->name, name)) + continue; + if (level && p->level != PARAM_UNSET) { + pr_info("%s: override level to %d\n", name, p->level); + *level = p->level; + } + if (pages && p->pages != PARAM_UNSET) { + pr_info("%s: override pages to %d\n", name, p->pages); + *pages = p->pages; + } + } +} + +#define LVL_LEN 10 +#define LVL_FMT "%" __stringify(LVL_LEN) "[^:]" +#define NAME_FMT "%" __stringify(DEBUG_MAX_NAME_LEN) "[^:]" + +static bool __init s390dbf_parse_one(const char *arg, struct debug_param_t *param) +{ + struct debug_param_t p = { { 0 }, PARAM_UNSET, PARAM_UNSET }; + char level[LVL_LEN + 1] = { 0 }; + + /* arg: <name|pattern>:[<level>|-]:[<pages>] */ + if (sscanf(arg, NAME_FMT ":" LVL_FMT ":%d", p.name, level, &p.pages) > 1) { + if (strcmp(level, "-") == 0) + p.level = DEBUG_OFF_LEVEL; + else if (kstrtoint(level, 0, &p.level) != 0) + return false; + } else if (sscanf(arg, NAME_FMT "::%d", p.name, &p.pages) != 2) { + return false; + } + + if (p.level != PARAM_UNSET && p.level != DEBUG_OFF_LEVEL && + (p.level < 0 || p.level > DEBUG_MAX_LEVEL)) + return false; + if (p.pages != PARAM_UNSET && p.pages < 0) + return false; + *param = p; + + return true; +} + +static int __init s390dbf_parse(char *arg) +{ + debug_info_t **id; + int i, rc = 0; + + while (arg && debug_param_num < PARAM_NUM) { + if (s390dbf_parse_one(arg, &debug_param[debug_param_num])) + debug_param_num++; + else + rc = -EINVAL; + arg = strchr(arg, ','); + if (arg) + arg++; + } + + /* + * Apply level to static debug areas, delay buffer size changes until + * regular memory allocations are possible. + */ + for (i = 0, id = __s390dbf_info; &id[i] < __s390dbf_info_end; i++) + debug_get_param(id[i]->name, &id[i]->level, NULL); + + return rc; +} +early_param("s390dbf", s390dbf_parse); /* * debug_areas_alloc @@ -305,10 +392,11 @@ static void debug_info_free(debug_info_t *db_info) static debug_info_t *debug_info_create(const char *name, int pages_per_area, int nr_areas, int buf_size, umode_t mode) { + int level = DEBUG_DEFAULT_LEVEL; debug_info_t *rc; - rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, - DEBUG_DEFAULT_LEVEL, ALL_AREAS); + debug_get_param(name, &level, &pages_per_area); + rc = debug_info_alloc(name, pages_per_area, nr_areas, buf_size, level, ALL_AREAS); if (!rc) goto out; @@ -872,6 +960,7 @@ void debug_register_static(debug_info_t *id, int pages_per_area, int nr_areas) return; } + debug_get_param(id->name, &id->level, &pages_per_area); copy = debug_info_alloc("", pages_per_area, nr_areas, id->buf_size, id->level, ALL_AREAS); if (!copy) { @@ -975,16 +1064,7 @@ static int debug_set_size(debug_info_t *id, int nr_areas, int pages_per_area) return 0; } -/** - * debug_set_level() - Sets new actual debug level if new_level is valid. - * - * @id: handle for debug log - * @new_level: new debug level - * - * Return: - * none - */ -void debug_set_level(debug_info_t *id, int new_level) +static void _debug_set_level(debug_info_t *id, int new_level) { unsigned long flags; @@ -1003,6 +1083,23 @@ void debug_set_level(debug_info_t *id, int new_level) id->level = new_level; raw_spin_unlock_irqrestore(&id->lock, flags); } + +/** + * debug_set_level() - Sets new actual debug level if new_level is valid. + * + * @id: handle for debug log + * @new_level: new debug level + * + * Return: + * none + */ +void debug_set_level(debug_info_t *id, int new_level) +{ + /* Level specified via kernel parameter takes precedence */ + debug_get_param(id->name, &new_level, NULL); + + _debug_set_level(id, new_level); +} EXPORT_SYMBOL(debug_set_level); /* @@ -1137,8 +1234,6 @@ static const struct ctl_table s390dbf_table[] = { }, }; -static struct ctl_table_header *s390dbf_sysctl_header; - /** * debug_stop_all() - stops the debug feature if stopping is allowed. * @@ -1529,7 +1624,7 @@ static int debug_input_level_fn(debug_info_t *id, struct debug_view *view, goto out; } if (str[0] == '-') { - debug_set_level(id, DEBUG_OFF_LEVEL); + _debug_set_level(id, DEBUG_OFF_LEVEL); rc = user_len; goto free_str; } else { @@ -1539,7 +1634,7 @@ static int debug_input_level_fn(debug_info_t *id, struct debug_view *view, pr_warn("%s is not a valid level for a debug feature\n", str); rc = -EINVAL; } else { - debug_set_level(id, new_level); + _debug_set_level(id, new_level); rc = user_len; } free_str: @@ -1728,7 +1823,7 @@ EXPORT_SYMBOL(debug_sprintf_format_fn); */ static int __init debug_init(void) { - s390dbf_sysctl_header = register_sysctl("s390dbf", s390dbf_table); + register_sysctl("s390dbf", s390dbf_table); mutex_lock(&debug_mutex); debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT, NULL); initialized = 1; diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 0df95dcb21012..dabd569dbba8d 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -203,9 +203,6 @@ unsigned long __get_wchan(struct task_struct *p) struct unwind_state state; unsigned long ip = 0; - if (!task_stack_page(p)) - return 0; - if (!try_get_task_stack(p)) return 0; diff --git a/arch/s390/kernel/trace_clock.c b/arch/s390/kernel/trace_clock.c new file mode 100644 index 0000000000000..9ca568058cbce --- /dev/null +++ b/arch/s390/kernel/trace_clock.c @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/trace_clock.h> +#include <linux/timex.h> +/* + * trace_clock_s390_tod(): trace clock based on the s390 TOD clock + * + * Unlike the other clocks, this is not in nanoseconds. + */ +u64 notrace trace_clock_s390_tod(void) +{ + return get_tod_clock(); +} diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S index 2b62395e35bfb..1f0e71c58eb9c 100644 --- a/arch/s390/kernel/vmlinux.lds.S +++ b/arch/s390/kernel/vmlinux.lds.S @@ -159,6 +159,13 @@ SECTIONS } #endif + . = ALIGN(8); + .s390dbf_info : { + __s390dbf_info = .; + *(.s390dbf_info) + __s390dbf_info_end = .; + } + /* * Table with the patch locations to undo expolines */ diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 11a689423440f..f07168a0d3dd3 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -84,6 +84,8 @@ void __init arch_setup_zero_pages(void) empty_zero_page = (unsigned long)memblock_alloc_or_panic(PAGE_SIZE << order, PAGE_SIZE); zero_page_mask = ((PAGE_SIZE << order) - 1) & PAGE_MASK; + + set_memory_ro(empty_zero_page, 1UL << order); } void __init arch_zone_limits_init(unsigned long *max_zone_pfns) |
