OSDN Git Service

Merge tag 's390-5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 May 2021 21:39:50 +0000 (14:39 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 6 May 2021 21:39:50 +0000 (14:39 -0700)
Pull more s390 updates from Heiko Carstens:

 - add support for system call stack randomization

 - handle stale PCI deconfiguration events

 - couple of defconfig updates

 - some fixes and cleanups

* tag 's390-5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390: fix detection of vector enhancements facility 1 vs. vector packed decimal facility
  s390/entry: add support for syscall stack randomization
  s390/configs: change CONFIG_VIRTIO_CONSOLE to "m"
  s390/cio: remove invalid condition on IO_SCH_UNREG
  s390/cpumf: remove call to perf_event_update_userpage
  s390/cpumf: move counter set size calculation to common place
  s390/cpumf: beautify if-then-else indentation
  s390/configs: enable CONFIG_PCI_IOV
  s390/pci: handle stale deconfiguration events
  s390/pci: rename zpci_configure_device()

16 files changed:
arch/s390/Kconfig
arch/s390/configs/debug_defconfig
arch/s390/configs/defconfig
arch/s390/include/asm/cpu_mcf.h
arch/s390/include/asm/entry-common.h
arch/s390/include/asm/pci.h
arch/s390/kernel/perf_cpum_cf.c
arch/s390/kernel/perf_cpum_cf_common.c
arch/s390/kernel/perf_cpum_cf_diag.c
arch/s390/kernel/setup.c
arch/s390/kernel/syscall.c
arch/s390/kernel/traps.c
arch/s390/pci/pci.c
arch/s390/pci/pci_event.c
drivers/pci/hotplug/s390_pci_hpc.c
drivers/s390/cio/device.c

index d729895..b4c7c34 100644 (file)
@@ -140,6 +140,7 @@ config S390
        select HAVE_ARCH_JUMP_LABEL_RELATIVE
        select HAVE_ARCH_KASAN
        select HAVE_ARCH_KASAN_VMALLOC
+       select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
        select HAVE_ARCH_SECCOMP_FILTER
        select HAVE_ARCH_SOFT_DIRTY
        select HAVE_ARCH_TRACEHOOK
index 6422618..86afcc6 100644 (file)
@@ -387,6 +387,7 @@ CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
 CONFIG_PCI=y
+CONFIG_PCI_IOV=y
 # CONFIG_PCIEASPM is not set
 CONFIG_PCI_DEBUG=y
 CONFIG_HOTPLUG_PCI=y
@@ -548,7 +549,7 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 CONFIG_LEGACY_PTY_COUNT=0
-CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_CONSOLE=m
 CONFIG_HW_RANDOM_VIRTIO=m
 CONFIG_RAW_DRIVER=m
 CONFIG_HANGCHECK_TIMER=m
index 371a529..71b49ea 100644 (file)
@@ -377,6 +377,7 @@ CONFIG_CGROUP_NET_PRIO=y
 CONFIG_BPF_JIT=y
 CONFIG_NET_PKTGEN=m
 CONFIG_PCI=y
+CONFIG_PCI_IOV=y
 # CONFIG_PCIEASPM is not set
 CONFIG_HOTPLUG_PCI=y
 CONFIG_HOTPLUG_PCI_S390=y
@@ -540,7 +541,7 @@ CONFIG_INPUT_EVDEV=y
 # CONFIG_INPUT_MOUSE is not set
 # CONFIG_SERIO is not set
 CONFIG_LEGACY_PTY_COUNT=0
-CONFIG_VIRTIO_CONSOLE=y
+CONFIG_VIRTIO_CONSOLE=m
 CONFIG_HW_RANDOM_VIRTIO=m
 CONFIG_RAW_DRIVER=m
 CONFIG_HANGCHECK_TIMER=m
index 649b9fc..3e4cbcb 100644 (file)
@@ -123,4 +123,6 @@ static inline int stccm_avail(void)
        return test_facility(142);
 }
 
+size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
+                          struct cpumf_ctr_info *info);
 #endif /* _ASM_S390_CPU_MCF_H */
index 9cceb26..baa8005 100644 (file)
@@ -4,9 +4,11 @@
 
 #include <linux/sched.h>
 #include <linux/audit.h>
+#include <linux/randomize_kstack.h>
 #include <linux/tracehook.h>
 #include <linux/processor.h>
 #include <linux/uaccess.h>
+#include <asm/timex.h>
 #include <asm/fpu/api.h>
 
 #define ARCH_EXIT_TO_USER_MODE_WORK (_TIF_GUARDED_STORAGE | _TIF_PER_TRAP)
@@ -48,6 +50,14 @@ static __always_inline void arch_exit_to_user_mode(void)
 
 #define arch_exit_to_user_mode arch_exit_to_user_mode
 
+static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
+                                                 unsigned long ti_work)
+{
+       choose_random_kstack_offset(get_tod_clock_fast() & 0xff);
+}
+
+#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
+
 static inline bool on_thread_stack(void)
 {
        return !(((unsigned long)(current->stack) ^ current_stack_pointer()) & ~(THREAD_SIZE - 1));
index 35c2af9..10b67f8 100644 (file)
@@ -204,7 +204,7 @@ extern unsigned int s390_pci_no_rid;
 struct zpci_dev *zpci_create_device(u32 fid, u32 fh, enum zpci_state state);
 int zpci_enable_device(struct zpci_dev *);
 int zpci_disable_device(struct zpci_dev *);
-int zpci_configure_device(struct zpci_dev *zdev, u32 fh);
+int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh);
 int zpci_deconfigure_device(struct zpci_dev *zdev);
 
 int zpci_register_ioat(struct zpci_dev *, u8, u64, u64, u64);
index b3beef6..31a605b 100644 (file)
@@ -230,9 +230,7 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type)
                /* No support for kernel space counters only */
                } else if (!attr->exclude_kernel && attr->exclude_user) {
                        return -EOPNOTSUPP;
-
-               /* Count user and kernel space */
-               } else {
+               } else {        /* Count user and kernel space */
                        if (ev >= ARRAY_SIZE(cpumf_generic_events_basic))
                                return -EOPNOTSUPP;
                        ev = cpumf_generic_events_basic[ev];
@@ -402,12 +400,12 @@ static void cpumf_pmu_stop(struct perf_event *event, int flags)
                 */
                if (!atomic_dec_return(&cpuhw->ctr_set[hwc->config_base]))
                        ctr_set_stop(&cpuhw->state, hwc->config_base);
-               event->hw.state |= PERF_HES_STOPPED;
+               hwc->state |= PERF_HES_STOPPED;
        }
 
        if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
                hw_perf_event_update(event);
-               event->hw.state |= PERF_HES_UPTODATE;
+               hwc->state |= PERF_HES_UPTODATE;
        }
 }
 
@@ -430,8 +428,6 @@ static int cpumf_pmu_add(struct perf_event *event, int flags)
        if (flags & PERF_EF_START)
                cpumf_pmu_start(event, PERF_EF_RELOAD);
 
-       perf_event_update_userpage(event);
-
        return 0;
 }
 
@@ -451,8 +447,6 @@ static void cpumf_pmu_del(struct perf_event *event, int flags)
         */
        if (!atomic_read(&cpuhw->ctr_set[event->hw.config_base]))
                ctr_set_disable(&cpuhw->state, event->hw.config_base);
-
-       perf_event_update_userpage(event);
 }
 
 /*
index 3bced89..6d53215 100644 (file)
@@ -170,6 +170,52 @@ static int cpum_cf_offline_cpu(unsigned int cpu)
        return cpum_cf_setup(cpu, PMC_RELEASE);
 }
 
+/* Return the maximum possible counter set size (in number of 8 byte counters)
+ * depending on type and model number.
+ */
+size_t cpum_cf_ctrset_size(enum cpumf_ctr_set ctrset,
+                          struct cpumf_ctr_info *info)
+{
+       size_t ctrset_size = 0;
+
+       switch (ctrset) {
+       case CPUMF_CTR_SET_BASIC:
+               if (info->cfvn >= 1)
+                       ctrset_size = 6;
+               break;
+       case CPUMF_CTR_SET_USER:
+               if (info->cfvn == 1)
+                       ctrset_size = 6;
+               else if (info->cfvn >= 3)
+                       ctrset_size = 2;
+               break;
+       case CPUMF_CTR_SET_CRYPTO:
+               if (info->csvn >= 1 && info->csvn <= 5)
+                       ctrset_size = 16;
+               else if (info->csvn == 6)
+                       ctrset_size = 20;
+               break;
+       case CPUMF_CTR_SET_EXT:
+               if (info->csvn == 1)
+                       ctrset_size = 32;
+               else if (info->csvn == 2)
+                       ctrset_size = 48;
+               else if (info->csvn >= 3 && info->csvn <= 5)
+                       ctrset_size = 128;
+               else if (info->csvn == 6)
+                       ctrset_size = 160;
+               break;
+       case CPUMF_CTR_SET_MT_DIAG:
+               if (info->csvn > 3)
+                       ctrset_size = 48;
+               break;
+       case CPUMF_CTR_SET_MAX:
+               break;
+       }
+
+       return ctrset_size;
+}
+
 static int __init cpum_cf_init(void)
 {
        int rc;
index 2e3e7ed..08c985c 100644 (file)
@@ -316,52 +316,6 @@ static void cf_diag_read(struct perf_event *event)
        debug_sprintf_event(cf_diag_dbg, 5, "%s event %p\n", __func__, event);
 }
 
-/* Return the maximum possible counter set size (in number of 8 byte counters)
- * depending on type and model number.
- */
-static size_t cf_diag_ctrset_size(enum cpumf_ctr_set ctrset,
-                                struct cpumf_ctr_info *info)
-{
-       size_t ctrset_size = 0;
-
-       switch (ctrset) {
-       case CPUMF_CTR_SET_BASIC:
-               if (info->cfvn >= 1)
-                       ctrset_size = 6;
-               break;
-       case CPUMF_CTR_SET_USER:
-               if (info->cfvn == 1)
-                       ctrset_size = 6;
-               else if (info->cfvn >= 3)
-                       ctrset_size = 2;
-               break;
-       case CPUMF_CTR_SET_CRYPTO:
-               if (info->csvn >= 1 && info->csvn <= 5)
-                       ctrset_size = 16;
-               else if (info->csvn == 6)
-                       ctrset_size = 20;
-               break;
-       case CPUMF_CTR_SET_EXT:
-               if (info->csvn == 1)
-                       ctrset_size = 32;
-               else if (info->csvn == 2)
-                       ctrset_size = 48;
-               else if (info->csvn >= 3 && info->csvn <= 5)
-                       ctrset_size = 128;
-               else if (info->csvn == 6)
-                       ctrset_size = 160;
-               break;
-       case CPUMF_CTR_SET_MT_DIAG:
-               if (info->csvn > 3)
-                       ctrset_size = 48;
-               break;
-       case CPUMF_CTR_SET_MAX:
-               break;
-       }
-
-       return ctrset_size;
-}
-
 /* Calculate memory needed to store all counter sets together with header and
  * trailer data. This is independend of the counter set authorization which
  * can vary depending on the configuration.
@@ -372,7 +326,7 @@ static size_t cf_diag_ctrset_maxsize(struct cpumf_ctr_info *info)
        enum cpumf_ctr_set i;
 
        for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) {
-               size_t size = cf_diag_ctrset_size(i, info);
+               size_t size = cpum_cf_ctrset_size(i, info);
 
                if (size)
                        max_size += size * sizeof(u64) +
@@ -405,7 +359,7 @@ static size_t cf_diag_getctrset(struct cf_ctrset_entry *ctrdata, int ctrset,
        ctrdata->def = CF_DIAG_CTRSET_DEF;
        ctrdata->set = ctrset;
        ctrdata->res1 = 0;
-       ctrset_size = cf_diag_ctrset_size(ctrset, &cpuhw->info);
+       ctrset_size = cpum_cf_ctrset_size(ctrset, &cpuhw->info);
 
        if (ctrset_size) {                      /* Save data */
                need = ctrset_size * sizeof(u64) + sizeof(*ctrdata);
@@ -845,7 +799,7 @@ static void cf_diag_cpu_read(void *parm)
 
                if (!(p->sets & cpumf_ctr_ctl[set]))
                        continue;       /* Counter set not in list */
-               set_size = cf_diag_ctrset_size(set, &cpuhw->info);
+               set_size = cpum_cf_ctrset_size(set, &cpuhw->info);
                space = sizeof(csd->data) - csd->used;
                space = cf_diag_cpuset_read(sp, set, set_size, space);
                if (space) {
@@ -975,7 +929,7 @@ static size_t cf_diag_needspace(unsigned int sets)
        for (i = CPUMF_CTR_SET_BASIC; i < CPUMF_CTR_SET_MAX; ++i) {
                if (!(sets & cpumf_ctr_ctl[i]))
                        continue;
-               bytes += cf_diag_ctrset_size(i, &cpuhw->info) * sizeof(u64) +
+               bytes += cpum_cf_ctrset_size(i, &cpuhw->info) * sizeof(u64) +
                         sizeof(((struct s390_ctrset_setdata *)0)->set) +
                         sizeof(((struct s390_ctrset_setdata *)0)->no_cnts);
        }
index 72134f9..5aab59a 100644 (file)
@@ -937,9 +937,9 @@ static int __init setup_hwcaps(void)
        if (MACHINE_HAS_VX) {
                elf_hwcap |= HWCAP_S390_VXRS;
                if (test_facility(134))
-                       elf_hwcap |= HWCAP_S390_VXRS_EXT;
-               if (test_facility(135))
                        elf_hwcap |= HWCAP_S390_VXRS_BCD;
+               if (test_facility(135))
+                       elf_hwcap |= HWCAP_S390_VXRS_EXT;
                if (test_facility(148))
                        elf_hwcap |= HWCAP_S390_VXRS_EXT2;
                if (test_facility(152))
index bc8e650..4e5cc7d 100644 (file)
@@ -142,6 +142,7 @@ void do_syscall(struct pt_regs *regs)
 
 void noinstr __do_syscall(struct pt_regs *regs, int per_trap)
 {
+       add_random_kstack_offset();
        enter_from_user_mode(regs);
 
        memcpy(&regs->gprs[8], S390_lowcore.save_area_sync, 8 * sizeof(unsigned long));
index 63021d4..8dd23c7 100644 (file)
@@ -17,6 +17,7 @@
 #include "asm/ptrace.h"
 #include <linux/kprobes.h>
 #include <linux/kdebug.h>
+#include <linux/randomize_kstack.h>
 #include <linux/extable.h>
 #include <linux/ptrace.h>
 #include <linux/sched.h>
@@ -301,6 +302,7 @@ void noinstr __do_pgm_check(struct pt_regs *regs)
        unsigned int trapnr, syscall_redirect = 0;
        irqentry_state_t state;
 
+       add_random_kstack_offset();
        regs->int_code = *(u32 *)&S390_lowcore.pgm_ilc;
        regs->int_parm_long = S390_lowcore.trans_exc_code;
 
index c01b6db..b0993e0 100644 (file)
@@ -738,17 +738,19 @@ error:
 }
 
 /**
- * zpci_configure_device() - Configure a zpci_dev
+ * zpci_scan_configured_device() - Scan a freshly configured zpci_dev
  * @zdev: The zpci_dev to be configured
  * @fh: The general function handle supplied by the platform
  *
  * Given a device in the configuration state Configured, enables, scans and
- * adds it to the common code PCI subsystem. If any failure occurs, the
- * zpci_dev is left disabled.
+ * adds it to the common code PCI subsystem if possible. If the PCI device is
+ * parked because we can not yet create a PCI bus because we have not seen
+ * function 0, it is ignored but will be scanned once function 0 appears.
+ * If any failure occurs, the zpci_dev is left disabled.
  *
  * Return: 0 on success, or an error code otherwise
  */
-int zpci_configure_device(struct zpci_dev *zdev, u32 fh)
+int zpci_scan_configured_device(struct zpci_dev *zdev, u32 fh)
 {
        int rc;
 
index 1178b48..cd447b9 100644 (file)
@@ -76,8 +76,6 @@ void zpci_event_error(void *data)
 
 static void zpci_event_hard_deconfigured(struct zpci_dev *zdev, u32 fh)
 {
-       enum zpci_state state;
-
        zdev->fh = fh;
        /* Give the driver a hint that the function is
         * already unusable.
@@ -88,15 +86,12 @@ static void zpci_event_hard_deconfigured(struct zpci_dev *zdev, u32 fh)
         */
        zpci_disable_device(zdev);
        zdev->state = ZPCI_FN_STATE_STANDBY;
-       if (!clp_get_state(zdev->fid, &state) &&
-           state == ZPCI_FN_STATE_RESERVED) {
-               zpci_zdev_put(zdev);
-       }
 }
 
 static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
 {
        struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
+       enum zpci_state state;
 
        zpci_err("avail CCDF:\n");
        zpci_err_hex(ccdf, sizeof(*ccdf));
@@ -113,7 +108,7 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
                                break;
                        zdev->state = ZPCI_FN_STATE_CONFIGURED;
                }
-               zpci_configure_device(zdev, ccdf->fh);
+               zpci_scan_configured_device(zdev, ccdf->fh);
                break;
        case 0x0302: /* Reserved -> Standby */
                if (!zdev)
@@ -123,13 +118,28 @@ static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
                break;
        case 0x0303: /* Deconfiguration requested */
                if (zdev) {
+                       /* The event may have been queued before we confirgured
+                        * the device.
+                        */
+                       if (zdev->state != ZPCI_FN_STATE_CONFIGURED)
+                               break;
                        zdev->fh = ccdf->fh;
                        zpci_deconfigure_device(zdev);
                }
                break;
        case 0x0304: /* Configured -> Standby|Reserved */
-               if (zdev)
-                       zpci_event_hard_deconfigured(zdev, ccdf->fh);
+               if (zdev) {
+                       /* The event may have been queued before we confirgured
+                        * the device.:
+                        */
+                       if (zdev->state == ZPCI_FN_STATE_CONFIGURED)
+                               zpci_event_hard_deconfigured(zdev, ccdf->fh);
+                       /* The 0x0304 event may immediately reserve the device */
+                       if (!clp_get_state(zdev->fid, &state) &&
+                           state == ZPCI_FN_STATE_RESERVED) {
+                               zpci_zdev_put(zdev);
+                       }
+               }
                break;
        case 0x0306: /* 0x308 or 0x302 for multiple devices */
                zpci_remove_reserved_devices();
index f8f056b..0148687 100644 (file)
@@ -35,7 +35,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot)
                return rc;
        zdev->state = ZPCI_FN_STATE_CONFIGURED;
 
-       return zpci_configure_device(zdev, zdev->fh);
+       return zpci_scan_configured_device(zdev, zdev->fh);
 }
 
 static int disable_slot(struct hotplug_slot *hotplug_slot)
index 3f02602..84f659c 100644 (file)
@@ -1532,8 +1532,7 @@ static int io_subchannel_sch_event(struct subchannel *sch, int process)
        switch (action) {
        case IO_SCH_ORPH_UNREG:
        case IO_SCH_UNREG:
-               if (!cdev)
-                       css_sch_device_unregister(sch);
+               css_sch_device_unregister(sch);
                break;
        case IO_SCH_ORPH_ATTACH:
        case IO_SCH_UNREG_ATTACH: