From: Linus Torvalds Date: Sun, 30 Apr 2023 18:43:31 +0000 (-0700) Subject: Merge tag 's390-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux X-Git-Tag: v6.6-pxa1908~1315 X-Git-Url: https://git.dujemihanovic.xyz/?a=commitdiff_plain;h=10de638d8ea57ebab4231ea077bed01d9bade775;p=linux.git Merge tag 's390-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux Pull s390 updates from Vasily Gorbik: - Add support for stackleak feature. Also allow specifying architecture-specific stackleak poison function to enable faster implementation. On s390, the mvc-based implementation helps decrease typical overhead from a factor of 3 to just 25% - Convert all assembler files to use SYM* style macros, deprecating the ENTRY() macro and other annotations. Select ARCH_USE_SYM_ANNOTATIONS - Improve KASLR to also randomize module and special amode31 code base load addresses - Rework decompressor memory tracking to support memory holes and improve error handling - Add support for protected virtualization AP binding - Add support for set_direct_map() calls - Implement set_memory_rox() and noexec module_alloc() - Remove obsolete overriding of mem*() functions for KASAN - Rework kexec/kdump to avoid using nodat_stack to call purgatory - Convert the rest of the s390 code to use flexible-array member instead of a zero-length array - Clean up uaccess inline asm - Enable ARCH_HAS_MEMBARRIER_SYNC_CORE - Convert to using CONFIG_FUNCTION_ALIGNMENT and enable DEBUG_FORCE_FUNCTION_ALIGN_64B - Resolve last_break in userspace fault reports - Simplify one-level sysctl registration - Clean up branch prediction handling - Rework CPU counter facility to retrieve available counter sets just once - Other various small fixes and improvements all over the code * tag 's390-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (118 commits) s390/stackleak: provide fast __stackleak_poison() implementation stackleak: allow to specify arch specific stackleak poison function s390: select ARCH_USE_SYM_ANNOTATIONS s390/mm: use VM_FLUSH_RESET_PERMS in module_alloc() s390: wire up memfd_secret system call s390/mm: enable ARCH_HAS_SET_DIRECT_MAP s390/mm: use BIT macro to generate SET_MEMORY bit masks s390/relocate_kernel: adjust indentation s390/relocate_kernel: use SYM* macros instead of ENTRY(), etc. s390/entry: use SYM* macros instead of ENTRY(), etc. s390/purgatory: use SYM* macros instead of ENTRY(), etc. s390/kprobes: use SYM* macros instead of ENTRY(), etc. s390/reipl: use SYM* macros instead of ENTRY(), etc. s390/head64: use SYM* macros instead of ENTRY(), etc. s390/earlypgm: use SYM* macros instead of ENTRY(), etc. s390/mcount: use SYM* macros instead of ENTRY(), etc. s390/crc32le: use SYM* macros instead of ENTRY(), etc. s390/crc32be: use SYM* macros instead of ENTRY(), etc. s390/crypto,chacha: use SYM* macros instead of ENTRY(), etc. s390/amode31: use SYM* macros instead of ENTRY(), etc. ... --- 10de638d8ea57ebab4231ea077bed01d9bade775 diff --cc arch/s390/Kconfig index 61d778397720,574bd48199f2..beb62f744c61 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@@ -120,9 -118,9 +118,10 @@@ config S39 select ARCH_SUPPORTS_DEBUG_PAGEALLOC select ARCH_SUPPORTS_HUGETLBFS select ARCH_SUPPORTS_NUMA_BALANCING + select ARCH_SUPPORTS_PER_VMA_LOCK select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF + select ARCH_USE_SYM_ANNOTATIONS select ARCH_WANTS_DYNAMIC_TASK_STRUCT select ARCH_WANTS_NO_INSTR select ARCH_WANT_DEFAULT_BPF_JIT diff --cc arch/s390/kernel/mcount.S index 6c10da43b538,a7902fdb7ba2..dbece2803c50 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@@ -28,15 -28,10 +28,15 @@@ .section .kprobes.text, "ax" - ENTRY(ftrace_stub) + SYM_FUNC_START(ftrace_stub) BR_EX %r14 - ENDPROC(ftrace_stub) + SYM_FUNC_END(ftrace_stub) +SYM_CODE_START(ftrace_stub_direct_tramp) + lgr %r1, %r0 + BR_EX %r1 +SYM_CODE_END(ftrace_stub_direct_tramp) + .macro ftrace_regs_entry, allregs=0 stg %r14,(__SF_GPRS+8*8)(%r15) # save traced function caller diff --cc arch/s390/kernel/setup.c index 4259b6c50516,0903fe356634..fe10da1a271e --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@@ -385,18 -381,13 +381,13 @@@ void stack_free(unsigned long stack #endif } - int __init arch_early_irq_init(void) -void __init arch_call_rest_init(void) ++void __init __noreturn arch_call_rest_init(void) { - unsigned long stack; - - stack = __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); - if (!stack) - panic("Couldn't allocate async stack"); - S390_lowcore.async_stack = stack + STACK_INIT_OFFSET; - return 0; + smp_reinit_ipl_cpu(); + rest_init(); } - void __init __noreturn arch_call_rest_init(void) + static unsigned long __init stack_alloc_early(void) { unsigned long stack; diff --cc arch/s390/kernel/topology.c index 72af753d1bba,e5d6a1c25d13..9fd19530c9a5 --- a/arch/s390/kernel/topology.c +++ b/arch/s390/kernel/topology.c @@@ -637,33 -637,14 +637,23 @@@ static struct ctl_table topology_ctl_ta { }, }; - static struct ctl_table topology_dir_table[] = { - { - .procname = "s390", - .maxlen = 0, - .mode = 0555, - .child = topology_ctl_table, - }, - { }, - }; - static int __init topology_init(void) { + struct device *dev_root; + int rc = 0; + timer_setup(&topology_timer, topology_timer_fn, TIMER_DEFERRABLE); if (MACHINE_HAS_TOPOLOGY) set_topology_timer(); else topology_update_polarization_simple(); - register_sysctl_table(topology_dir_table); + register_sysctl("s390", topology_ctl_table); - return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching); + + dev_root = bus_get_dev_root(&cpu_subsys); + if (dev_root) { + rc = device_create_file(dev_root, &dev_attr_dispatching); + put_device(dev_root); + } + return rc; } device_initcall(topology_init); diff --cc drivers/s390/crypto/ap_bus.c index 5a99e0b18289,70855af8c281..8d6b9a52bf3c --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@@ -1166,12 -1184,12 +1184,12 @@@ EXPORT_SYMBOL(ap_parse_mask_str) * AP bus attributes. */ -static ssize_t ap_domain_show(struct bus_type *bus, char *buf) +static ssize_t ap_domain_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%d\n", ap_domain_index); + return sysfs_emit(buf, "%d\n", ap_domain_index); } -static ssize_t ap_domain_store(struct bus_type *bus, +static ssize_t ap_domain_store(const struct bus_type *bus, const char *buf, size_t count) { int domain; @@@ -1193,65 -1211,61 +1211,61 @@@ static BUS_ATTR_RW(ap_domain); -static ssize_t ap_control_domain_mask_show(struct bus_type *bus, char *buf) +static ssize_t ap_control_domain_mask_show(const struct bus_type *bus, char *buf) { if (!ap_qci_info) /* QCI not supported */ - return scnprintf(buf, PAGE_SIZE, "not supported\n"); + return sysfs_emit(buf, "not supported\n"); - return scnprintf(buf, PAGE_SIZE, - "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", - ap_qci_info->adm[0], ap_qci_info->adm[1], - ap_qci_info->adm[2], ap_qci_info->adm[3], - ap_qci_info->adm[4], ap_qci_info->adm[5], - ap_qci_info->adm[6], ap_qci_info->adm[7]); + return sysfs_emit(buf, "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", + ap_qci_info->adm[0], ap_qci_info->adm[1], + ap_qci_info->adm[2], ap_qci_info->adm[3], + ap_qci_info->adm[4], ap_qci_info->adm[5], + ap_qci_info->adm[6], ap_qci_info->adm[7]); } static BUS_ATTR_RO(ap_control_domain_mask); -static ssize_t ap_usage_domain_mask_show(struct bus_type *bus, char *buf) +static ssize_t ap_usage_domain_mask_show(const struct bus_type *bus, char *buf) { if (!ap_qci_info) /* QCI not supported */ - return scnprintf(buf, PAGE_SIZE, "not supported\n"); + return sysfs_emit(buf, "not supported\n"); - return scnprintf(buf, PAGE_SIZE, - "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", - ap_qci_info->aqm[0], ap_qci_info->aqm[1], - ap_qci_info->aqm[2], ap_qci_info->aqm[3], - ap_qci_info->aqm[4], ap_qci_info->aqm[5], - ap_qci_info->aqm[6], ap_qci_info->aqm[7]); + return sysfs_emit(buf, "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", + ap_qci_info->aqm[0], ap_qci_info->aqm[1], + ap_qci_info->aqm[2], ap_qci_info->aqm[3], + ap_qci_info->aqm[4], ap_qci_info->aqm[5], + ap_qci_info->aqm[6], ap_qci_info->aqm[7]); } static BUS_ATTR_RO(ap_usage_domain_mask); -static ssize_t ap_adapter_mask_show(struct bus_type *bus, char *buf) +static ssize_t ap_adapter_mask_show(const struct bus_type *bus, char *buf) { if (!ap_qci_info) /* QCI not supported */ - return scnprintf(buf, PAGE_SIZE, "not supported\n"); + return sysfs_emit(buf, "not supported\n"); - return scnprintf(buf, PAGE_SIZE, - "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", - ap_qci_info->apm[0], ap_qci_info->apm[1], - ap_qci_info->apm[2], ap_qci_info->apm[3], - ap_qci_info->apm[4], ap_qci_info->apm[5], - ap_qci_info->apm[6], ap_qci_info->apm[7]); + return sysfs_emit(buf, "0x%08x%08x%08x%08x%08x%08x%08x%08x\n", + ap_qci_info->apm[0], ap_qci_info->apm[1], + ap_qci_info->apm[2], ap_qci_info->apm[3], + ap_qci_info->apm[4], ap_qci_info->apm[5], + ap_qci_info->apm[6], ap_qci_info->apm[7]); } static BUS_ATTR_RO(ap_adapter_mask); -static ssize_t ap_interrupts_show(struct bus_type *bus, char *buf) +static ssize_t ap_interrupts_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%d\n", - ap_irq_flag ? 1 : 0); + return sysfs_emit(buf, "%d\n", ap_irq_flag ? 1 : 0); } static BUS_ATTR_RO(ap_interrupts); -static ssize_t config_time_show(struct bus_type *bus, char *buf) +static ssize_t config_time_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%d\n", ap_config_time); + return sysfs_emit(buf, "%d\n", ap_config_time); } -static ssize_t config_time_store(struct bus_type *bus, +static ssize_t config_time_store(const struct bus_type *bus, const char *buf, size_t count) { int time; @@@ -1265,19 -1279,22 +1279,22 @@@ static BUS_ATTR_RW(config_time); -static ssize_t poll_thread_show(struct bus_type *bus, char *buf) +static ssize_t poll_thread_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%d\n", ap_poll_kthread ? 1 : 0); + return sysfs_emit(buf, "%d\n", ap_poll_kthread ? 1 : 0); } -static ssize_t poll_thread_store(struct bus_type *bus, +static ssize_t poll_thread_store(const struct bus_type *bus, const char *buf, size_t count) { - int flag, rc; + bool value; + int rc; - if (sscanf(buf, "%d\n", &flag) != 1) - return -EINVAL; - if (flag) { + rc = kstrtobool(buf, &value); + if (rc) + return rc; + + if (value) { rc = ap_poll_thread_start(); if (rc) count = rc; @@@ -1289,23 -1306,27 +1306,27 @@@ static BUS_ATTR_RW(poll_thread); -static ssize_t poll_timeout_show(struct bus_type *bus, char *buf) +static ssize_t poll_timeout_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%llu\n", poll_timeout); + return sysfs_emit(buf, "%lu\n", poll_high_timeout); } -static ssize_t poll_timeout_store(struct bus_type *bus, const char *buf, +static ssize_t poll_timeout_store(const struct bus_type *bus, const char *buf, size_t count) { - unsigned long long time; + unsigned long value; ktime_t hr_time; + int rc; + + rc = kstrtoul(buf, 0, &value); + if (rc) + return rc; /* 120 seconds = maximum poll interval */ - if (sscanf(buf, "%llu\n", &time) != 1 || time < 1 || - time > 120000000000ULL) + if (value > 120000000000UL) return -EINVAL; - poll_timeout = time; - hr_time = poll_timeout; + poll_high_timeout = value; + hr_time = poll_high_timeout; spin_lock_bh(&ap_poll_timer_lock); hrtimer_cancel(&ap_poll_timer); @@@ -1318,16 -1339,16 +1339,16 @@@ static BUS_ATTR_RW(poll_timeout); -static ssize_t ap_max_domain_id_show(struct bus_type *bus, char *buf) +static ssize_t ap_max_domain_id_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%d\n", ap_max_domain_id); + return sysfs_emit(buf, "%d\n", ap_max_domain_id); } static BUS_ATTR_RO(ap_max_domain_id); -static ssize_t ap_max_adapter_id_show(struct bus_type *bus, char *buf) +static ssize_t ap_max_adapter_id_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%d\n", ap_max_adapter_id); + return sysfs_emit(buf, "%d\n", ap_max_adapter_id); } static BUS_ATTR_RO(ap_max_adapter_id); @@@ -1518,13 -1537,12 +1537,12 @@@ done static BUS_ATTR_RW(aqmask); -static ssize_t scans_show(struct bus_type *bus, char *buf) +static ssize_t scans_show(const struct bus_type *bus, char *buf) { - return scnprintf(buf, PAGE_SIZE, "%llu\n", - atomic64_read(&ap_scan_bus_count)); + return sysfs_emit(buf, "%llu\n", atomic64_read(&ap_scan_bus_count)); } -static ssize_t scans_store(struct bus_type *bus, const char *buf, +static ssize_t scans_store(const struct bus_type *bus, const char *buf, size_t count) { AP_DBF_INFO("%s force AP bus rescan\n", __func__); @@@ -1552,6 -1570,31 +1570,31 @@@ static ssize_t bindings_show(const stru static BUS_ATTR_RO(bindings); -static ssize_t features_show(struct bus_type *bus, char *buf) ++static ssize_t features_show(const struct bus_type *bus, char *buf) + { + int n = 0; + + if (!ap_qci_info) /* QCI not supported */ + return sysfs_emit(buf, "-\n"); + + if (ap_qci_info->apsc) + n += sysfs_emit_at(buf, n, "APSC "); + if (ap_qci_info->apxa) + n += sysfs_emit_at(buf, n, "APXA "); + if (ap_qci_info->qact) + n += sysfs_emit_at(buf, n, "QACT "); + if (ap_qci_info->rc8a) + n += sysfs_emit_at(buf, n, "RC8A "); + if (ap_qci_info->apsb) + n += sysfs_emit_at(buf, n, "APSB "); + + sysfs_emit_at(buf, n == 0 ? 0 : n - 1, "\n"); + + return n; + } + + static BUS_ATTR_RO(features); + static struct attribute *ap_bus_attrs[] = { &bus_attr_ap_domain.attr, &bus_attr_ap_control_domain_mask.attr,