diff options
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/Makefile | 13 | ||||
-rw-r--r-- | arch/s390/kernel/base.S | 21 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 16 | ||||
-rw-r--r-- | arch/s390/kernel/early_nobss.c | 45 | ||||
-rw-r--r-- | arch/s390/kernel/early_printk.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/head64.S | 8 | ||||
-rw-r--r-- | arch/s390/kernel/module.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/perf_cpum_sf.c | 20 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 26 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 27 | ||||
-rw-r--r-- | arch/s390/kernel/stacktrace.c | 50 | ||||
-rw-r--r-- | arch/s390/kernel/vdso.c | 18 |
12 files changed, 76 insertions, 174 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 0f255b54b051..7edbbcd8228a 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -10,20 +10,12 @@ CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) # Do not trace early setup code CFLAGS_REMOVE_early.o = $(CC_FLAGS_FTRACE) -CFLAGS_REMOVE_early_nobss.o = $(CC_FLAGS_FTRACE) endif GCOV_PROFILE_early.o := n -GCOV_PROFILE_early_nobss.o := n - KCOV_INSTRUMENT_early.o := n -KCOV_INSTRUMENT_early_nobss.o := n - UBSAN_SANITIZE_early.o := n -UBSAN_SANITIZE_early_nobss.o := n - -KASAN_SANITIZE_early_nobss.o := n KASAN_SANITIZE_ipl.o := n KASAN_SANITIZE_machine_kexec.o := n @@ -48,7 +40,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o -obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o early_nobss.o +obj-y += debug.o irq.o ipl.o dis.o diag.o vdso.o obj-y += sysinfo.o lgr.o os_info.o machine_kexec.o pgm_check.o obj-y += runtime_instr.o cache.o fpu.o dumpstack.o guarded_storage.o sthyi.o obj-y += entry.o reipl.o relocate_kernel.o kdebugfs.o alternative.o @@ -90,6 +82,3 @@ obj-$(CONFIG_TRACEPOINTS) += trace.o # vdso obj-y += vdso64/ obj-$(CONFIG_COMPAT_VDSO) += vdso32/ - -chkbss := head64.o early_nobss.o -include $(srctree)/arch/s390/scripts/Makefile.chkbss diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S index 2f39ea57f358..b79e0fd571f8 100644 --- a/arch/s390/kernel/base.S +++ b/arch/s390/kernel/base.S @@ -16,27 +16,6 @@ GEN_BR_THUNK %r9 GEN_BR_THUNK %r14 -ENTRY(s390_base_mcck_handler) - basr %r13,0 -0: lg %r15,__LC_NODAT_STACK # load panic stack - aghi %r15,-STACK_FRAME_OVERHEAD - larl %r1,s390_base_mcck_handler_fn - lg %r9,0(%r1) - ltgr %r9,%r9 - jz 1f - BASR_EX %r14,%r9 -1: la %r1,4095 - lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1) - lpswe __LC_MCK_OLD_PSW -ENDPROC(s390_base_mcck_handler) - - .section .bss - .align 8 - .globl s390_base_mcck_handler_fn -s390_base_mcck_handler_fn: - .quad 0 - .previous - ENTRY(s390_base_ext_handler) stmg %r0,%r15,__LC_SAVE_AREA_ASYNC basr %r13,0 diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 6312fed48530..b432d63d0b37 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c @@ -32,6 +32,21 @@ #include <asm/boot_data.h> #include "entry.h" +static void __init reset_tod_clock(void) +{ + u64 time; + + if (store_tod_clock(&time) == 0) + return; + /* TOD clock not running. Set the clock to Unix Epoch. */ + if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0) + disabled_wait(); + + memset(tod_clock_base, 0, 16); + *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH; + S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; +} + /* * Initialize storage key for kernel pages */ @@ -301,6 +316,7 @@ static void __init check_image_bootable(void) void __init startup_init(void) { + reset_tod_clock(); check_image_bootable(); time_early_init(); init_kernel_storage_key(); diff --git a/arch/s390/kernel/early_nobss.c b/arch/s390/kernel/early_nobss.c deleted file mode 100644 index 52a3ef959341..000000000000 --- a/arch/s390/kernel/early_nobss.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright IBM Corp. 2007, 2018 - */ - -/* - * Early setup functions which may not rely on an initialized bss - * section. The last thing that is supposed to happen here is - * initialization of the bss section. - */ - -#include <linux/processor.h> -#include <linux/string.h> -#include <asm/sections.h> -#include <asm/lowcore.h> -#include <asm/timex.h> -#include <asm/kasan.h> -#include "entry.h" - -static void __init reset_tod_clock(void) -{ - u64 time; - - if (store_tod_clock(&time) == 0) - return; - /* TOD clock not running. Set the clock to Unix Epoch. */ - if (set_tod_clock(TOD_UNIX_EPOCH) != 0 || store_tod_clock(&time) != 0) - disabled_wait(); - - memset(tod_clock_base, 0, 16); - *(__u64 *) &tod_clock_base[1] = TOD_UNIX_EPOCH; - S390_lowcore.last_update_clock = TOD_UNIX_EPOCH; -} - -static void __init clear_bss_section(void) -{ - memset(__bss_start, 0, __bss_stop - __bss_start); -} - -void __init startup_init_nobss(void) -{ - reset_tod_clock(); - clear_bss_section(); - kasan_early_init(); -} diff --git a/arch/s390/kernel/early_printk.c b/arch/s390/kernel/early_printk.c index 40c1dfec944e..6f24d83bc5dc 100644 --- a/arch/s390/kernel/early_printk.c +++ b/arch/s390/kernel/early_printk.c @@ -25,7 +25,7 @@ static int __init setup_early_printk(char *buf) if (early_console) return 0; /* Accept only "earlyprintk" and "earlyprintk=sclp" */ - if (buf && strncmp(buf, "sclp", 4)) + if (buf && !str_has_prefix(buf, "sclp")) return 0; if (!sclp.has_linemode && !sclp.has_vt220) return 0; diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index f384a18e6c26..0d9ee198f4eb 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -34,11 +34,9 @@ ENTRY(startup_continue) larl %r14,init_task stg %r14,__LC_CURRENT larl %r15,init_thread_union+THREAD_SIZE-STACK_FRAME_OVERHEAD -# -# Early setup functions that may not rely on an initialized bss section, -# like moving the initrd. Returns with an initialized bss section. -# - brasl %r14,startup_init_nobss +#ifdef CONFIG_KASAN + brasl %r14,kasan_early_init +#endif # # Early machine initialization and detection functions. # diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c index 31889db609e9..ba8f19bb438b 100644 --- a/arch/s390/kernel/module.c +++ b/arch/s390/kernel/module.c @@ -472,11 +472,11 @@ int module_finalize(const Elf_Ehdr *hdr, apply_alternatives(aseg, aseg + s->sh_size); if (IS_ENABLED(CONFIG_EXPOLINE) && - (!strncmp(".s390_indirect", secname, 14))) + (str_has_prefix(secname, ".s390_indirect"))) nospec_revert(aseg, aseg + s->sh_size); if (IS_ENABLED(CONFIG_EXPOLINE) && - (!strncmp(".s390_return", secname, 12))) + (str_has_prefix(secname, ".s390_return"))) nospec_revert(aseg, aseg + s->sh_size); } diff --git a/arch/s390/kernel/perf_cpum_sf.c b/arch/s390/kernel/perf_cpum_sf.c index 1266194afb02..292a452cd1f3 100644 --- a/arch/s390/kernel/perf_cpum_sf.c +++ b/arch/s390/kernel/perf_cpum_sf.c @@ -514,7 +514,6 @@ static void extend_sampling_buffer(struct sf_buffer *sfb, sfb_pending_allocs(sfb, hwc)); } - /* Number of perf events counting hardware events */ static atomic_t num_events; /* Used to avoid races in calling reserve/release_cpumf_hardware */ @@ -923,9 +922,10 @@ static void cpumsf_pmu_enable(struct pmu *pmu) lpp(&S390_lowcore.lpp); debug_sprintf_event(sfdbg, 6, "pmu_enable: es=%i cs=%i ed=%i cd=%i " - "tear=%p dear=%p\n", cpuhw->lsctl.es, cpuhw->lsctl.cs, - cpuhw->lsctl.ed, cpuhw->lsctl.cd, - (void *) cpuhw->lsctl.tear, (void *) cpuhw->lsctl.dear); + "tear=%p dear=%p\n", cpuhw->lsctl.es, + cpuhw->lsctl.cs, cpuhw->lsctl.ed, cpuhw->lsctl.cd, + (void *) cpuhw->lsctl.tear, + (void *) cpuhw->lsctl.dear); } static void cpumsf_pmu_disable(struct pmu *pmu) @@ -1083,7 +1083,8 @@ static void debug_sample_entry(struct hws_basic_entry *sample, struct hws_trailer_entry *te) { debug_sprintf_event(sfdbg, 4, "hw_collect_samples: Found unknown " - "sampling data entry: te->f=%i basic.def=%04x (%p)\n", + "sampling data entry: te->f=%i basic.def=%04x " + "(%p)\n", te->f, sample->def, sample); } @@ -1216,7 +1217,7 @@ static void hw_perf_event_update(struct perf_event *event, int flush_all) /* Timestamps are valid for full sample-data-blocks only */ debug_sprintf_event(sfdbg, 6, "hw_perf_event_update: sdbt=%p " - "overflow=%llu timestamp=0x%llx\n", + "overflow=%llu timestamp=%#llx\n", sdbt, te->overflow, (te->f) ? trailer_timestamp(te) : 0ULL); @@ -1879,10 +1880,12 @@ static struct attribute_group cpumsf_pmu_events_group = { .name = "events", .attrs = cpumsf_pmu_events_attr, }; + static struct attribute_group cpumsf_pmu_format_group = { .name = "format", .attrs = cpumsf_pmu_format_attr, }; + static const struct attribute_group *cpumsf_pmu_attr_groups[] = { &cpumsf_pmu_events_group, &cpumsf_pmu_format_group, @@ -1938,7 +1941,8 @@ static void cpumf_measurement_alert(struct ext_code ext_code, /* Report measurement alerts only for non-PRA codes */ if (alert != CPU_MF_INT_SF_PRA) - debug_sprintf_event(sfdbg, 6, "measurement alert: 0x%x\n", alert); + debug_sprintf_event(sfdbg, 6, "measurement alert: %#x\n", + alert); /* Sampling authorization change request */ if (alert & CPU_MF_INT_SF_SACA) @@ -1959,6 +1963,7 @@ static void cpumf_measurement_alert(struct ext_code ext_code, sf_disable(); } } + static int cpusf_pmu_setup(unsigned int cpu, int flags) { /* Ignore the notification if no events are scheduled on the PMU. @@ -2096,5 +2101,6 @@ static int __init init_cpum_sampling_pmu(void) out: return err; } + arch_initcall(init_cpum_sampling_pmu); core_param(cpum_sfb_size, CPUM_SF_MAX_SDB, sfb_size, 0640); diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 63873aa6693f..b0afec673f77 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c @@ -184,20 +184,30 @@ unsigned long get_wchan(struct task_struct *p) if (!p || p == current || p->state == TASK_RUNNING || !task_stack_page(p)) return 0; + + if (!try_get_task_stack(p)) + return 0; + low = task_stack_page(p); high = (struct stack_frame *) task_pt_regs(p); sf = (struct stack_frame *) p->thread.ksp; - if (sf <= low || sf > high) - return 0; + if (sf <= low || sf > high) { + return_address = 0; + goto out; + } for (count = 0; count < 16; count++) { - sf = (struct stack_frame *) sf->back_chain; - if (sf <= low || sf > high) - return 0; - return_address = sf->gprs[8]; + sf = (struct stack_frame *)READ_ONCE_NOCHECK(sf->back_chain); + if (sf <= low || sf > high) { + return_address = 0; + goto out; + } + return_address = READ_ONCE_NOCHECK(sf->gprs[8]); if (!in_sched_functions(return_address)) - return return_address; + goto out; } - return 0; +out: + put_task_stack(p); + return return_address; } unsigned long arch_align_stack(unsigned long sp) diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 253177900950..3ff291bc63b7 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -99,6 +99,7 @@ int __bootdata_preserved(prot_virt_guest); int __bootdata(noexec_disabled); int __bootdata(memory_end_set); unsigned long __bootdata(memory_end); +unsigned long __bootdata(vmalloc_size); unsigned long __bootdata(max_physmem_end); struct mem_detect_info __bootdata(mem_detect); @@ -168,15 +169,15 @@ static void __init set_preferred_console(void) static int __init conmode_setup(char *str) { #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) - if (strncmp(str, "hwc", 4) == 0 || strncmp(str, "sclp", 5) == 0) + if (!strcmp(str, "hwc") || !strcmp(str, "sclp")) SET_CONSOLE_SCLP; #endif #if defined(CONFIG_TN3215_CONSOLE) - if (strncmp(str, "3215", 5) == 0) + if (!strcmp(str, "3215")) SET_CONSOLE_3215; #endif #if defined(CONFIG_TN3270_CONSOLE) - if (strncmp(str, "3270", 5) == 0) + if (!strcmp(str, "3270")) SET_CONSOLE_3270; #endif set_preferred_console(); @@ -211,7 +212,7 @@ static void __init conmode_default(void) #endif return; } - if (strncmp(ptr + 8, "3270", 4) == 0) { + if (str_has_prefix(ptr + 8, "3270")) { #if defined(CONFIG_TN3270_CONSOLE) SET_CONSOLE_3270; #elif defined(CONFIG_TN3215_CONSOLE) @@ -219,7 +220,7 @@ static void __init conmode_default(void) #elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) SET_CONSOLE_SCLP; #endif - } else if (strncmp(ptr + 8, "3215", 4) == 0) { + } else if (str_has_prefix(ptr + 8, "3215")) { #if defined(CONFIG_TN3215_CONSOLE) SET_CONSOLE_3215; #elif defined(CONFIG_TN3270_CONSOLE) @@ -302,15 +303,6 @@ void machine_power_off(void) void (*pm_power_off)(void) = machine_power_off; EXPORT_SYMBOL_GPL(pm_power_off); -static int __init parse_vmalloc(char *arg) -{ - if (!arg) - return -EINVAL; - VMALLOC_END = (memparse(arg, &arg) + PAGE_SIZE - 1) & PAGE_MASK; - return 0; -} -early_param("vmalloc", parse_vmalloc); - void *restart_stack __section(.data); unsigned long stack_alloc(void) @@ -563,10 +555,9 @@ static void __init setup_resources(void) static void __init setup_memory_end(void) { - unsigned long vmax, vmalloc_size, tmp; + unsigned long vmax, tmp; /* Choose kernel address space layout: 3 or 4 levels. */ - vmalloc_size = VMALLOC_END ?: (128UL << 30) - MODULES_LEN; if (IS_ENABLED(CONFIG_KASAN)) { vmax = IS_ENABLED(CONFIG_KASAN_S390_4_LEVEL_PAGING) ? _REGION1_SIZE @@ -990,6 +981,10 @@ static int __init setup_hwcaps(void) case 0x3907: strcpy(elf_platform, "z14"); break; + case 0x8561: + case 0x8562: + strcpy(elf_platform, "z15"); + break; } /* diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c index f6a620f854e1..f8fc4f8aef9b 100644 --- a/arch/s390/kernel/stacktrace.c +++ b/arch/s390/kernel/stacktrace.c @@ -6,57 +6,19 @@ * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> */ -#include <linux/sched.h> -#include <linux/sched/debug.h> #include <linux/stacktrace.h> -#include <linux/kallsyms.h> -#include <linux/export.h> #include <asm/stacktrace.h> #include <asm/unwind.h> -void save_stack_trace(struct stack_trace *trace) +void arch_stack_walk(stack_trace_consume_fn consume_entry, void *cookie, + struct task_struct *task, struct pt_regs *regs) { struct unwind_state state; + unsigned long addr; - unwind_for_each_frame(&state, current, NULL, 0) { - if (trace->nr_entries >= trace->max_entries) + unwind_for_each_frame(&state, task, regs, 0) { + addr = unwind_get_return_address(&state); + if (!addr || !consume_entry(cookie, addr, false)) break; - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = state.ip; } } -EXPORT_SYMBOL_GPL(save_stack_trace); - -void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) -{ - struct unwind_state state; - - unwind_for_each_frame(&state, tsk, NULL, 0) { - if (trace->nr_entries >= trace->max_entries) - break; - if (in_sched_functions(state.ip)) - continue; - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = state.ip; - } -} -EXPORT_SYMBOL_GPL(save_stack_trace_tsk); - -void save_stack_trace_regs(struct pt_regs *regs, struct stack_trace *trace) -{ - struct unwind_state state; - - unwind_for_each_frame(&state, current, regs, 0) { - if (trace->nr_entries >= trace->max_entries) - break; - if (trace->skip > 0) - trace->skip--; - else - trace->entries[trace->nr_entries++] = state.ip; - } -} -EXPORT_SYMBOL_GPL(save_stack_trace_regs); diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index c6bc190f3c28..ed1fc08ccea2 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c @@ -97,21 +97,13 @@ static const struct vm_special_mapping vdso_mapping = { .mremap = vdso_mremap, }; -static int __init vdso_setup(char *s) +static int __init vdso_setup(char *str) { - unsigned long val; - int rc; + bool enabled; - rc = 0; - if (strncmp(s, "on", 3) == 0) - vdso_enabled = 1; - else if (strncmp(s, "off", 4) == 0) - vdso_enabled = 0; - else { - rc = kstrtoul(s, 0, &val); - vdso_enabled = rc ? 0 : !!val; - } - return !rc; + if (!kstrtobool(str, &enabled)) + vdso_enabled = enabled; + return 1; } __setup("vdso=", vdso_setup); |