Merge tag 's390-6.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 30 Apr 2023 18:43:31 +0000 (11:43 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 30 Apr 2023 18:43:31 +0000 (11:43 -0700)
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.
  ...

1  2 
arch/s390/Kconfig
arch/s390/include/asm/pgtable.h
arch/s390/kernel/mcount.S
arch/s390/kernel/module.c
arch/s390/kernel/setup.c
arch/s390/kernel/smp.c
arch/s390/kernel/topology.c
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/vfio_ap_drv.c
drivers/s390/crypto/zcrypt_api.c
lib/Kconfig.debug

index 61d778397720a5243043e508d1712d049371555c,574bd48199f2abe6c3a924e912aa62af8a2c743e..beb62f744c61e2d25c80149e8b44cdeb98fe7bb9
@@@ -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
Simple merge
index 6c10da43b5385e39f03c00f4a9d0462100e83260,a7902fdb7ba292c791bc325e43cd06f98b71a03e..dbece2803c50bd03d7e03d5b4c41f3b349ad8eb8
  
        .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
  
Simple merge
index 4259b6c505163ce9011ecd6ffeb3d6902a1b6c1e,0903fe35663410fb01760b494e4e7f67452b959f..fe10da1a271e867966c2635e0ae1c4f5280a8f8f
@@@ -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;
  
Simple merge
index 72af753d1bbaccab94628a28fa7a782ef2ced82d,e5d6a1c25d13affa166a53b1402ca47cbfc10fa1..9fd19530c9a5623d5901abb1dd9e2032238203ba
@@@ -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);
index 5a99e0b1828975c06a76fae93facaabe20c35ba4,70855af8c2816f379409c4a84a9c0e75740f5e20..8d6b9a52bf3cbd1a711ab75df24e032acaeb8385
@@@ -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;
  
  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;
  
  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;
  
  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);
  
  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,
Simple merge
Simple merge
Simple merge