diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 16:16:16 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 16:16:16 -0500 |
commit | cbd88cd4c07f9361914ab7fd7e21c9227986fe68 (patch) | |
tree | 8bc448d73f93f10ebd34ef38c911b06359000ed0 | |
parent | 928b3f12e5fea9d201bbc029d8d537ba7cc14fe7 (diff) | |
parent | c2ab7282f0fcd11eea4d0ba45d1c65d89428c314 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 updates from Martin Schwidefsky:
"Among the traditional bug fixes and cleanups are some improvements:
- A tool to generated the facility lists, generating the bit fields
by hand has been a source of bugs in the past
- The spinlock loop is reordered to avoid bursts of hypervisor calls
- Add support for the open-for-business interface to the service
element
- The get_cpu call is added to the vdso
- A set of tracepoints is defined for the common I/O layer
- The deprecated sclp_cpi module is removed
- Update default configuration"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: (56 commits)
s390/sclp: fix possible control register corruption
s390: fix normalization bug in exception table sorting
s390/configs: update default configurations
s390/vdso: optimize getcpu system call
s390: drop smp_mb in vdso_init
s390: rename struct _lowcore to struct lowcore
s390/mem_detect: use unsigned longs
s390/ptrace: get rid of long longs in psw_bits
s390/sysinfo: add missing SYSIB 1.2.2 multithreading fields
s390: get rid of CONFIG_SCHED_MC and CONFIG_SCHED_BOOK
s390/Kconfig: remove pointless 64 bit dependencies
s390/dasd: fix failfast for disconnected devices
s390/con3270: testing return kzalloc retval
s390/hmcdrv: constify hmcdrv_ftp_ops structs
s390/cio: add NULL test
s390/cio: Change I/O instructions from inline to normal functions
s390/cio: Introduce common I/O layer tracepoints
s390/cio: Consolidate inline assemblies and related data definitions
s390/cio: Fix incorrect xsch opcode specification
s390/cio: Remove unused inline assemblies
...
93 files changed, 1948 insertions, 1567 deletions
diff --git a/Documentation/s390/zfcpdump.txt b/Documentation/s390/zfcpdump.txt index dc929be96016..b064aa59714d 100644 --- a/Documentation/s390/zfcpdump.txt +++ b/Documentation/s390/zfcpdump.txt | |||
@@ -15,19 +15,15 @@ the s390-tools package) to make the device bootable. The operator of a Linux | |||
15 | system can then trigger a SCSI dump by booting the SCSI disk, where zfcpdump | 15 | system can then trigger a SCSI dump by booting the SCSI disk, where zfcpdump |
16 | resides on. | 16 | resides on. |
17 | 17 | ||
18 | The kernel part of zfcpdump is implemented as a debugfs file under "zcore/mem", | 18 | The user space dump tool accesses the memory of the crashed system by means |
19 | which exports memory and registers of the crashed Linux in an s390 | 19 | of the /proc/vmcore interface. This interface exports the crashed system's |
20 | standalone dump format. It can be used in the same way as e.g. /dev/mem. The | 20 | memory and registers in ELF core dump format. To access the memory which has |
21 | dump format defines a 4K header followed by plain uncompressed memory. The | 21 | been saved by the hardware SCLP requests will be created at the time the data |
22 | register sets are stored in the prefix pages of the respective CPUs. To build a | 22 | is needed by /proc/vmcore. The tail part of the crashed systems memory which |
23 | dump enabled kernel with the zcore driver, the kernel config option | 23 | has not been stashed by hardware can just be copied from real memory. |
24 | CONFIG_CRASH_DUMP has to be set. When reading from "zcore/mem", the part of | 24 | |
25 | memory, which has been saved by hardware is read by the driver via the SCLP | 25 | To build a dump enabled kernel the kernel config option CONFIG_CRASH_DUMP |
26 | hardware interface. The second part is just copied from the non overwritten real | 26 | has to be set. |
27 | memory. | ||
28 | |||
29 | Since kernel version 3.12 also the /proc/vmcore file can also be used to access | ||
30 | the dump. | ||
31 | 27 | ||
32 | To get a valid zfcpdump kernel configuration use "make zfcpdump_defconfig". | 28 | To get a valid zfcpdump kernel configuration use "make zfcpdump_defconfig". |
33 | 29 | ||
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 3a55f493c7da..6d0ae7d30724 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -166,8 +166,7 @@ config SCHED_OMIT_FRAME_POINTER | |||
166 | 166 | ||
167 | config PGTABLE_LEVELS | 167 | config PGTABLE_LEVELS |
168 | int | 168 | int |
169 | default 4 if 64BIT | 169 | default 4 |
170 | default 2 | ||
171 | 170 | ||
172 | source "init/Kconfig" | 171 | source "init/Kconfig" |
173 | 172 | ||
@@ -390,9 +389,6 @@ config HOTPLUG_CPU | |||
390 | can be controlled through /sys/devices/system/cpu/cpu#. | 389 | can be controlled through /sys/devices/system/cpu/cpu#. |
391 | Say N if you want to disable CPU hotplug. | 390 | Say N if you want to disable CPU hotplug. |
392 | 391 | ||
393 | config SCHED_SMT | ||
394 | def_bool n | ||
395 | |||
396 | # Some NUMA nodes have memory ranges that span | 392 | # Some NUMA nodes have memory ranges that span |
397 | # other nodes. Even though a pfn is valid and | 393 | # other nodes. Even though a pfn is valid and |
398 | # between a node's start and end pfns, it may not | 394 | # between a node's start and end pfns, it may not |
@@ -403,7 +399,7 @@ config NODES_SPAN_OTHER_NODES | |||
403 | 399 | ||
404 | config NUMA | 400 | config NUMA |
405 | bool "NUMA support" | 401 | bool "NUMA support" |
406 | depends on SMP && 64BIT && SCHED_TOPOLOGY | 402 | depends on SMP && SCHED_TOPOLOGY |
407 | default n | 403 | default n |
408 | help | 404 | help |
409 | Enable NUMA support | 405 | Enable NUMA support |
@@ -463,6 +459,9 @@ config EMU_SIZE | |||
463 | 459 | ||
464 | endmenu | 460 | endmenu |
465 | 461 | ||
462 | config SCHED_SMT | ||
463 | def_bool n | ||
464 | |||
466 | config SCHED_MC | 465 | config SCHED_MC |
467 | def_bool n | 466 | def_bool n |
468 | 467 | ||
diff --git a/arch/s390/Makefile b/arch/s390/Makefile index e8d4423e4f85..224b42734f0d 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile | |||
@@ -106,6 +106,7 @@ drivers-y += drivers/s390/ | |||
106 | drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ | 106 | drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ |
107 | 107 | ||
108 | boot := arch/s390/boot | 108 | boot := arch/s390/boot |
109 | tools := arch/s390/tools | ||
109 | 110 | ||
110 | all: image bzImage | 111 | all: image bzImage |
111 | 112 | ||
@@ -124,9 +125,17 @@ vdso_install: | |||
124 | 125 | ||
125 | archclean: | 126 | archclean: |
126 | $(Q)$(MAKE) $(clean)=$(boot) | 127 | $(Q)$(MAKE) $(clean)=$(boot) |
128 | $(Q)$(MAKE) $(clean)=$(tools) | ||
129 | |||
130 | archprepare: | ||
131 | $(Q)$(MAKE) $(build)=$(tools) include/generated/facilities.h | ||
127 | 132 | ||
128 | # Don't use tabs in echo arguments | 133 | # Don't use tabs in echo arguments |
129 | define archhelp | 134 | define archhelp |
130 | echo '* image - Kernel image for IPL ($(boot)/image)' | 135 | echo '* image - Kernel image for IPL ($(boot)/image)' |
131 | echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)' | 136 | echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)' |
137 | echo ' install - Install kernel using' | ||
138 | echo ' (your) ~/bin/$(INSTALLKERNEL) or' | ||
139 | echo ' (distribution) /sbin/$(INSTALLKERNEL) or' | ||
140 | echo ' install to $$(INSTALL_PATH)' | ||
132 | endef | 141 | endef |
diff --git a/arch/s390/configs/default_defconfig b/arch/s390/configs/default_defconfig index ed7da281df66..0ac42cc4f880 100644 --- a/arch/s390/configs/default_defconfig +++ b/arch/s390/configs/default_defconfig | |||
@@ -10,28 +10,35 @@ CONFIG_TASKSTATS=y | |||
10 | CONFIG_TASK_DELAY_ACCT=y | 10 | CONFIG_TASK_DELAY_ACCT=y |
11 | CONFIG_TASK_XACCT=y | 11 | CONFIG_TASK_XACCT=y |
12 | CONFIG_TASK_IO_ACCOUNTING=y | 12 | CONFIG_TASK_IO_ACCOUNTING=y |
13 | CONFIG_RCU_FAST_NO_HZ=y | ||
14 | CONFIG_IKCONFIG=y | 13 | CONFIG_IKCONFIG=y |
15 | CONFIG_IKCONFIG_PROC=y | 14 | CONFIG_IKCONFIG_PROC=y |
16 | CONFIG_NUMA_BALANCING=y | 15 | CONFIG_NUMA_BALANCING=y |
17 | CONFIG_CGROUP_FREEZER=y | 16 | CONFIG_CGROUP_FREEZER=y |
17 | CONFIG_CGROUP_PIDS=y | ||
18 | CONFIG_CGROUP_DEVICE=y | 18 | CONFIG_CGROUP_DEVICE=y |
19 | CONFIG_CPUSETS=y | 19 | CONFIG_CPUSETS=y |
20 | CONFIG_CGROUP_CPUACCT=y | 20 | CONFIG_CGROUP_CPUACCT=y |
21 | CONFIG_MEMCG=y | ||
22 | CONFIG_MEMCG_SWAP=y | ||
23 | CONFIG_MEMCG_KMEM=y | ||
24 | CONFIG_CGROUP_HUGETLB=y | ||
21 | CONFIG_CGROUP_PERF=y | 25 | CONFIG_CGROUP_PERF=y |
22 | CONFIG_CFS_BANDWIDTH=y | 26 | CONFIG_CFS_BANDWIDTH=y |
23 | CONFIG_RT_GROUP_SCHED=y | 27 | CONFIG_RT_GROUP_SCHED=y |
24 | CONFIG_BLK_CGROUP=y | 28 | CONFIG_BLK_CGROUP=y |
25 | CONFIG_NAMESPACES=y | 29 | CONFIG_NAMESPACES=y |
30 | CONFIG_USER_NS=y | ||
26 | CONFIG_SCHED_AUTOGROUP=y | 31 | CONFIG_SCHED_AUTOGROUP=y |
27 | CONFIG_BLK_DEV_INITRD=y | 32 | CONFIG_BLK_DEV_INITRD=y |
28 | CONFIG_EXPERT=y | 33 | CONFIG_EXPERT=y |
29 | CONFIG_BPF_SYSCALL=y | 34 | CONFIG_BPF_SYSCALL=y |
35 | CONFIG_USERFAULTFD=y | ||
30 | # CONFIG_COMPAT_BRK is not set | 36 | # CONFIG_COMPAT_BRK is not set |
31 | CONFIG_PROFILING=y | 37 | CONFIG_PROFILING=y |
32 | CONFIG_OPROFILE=m | 38 | CONFIG_OPROFILE=m |
33 | CONFIG_KPROBES=y | 39 | CONFIG_KPROBES=y |
34 | CONFIG_JUMP_LABEL=y | 40 | CONFIG_JUMP_LABEL=y |
41 | CONFIG_STATIC_KEYS_SELFTEST=y | ||
35 | CONFIG_MODULES=y | 42 | CONFIG_MODULES=y |
36 | CONFIG_MODULE_FORCE_LOAD=y | 43 | CONFIG_MODULE_FORCE_LOAD=y |
37 | CONFIG_MODULE_UNLOAD=y | 44 | CONFIG_MODULE_UNLOAD=y |
@@ -64,7 +71,6 @@ CONFIG_HOTPLUG_PCI=y | |||
64 | CONFIG_HOTPLUG_PCI_S390=y | 71 | CONFIG_HOTPLUG_PCI_S390=y |
65 | CONFIG_CHSC_SCH=y | 72 | CONFIG_CHSC_SCH=y |
66 | CONFIG_CRASH_DUMP=y | 73 | CONFIG_CRASH_DUMP=y |
67 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
68 | CONFIG_BINFMT_MISC=m | 74 | CONFIG_BINFMT_MISC=m |
69 | CONFIG_HIBERNATION=y | 75 | CONFIG_HIBERNATION=y |
70 | CONFIG_NET=y | 76 | CONFIG_NET=y |
@@ -106,7 +112,6 @@ CONFIG_TCP_CONG_LP=m | |||
106 | CONFIG_TCP_CONG_VENO=m | 112 | CONFIG_TCP_CONG_VENO=m |
107 | CONFIG_TCP_CONG_YEAH=m | 113 | CONFIG_TCP_CONG_YEAH=m |
108 | CONFIG_TCP_CONG_ILLINOIS=m | 114 | CONFIG_TCP_CONG_ILLINOIS=m |
109 | CONFIG_IPV6=y | ||
110 | CONFIG_IPV6_ROUTER_PREF=y | 115 | CONFIG_IPV6_ROUTER_PREF=y |
111 | CONFIG_INET6_AH=m | 116 | CONFIG_INET6_AH=m |
112 | CONFIG_INET6_ESP=m | 117 | CONFIG_INET6_ESP=m |
@@ -457,19 +462,9 @@ CONFIG_INFINIBAND=m | |||
457 | CONFIG_INFINIBAND_USER_ACCESS=m | 462 | CONFIG_INFINIBAND_USER_ACCESS=m |
458 | CONFIG_MLX4_INFINIBAND=m | 463 | CONFIG_MLX4_INFINIBAND=m |
459 | CONFIG_VIRTIO_BALLOON=m | 464 | CONFIG_VIRTIO_BALLOON=m |
460 | # CONFIG_IOMMU_SUPPORT is not set | ||
461 | CONFIG_EXT2_FS=y | ||
462 | CONFIG_EXT2_FS_XATTR=y | ||
463 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
464 | CONFIG_EXT2_FS_SECURITY=y | ||
465 | CONFIG_EXT3_FS=y | ||
466 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
467 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
468 | CONFIG_EXT3_FS_SECURITY=y | ||
469 | CONFIG_EXT4_FS=y | 465 | CONFIG_EXT4_FS=y |
470 | CONFIG_EXT4_FS_POSIX_ACL=y | 466 | CONFIG_EXT4_FS_POSIX_ACL=y |
471 | CONFIG_EXT4_FS_SECURITY=y | 467 | CONFIG_EXT4_FS_SECURITY=y |
472 | CONFIG_JBD_DEBUG=y | ||
473 | CONFIG_JBD2_DEBUG=y | 468 | CONFIG_JBD2_DEBUG=y |
474 | CONFIG_JFS_FS=m | 469 | CONFIG_JFS_FS=m |
475 | CONFIG_JFS_POSIX_ACL=y | 470 | CONFIG_JFS_POSIX_ACL=y |
@@ -490,7 +485,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y | |||
490 | CONFIG_QFMT_V1=m | 485 | CONFIG_QFMT_V1=m |
491 | CONFIG_QFMT_V2=m | 486 | CONFIG_QFMT_V2=m |
492 | CONFIG_AUTOFS4_FS=m | 487 | CONFIG_AUTOFS4_FS=m |
493 | CONFIG_FUSE_FS=m | 488 | CONFIG_FUSE_FS=y |
494 | CONFIG_CUSE=m | 489 | CONFIG_CUSE=m |
495 | CONFIG_FSCACHE=m | 490 | CONFIG_FSCACHE=m |
496 | CONFIG_CACHEFILES=m | 491 | CONFIG_CACHEFILES=m |
@@ -542,10 +537,11 @@ CONFIG_DLM=m | |||
542 | CONFIG_PRINTK_TIME=y | 537 | CONFIG_PRINTK_TIME=y |
543 | CONFIG_DYNAMIC_DEBUG=y | 538 | CONFIG_DYNAMIC_DEBUG=y |
544 | CONFIG_DEBUG_INFO=y | 539 | CONFIG_DEBUG_INFO=y |
545 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
546 | CONFIG_FRAME_WARN=1024 | 540 | CONFIG_FRAME_WARN=1024 |
547 | CONFIG_READABLE_ASM=y | 541 | CONFIG_READABLE_ASM=y |
548 | CONFIG_UNUSED_SYMBOLS=y | 542 | CONFIG_UNUSED_SYMBOLS=y |
543 | CONFIG_HEADERS_CHECK=y | ||
544 | CONFIG_DEBUG_SECTION_MISMATCH=y | ||
549 | CONFIG_MAGIC_SYSRQ=y | 545 | CONFIG_MAGIC_SYSRQ=y |
550 | CONFIG_DEBUG_PAGEALLOC=y | 546 | CONFIG_DEBUG_PAGEALLOC=y |
551 | CONFIG_DEBUG_OBJECTS=y | 547 | CONFIG_DEBUG_OBJECTS=y |
@@ -588,6 +584,7 @@ CONFIG_FAILSLAB=y | |||
588 | CONFIG_FAIL_PAGE_ALLOC=y | 584 | CONFIG_FAIL_PAGE_ALLOC=y |
589 | CONFIG_FAIL_MAKE_REQUEST=y | 585 | CONFIG_FAIL_MAKE_REQUEST=y |
590 | CONFIG_FAIL_IO_TIMEOUT=y | 586 | CONFIG_FAIL_IO_TIMEOUT=y |
587 | CONFIG_FAIL_FUTEX=y | ||
591 | CONFIG_FAULT_INJECTION_DEBUG_FS=y | 588 | CONFIG_FAULT_INJECTION_DEBUG_FS=y |
592 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y | 589 | CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y |
593 | CONFIG_LATENCYTOP=y | 590 | CONFIG_LATENCYTOP=y |
diff --git a/arch/s390/configs/gcov_defconfig b/arch/s390/configs/gcov_defconfig index 9858b14cde1e..a31dcd56f7c0 100644 --- a/arch/s390/configs/gcov_defconfig +++ b/arch/s390/configs/gcov_defconfig | |||
@@ -10,21 +10,27 @@ CONFIG_TASKSTATS=y | |||
10 | CONFIG_TASK_DELAY_ACCT=y | 10 | CONFIG_TASK_DELAY_ACCT=y |
11 | CONFIG_TASK_XACCT=y | 11 | CONFIG_TASK_XACCT=y |
12 | CONFIG_TASK_IO_ACCOUNTING=y | 12 | CONFIG_TASK_IO_ACCOUNTING=y |
13 | CONFIG_RCU_FAST_NO_HZ=y | ||
14 | CONFIG_IKCONFIG=y | 13 | CONFIG_IKCONFIG=y |
15 | CONFIG_IKCONFIG_PROC=y | 14 | CONFIG_IKCONFIG_PROC=y |
16 | CONFIG_NUMA_BALANCING=y | 15 | CONFIG_NUMA_BALANCING=y |
17 | CONFIG_CGROUP_FREEZER=y | 16 | CONFIG_CGROUP_FREEZER=y |
17 | CONFIG_CGROUP_PIDS=y | ||
18 | CONFIG_CGROUP_DEVICE=y | 18 | CONFIG_CGROUP_DEVICE=y |
19 | CONFIG_CPUSETS=y | 19 | CONFIG_CPUSETS=y |
20 | CONFIG_CGROUP_CPUACCT=y | 20 | CONFIG_CGROUP_CPUACCT=y |
21 | CONFIG_MEMCG=y | ||
22 | CONFIG_MEMCG_SWAP=y | ||
23 | CONFIG_MEMCG_KMEM=y | ||
24 | CONFIG_CGROUP_HUGETLB=y | ||
21 | CONFIG_CGROUP_PERF=y | 25 | CONFIG_CGROUP_PERF=y |
22 | CONFIG_BLK_CGROUP=y | 26 | CONFIG_BLK_CGROUP=y |
23 | CONFIG_NAMESPACES=y | 27 | CONFIG_NAMESPACES=y |
28 | CONFIG_USER_NS=y | ||
24 | CONFIG_SCHED_AUTOGROUP=y | 29 | CONFIG_SCHED_AUTOGROUP=y |
25 | CONFIG_BLK_DEV_INITRD=y | 30 | CONFIG_BLK_DEV_INITRD=y |
26 | CONFIG_EXPERT=y | 31 | CONFIG_EXPERT=y |
27 | CONFIG_BPF_SYSCALL=y | 32 | CONFIG_BPF_SYSCALL=y |
33 | CONFIG_USERFAULTFD=y | ||
28 | # CONFIG_COMPAT_BRK is not set | 34 | # CONFIG_COMPAT_BRK is not set |
29 | CONFIG_PROFILING=y | 35 | CONFIG_PROFILING=y |
30 | CONFIG_OPROFILE=m | 36 | CONFIG_OPROFILE=m |
@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y | |||
61 | CONFIG_HOTPLUG_PCI_S390=y | 67 | CONFIG_HOTPLUG_PCI_S390=y |
62 | CONFIG_CHSC_SCH=y | 68 | CONFIG_CHSC_SCH=y |
63 | CONFIG_CRASH_DUMP=y | 69 | CONFIG_CRASH_DUMP=y |
64 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
65 | CONFIG_BINFMT_MISC=m | 70 | CONFIG_BINFMT_MISC=m |
66 | CONFIG_HIBERNATION=y | 71 | CONFIG_HIBERNATION=y |
67 | CONFIG_NET=y | 72 | CONFIG_NET=y |
@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m | |||
103 | CONFIG_TCP_CONG_VENO=m | 108 | CONFIG_TCP_CONG_VENO=m |
104 | CONFIG_TCP_CONG_YEAH=m | 109 | CONFIG_TCP_CONG_YEAH=m |
105 | CONFIG_TCP_CONG_ILLINOIS=m | 110 | CONFIG_TCP_CONG_ILLINOIS=m |
106 | CONFIG_IPV6=y | ||
107 | CONFIG_IPV6_ROUTER_PREF=y | 111 | CONFIG_IPV6_ROUTER_PREF=y |
108 | CONFIG_INET6_AH=m | 112 | CONFIG_INET6_AH=m |
109 | CONFIG_INET6_ESP=m | 113 | CONFIG_INET6_ESP=m |
@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m | |||
453 | CONFIG_INFINIBAND_USER_ACCESS=m | 457 | CONFIG_INFINIBAND_USER_ACCESS=m |
454 | CONFIG_MLX4_INFINIBAND=m | 458 | CONFIG_MLX4_INFINIBAND=m |
455 | CONFIG_VIRTIO_BALLOON=m | 459 | CONFIG_VIRTIO_BALLOON=m |
456 | # CONFIG_IOMMU_SUPPORT is not set | ||
457 | CONFIG_EXT2_FS=y | ||
458 | CONFIG_EXT2_FS_XATTR=y | ||
459 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
460 | CONFIG_EXT2_FS_SECURITY=y | ||
461 | CONFIG_EXT3_FS=y | ||
462 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
463 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
464 | CONFIG_EXT3_FS_SECURITY=y | ||
465 | CONFIG_EXT4_FS=y | 460 | CONFIG_EXT4_FS=y |
466 | CONFIG_EXT4_FS_POSIX_ACL=y | 461 | CONFIG_EXT4_FS_POSIX_ACL=y |
467 | CONFIG_EXT4_FS_SECURITY=y | 462 | CONFIG_EXT4_FS_SECURITY=y |
468 | CONFIG_JBD_DEBUG=y | ||
469 | CONFIG_JBD2_DEBUG=y | 463 | CONFIG_JBD2_DEBUG=y |
470 | CONFIG_JFS_FS=m | 464 | CONFIG_JFS_FS=m |
471 | CONFIG_JFS_POSIX_ACL=y | 465 | CONFIG_JFS_POSIX_ACL=y |
@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y | |||
485 | CONFIG_QFMT_V1=m | 479 | CONFIG_QFMT_V1=m |
486 | CONFIG_QFMT_V2=m | 480 | CONFIG_QFMT_V2=m |
487 | CONFIG_AUTOFS4_FS=m | 481 | CONFIG_AUTOFS4_FS=m |
488 | CONFIG_FUSE_FS=m | 482 | CONFIG_FUSE_FS=y |
489 | CONFIG_CUSE=m | 483 | CONFIG_CUSE=m |
490 | CONFIG_FSCACHE=m | 484 | CONFIG_FSCACHE=m |
491 | CONFIG_CACHEFILES=m | 485 | CONFIG_CACHEFILES=m |
@@ -550,6 +544,7 @@ CONFIG_NOTIFIER_ERROR_INJECTION=m | |||
550 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m | 544 | CONFIG_CPU_NOTIFIER_ERROR_INJECT=m |
551 | CONFIG_PM_NOTIFIER_ERROR_INJECT=m | 545 | CONFIG_PM_NOTIFIER_ERROR_INJECT=m |
552 | CONFIG_LATENCYTOP=y | 546 | CONFIG_LATENCYTOP=y |
547 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
553 | CONFIG_BLK_DEV_IO_TRACE=y | 548 | CONFIG_BLK_DEV_IO_TRACE=y |
554 | # CONFIG_KPROBE_EVENT is not set | 549 | # CONFIG_KPROBE_EVENT is not set |
555 | CONFIG_LKDTM=m | 550 | CONFIG_LKDTM=m |
@@ -557,6 +552,7 @@ CONFIG_RBTREE_TEST=m | |||
557 | CONFIG_INTERVAL_TREE_TEST=m | 552 | CONFIG_INTERVAL_TREE_TEST=m |
558 | CONFIG_PERCPU_TEST=m | 553 | CONFIG_PERCPU_TEST=m |
559 | CONFIG_ATOMIC64_SELFTEST=y | 554 | CONFIG_ATOMIC64_SELFTEST=y |
555 | CONFIG_TEST_BPF=m | ||
560 | # CONFIG_STRICT_DEVMEM is not set | 556 | # CONFIG_STRICT_DEVMEM is not set |
561 | CONFIG_S390_PTDUMP=y | 557 | CONFIG_S390_PTDUMP=y |
562 | CONFIG_ENCRYPTED_KEYS=m | 558 | CONFIG_ENCRYPTED_KEYS=m |
diff --git a/arch/s390/configs/performance_defconfig b/arch/s390/configs/performance_defconfig index 7f14f80717d4..7b73bf353345 100644 --- a/arch/s390/configs/performance_defconfig +++ b/arch/s390/configs/performance_defconfig | |||
@@ -10,22 +10,28 @@ CONFIG_TASKSTATS=y | |||
10 | CONFIG_TASK_DELAY_ACCT=y | 10 | CONFIG_TASK_DELAY_ACCT=y |
11 | CONFIG_TASK_XACCT=y | 11 | CONFIG_TASK_XACCT=y |
12 | CONFIG_TASK_IO_ACCOUNTING=y | 12 | CONFIG_TASK_IO_ACCOUNTING=y |
13 | CONFIG_RCU_FAST_NO_HZ=y | ||
14 | CONFIG_IKCONFIG=y | 13 | CONFIG_IKCONFIG=y |
15 | CONFIG_IKCONFIG_PROC=y | 14 | CONFIG_IKCONFIG_PROC=y |
16 | CONFIG_NUMA_BALANCING=y | 15 | CONFIG_NUMA_BALANCING=y |
17 | # CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set | 16 | # CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set |
18 | CONFIG_CGROUP_FREEZER=y | 17 | CONFIG_CGROUP_FREEZER=y |
18 | CONFIG_CGROUP_PIDS=y | ||
19 | CONFIG_CGROUP_DEVICE=y | 19 | CONFIG_CGROUP_DEVICE=y |
20 | CONFIG_CPUSETS=y | 20 | CONFIG_CPUSETS=y |
21 | CONFIG_CGROUP_CPUACCT=y | 21 | CONFIG_CGROUP_CPUACCT=y |
22 | CONFIG_MEMCG=y | ||
23 | CONFIG_MEMCG_SWAP=y | ||
24 | CONFIG_MEMCG_KMEM=y | ||
25 | CONFIG_CGROUP_HUGETLB=y | ||
22 | CONFIG_CGROUP_PERF=y | 26 | CONFIG_CGROUP_PERF=y |
23 | CONFIG_BLK_CGROUP=y | 27 | CONFIG_BLK_CGROUP=y |
24 | CONFIG_NAMESPACES=y | 28 | CONFIG_NAMESPACES=y |
29 | CONFIG_USER_NS=y | ||
25 | CONFIG_SCHED_AUTOGROUP=y | 30 | CONFIG_SCHED_AUTOGROUP=y |
26 | CONFIG_BLK_DEV_INITRD=y | 31 | CONFIG_BLK_DEV_INITRD=y |
27 | CONFIG_EXPERT=y | 32 | CONFIG_EXPERT=y |
28 | CONFIG_BPF_SYSCALL=y | 33 | CONFIG_BPF_SYSCALL=y |
34 | CONFIG_USERFAULTFD=y | ||
29 | # CONFIG_COMPAT_BRK is not set | 35 | # CONFIG_COMPAT_BRK is not set |
30 | CONFIG_PROFILING=y | 36 | CONFIG_PROFILING=y |
31 | CONFIG_OPROFILE=m | 37 | CONFIG_OPROFILE=m |
@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y | |||
61 | CONFIG_HOTPLUG_PCI_S390=y | 67 | CONFIG_HOTPLUG_PCI_S390=y |
62 | CONFIG_CHSC_SCH=y | 68 | CONFIG_CHSC_SCH=y |
63 | CONFIG_CRASH_DUMP=y | 69 | CONFIG_CRASH_DUMP=y |
64 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
65 | CONFIG_BINFMT_MISC=m | 70 | CONFIG_BINFMT_MISC=m |
66 | CONFIG_HIBERNATION=y | 71 | CONFIG_HIBERNATION=y |
67 | CONFIG_NET=y | 72 | CONFIG_NET=y |
@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m | |||
103 | CONFIG_TCP_CONG_VENO=m | 108 | CONFIG_TCP_CONG_VENO=m |
104 | CONFIG_TCP_CONG_YEAH=m | 109 | CONFIG_TCP_CONG_YEAH=m |
105 | CONFIG_TCP_CONG_ILLINOIS=m | 110 | CONFIG_TCP_CONG_ILLINOIS=m |
106 | CONFIG_IPV6=y | ||
107 | CONFIG_IPV6_ROUTER_PREF=y | 111 | CONFIG_IPV6_ROUTER_PREF=y |
108 | CONFIG_INET6_AH=m | 112 | CONFIG_INET6_AH=m |
109 | CONFIG_INET6_ESP=m | 113 | CONFIG_INET6_ESP=m |
@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m | |||
453 | CONFIG_INFINIBAND_USER_ACCESS=m | 457 | CONFIG_INFINIBAND_USER_ACCESS=m |
454 | CONFIG_MLX4_INFINIBAND=m | 458 | CONFIG_MLX4_INFINIBAND=m |
455 | CONFIG_VIRTIO_BALLOON=m | 459 | CONFIG_VIRTIO_BALLOON=m |
456 | # CONFIG_IOMMU_SUPPORT is not set | ||
457 | CONFIG_EXT2_FS=y | ||
458 | CONFIG_EXT2_FS_XATTR=y | ||
459 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
460 | CONFIG_EXT2_FS_SECURITY=y | ||
461 | CONFIG_EXT3_FS=y | ||
462 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
463 | CONFIG_EXT3_FS_POSIX_ACL=y | ||
464 | CONFIG_EXT3_FS_SECURITY=y | ||
465 | CONFIG_EXT4_FS=y | 460 | CONFIG_EXT4_FS=y |
466 | CONFIG_EXT4_FS_POSIX_ACL=y | 461 | CONFIG_EXT4_FS_POSIX_ACL=y |
467 | CONFIG_EXT4_FS_SECURITY=y | 462 | CONFIG_EXT4_FS_SECURITY=y |
468 | CONFIG_JBD_DEBUG=y | ||
469 | CONFIG_JBD2_DEBUG=y | 463 | CONFIG_JBD2_DEBUG=y |
470 | CONFIG_JFS_FS=m | 464 | CONFIG_JFS_FS=m |
471 | CONFIG_JFS_POSIX_ACL=y | 465 | CONFIG_JFS_POSIX_ACL=y |
@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y | |||
485 | CONFIG_QFMT_V1=m | 479 | CONFIG_QFMT_V1=m |
486 | CONFIG_QFMT_V2=m | 480 | CONFIG_QFMT_V2=m |
487 | CONFIG_AUTOFS4_FS=m | 481 | CONFIG_AUTOFS4_FS=m |
488 | CONFIG_FUSE_FS=m | 482 | CONFIG_FUSE_FS=y |
489 | CONFIG_CUSE=m | 483 | CONFIG_CUSE=m |
490 | CONFIG_FSCACHE=m | 484 | CONFIG_FSCACHE=m |
491 | CONFIG_CACHEFILES=m | 485 | CONFIG_CACHEFILES=m |
@@ -546,6 +540,7 @@ CONFIG_TIMER_STATS=y | |||
546 | CONFIG_RCU_TORTURE_TEST=m | 540 | CONFIG_RCU_TORTURE_TEST=m |
547 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 541 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
548 | CONFIG_LATENCYTOP=y | 542 | CONFIG_LATENCYTOP=y |
543 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | ||
549 | CONFIG_SCHED_TRACER=y | 544 | CONFIG_SCHED_TRACER=y |
550 | CONFIG_FTRACE_SYSCALLS=y | 545 | CONFIG_FTRACE_SYSCALLS=y |
551 | CONFIG_STACK_TRACER=y | 546 | CONFIG_STACK_TRACER=y |
@@ -554,6 +549,7 @@ CONFIG_UPROBE_EVENT=y | |||
554 | CONFIG_LKDTM=m | 549 | CONFIG_LKDTM=m |
555 | CONFIG_PERCPU_TEST=m | 550 | CONFIG_PERCPU_TEST=m |
556 | CONFIG_ATOMIC64_SELFTEST=y | 551 | CONFIG_ATOMIC64_SELFTEST=y |
552 | CONFIG_TEST_BPF=m | ||
557 | # CONFIG_STRICT_DEVMEM is not set | 553 | # CONFIG_STRICT_DEVMEM is not set |
558 | CONFIG_S390_PTDUMP=y | 554 | CONFIG_S390_PTDUMP=y |
559 | CONFIG_ENCRYPTED_KEYS=m | 555 | CONFIG_ENCRYPTED_KEYS=m |
diff --git a/arch/s390/configs/zfcpdump_defconfig b/arch/s390/configs/zfcpdump_defconfig index 92805d604173..1719843a55a2 100644 --- a/arch/s390/configs/zfcpdump_defconfig +++ b/arch/s390/configs/zfcpdump_defconfig | |||
@@ -23,8 +23,6 @@ CONFIG_CRASH_DUMP=y | |||
23 | # CONFIG_SECCOMP is not set | 23 | # CONFIG_SECCOMP is not set |
24 | CONFIG_NET=y | 24 | CONFIG_NET=y |
25 | # CONFIG_IUCV is not set | 25 | # CONFIG_IUCV is not set |
26 | CONFIG_ATM=y | ||
27 | CONFIG_ATM_LANE=y | ||
28 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 26 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
29 | CONFIG_DEVTMPFS=y | 27 | CONFIG_DEVTMPFS=y |
30 | # CONFIG_FIRMWARE_IN_KERNEL is not set | 28 | # CONFIG_FIRMWARE_IN_KERNEL is not set |
@@ -54,14 +52,10 @@ CONFIG_RAW_DRIVER=y | |||
54 | # CONFIG_S390_VMUR is not set | 52 | # CONFIG_S390_VMUR is not set |
55 | # CONFIG_HID is not set | 53 | # CONFIG_HID is not set |
56 | # CONFIG_IOMMU_SUPPORT is not set | 54 | # CONFIG_IOMMU_SUPPORT is not set |
57 | CONFIG_EXT2_FS=y | 55 | # CONFIG_DNOTIFY is not set |
58 | CONFIG_EXT3_FS=y | ||
59 | # CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set | ||
60 | CONFIG_EXT4_FS=y | ||
61 | CONFIG_EXT4_FS_POSIX_ACL=y | ||
62 | CONFIG_EXT4_FS_SECURITY=y | ||
63 | # CONFIG_INOTIFY_USER is not set | 56 | # CONFIG_INOTIFY_USER is not set |
64 | CONFIG_CONFIGFS_FS=y | 57 | CONFIG_CONFIGFS_FS=y |
58 | # CONFIG_MISC_FILESYSTEMS is not set | ||
65 | CONFIG_PRINTK_TIME=y | 59 | CONFIG_PRINTK_TIME=y |
66 | CONFIG_DEBUG_INFO=y | 60 | CONFIG_DEBUG_INFO=y |
67 | CONFIG_DEBUG_FS=y | 61 | CONFIG_DEBUG_FS=y |
diff --git a/arch/s390/defconfig b/arch/s390/defconfig index 9256b48e7e43..e24f2af4c73b 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig | |||
@@ -11,22 +11,31 @@ CONFIG_TASK_IO_ACCOUNTING=y | |||
11 | CONFIG_IKCONFIG=y | 11 | CONFIG_IKCONFIG=y |
12 | CONFIG_IKCONFIG_PROC=y | 12 | CONFIG_IKCONFIG_PROC=y |
13 | CONFIG_CGROUPS=y | 13 | CONFIG_CGROUPS=y |
14 | CONFIG_CGROUP_FREEZER=y | ||
15 | CONFIG_CGROUP_PIDS=y | ||
16 | CONFIG_CGROUP_DEVICE=y | ||
14 | CONFIG_CPUSETS=y | 17 | CONFIG_CPUSETS=y |
15 | CONFIG_CGROUP_CPUACCT=y | 18 | CONFIG_CGROUP_CPUACCT=y |
16 | CONFIG_MEMCG=y | 19 | CONFIG_MEMCG=y |
17 | CONFIG_MEMCG_SWAP=y | 20 | CONFIG_MEMCG_SWAP=y |
21 | CONFIG_MEMCG_KMEM=y | ||
22 | CONFIG_CGROUP_HUGETLB=y | ||
23 | CONFIG_CGROUP_PERF=y | ||
18 | CONFIG_CGROUP_SCHED=y | 24 | CONFIG_CGROUP_SCHED=y |
19 | CONFIG_RT_GROUP_SCHED=y | 25 | CONFIG_RT_GROUP_SCHED=y |
20 | CONFIG_BLK_CGROUP=y | 26 | CONFIG_BLK_CGROUP=y |
21 | CONFIG_NAMESPACES=y | 27 | CONFIG_NAMESPACES=y |
28 | CONFIG_USER_NS=y | ||
22 | CONFIG_BLK_DEV_INITRD=y | 29 | CONFIG_BLK_DEV_INITRD=y |
23 | CONFIG_EXPERT=y | 30 | CONFIG_EXPERT=y |
24 | CONFIG_BPF_SYSCALL=y | 31 | CONFIG_BPF_SYSCALL=y |
32 | CONFIG_USERFAULTFD=y | ||
25 | # CONFIG_COMPAT_BRK is not set | 33 | # CONFIG_COMPAT_BRK is not set |
26 | CONFIG_PROFILING=y | 34 | CONFIG_PROFILING=y |
27 | CONFIG_OPROFILE=y | 35 | CONFIG_OPROFILE=y |
28 | CONFIG_KPROBES=y | 36 | CONFIG_KPROBES=y |
29 | CONFIG_JUMP_LABEL=y | 37 | CONFIG_JUMP_LABEL=y |
38 | CONFIG_STATIC_KEYS_SELFTEST=y | ||
30 | CONFIG_MODULES=y | 39 | CONFIG_MODULES=y |
31 | CONFIG_MODULE_UNLOAD=y | 40 | CONFIG_MODULE_UNLOAD=y |
32 | CONFIG_MODVERSIONS=y | 41 | CONFIG_MODVERSIONS=y |
@@ -37,6 +46,7 @@ CONFIG_DEFAULT_DEADLINE=y | |||
37 | CONFIG_LIVEPATCH=y | 46 | CONFIG_LIVEPATCH=y |
38 | CONFIG_MARCH_Z196=y | 47 | CONFIG_MARCH_Z196=y |
39 | CONFIG_NR_CPUS=256 | 48 | CONFIG_NR_CPUS=256 |
49 | CONFIG_NUMA=y | ||
40 | CONFIG_HZ_100=y | 50 | CONFIG_HZ_100=y |
41 | CONFIG_MEMORY_HOTPLUG=y | 51 | CONFIG_MEMORY_HOTPLUG=y |
42 | CONFIG_MEMORY_HOTREMOVE=y | 52 | CONFIG_MEMORY_HOTREMOVE=y |
@@ -52,7 +62,6 @@ CONFIG_NET_KEY=y | |||
52 | CONFIG_INET=y | 62 | CONFIG_INET=y |
53 | CONFIG_IP_MULTICAST=y | 63 | CONFIG_IP_MULTICAST=y |
54 | # CONFIG_INET_LRO is not set | 64 | # CONFIG_INET_LRO is not set |
55 | CONFIG_IPV6=y | ||
56 | CONFIG_L2TP=m | 65 | CONFIG_L2TP=m |
57 | CONFIG_L2TP_DEBUGFS=m | 66 | CONFIG_L2TP_DEBUGFS=m |
58 | CONFIG_VLAN_8021Q=y | 67 | CONFIG_VLAN_8021Q=y |
@@ -89,10 +98,26 @@ CONFIG_BLK_DEV_SR_VENDOR=y | |||
89 | CONFIG_CHR_DEV_SG=y | 98 | CONFIG_CHR_DEV_SG=y |
90 | CONFIG_SCSI_CONSTANTS=y | 99 | CONFIG_SCSI_CONSTANTS=y |
91 | CONFIG_SCSI_LOGGING=y | 100 | CONFIG_SCSI_LOGGING=y |
92 | CONFIG_SCSI_SCAN_ASYNC=y | ||
93 | CONFIG_SCSI_FC_ATTRS=y | 101 | CONFIG_SCSI_FC_ATTRS=y |
94 | CONFIG_ZFCP=y | 102 | CONFIG_ZFCP=y |
95 | CONFIG_SCSI_VIRTIO=y | 103 | CONFIG_SCSI_VIRTIO=y |
104 | CONFIG_MD=y | ||
105 | CONFIG_MD_LINEAR=m | ||
106 | CONFIG_MD_RAID0=m | ||
107 | CONFIG_MD_MULTIPATH=m | ||
108 | CONFIG_BLK_DEV_DM=y | ||
109 | CONFIG_DM_CRYPT=m | ||
110 | CONFIG_DM_SNAPSHOT=m | ||
111 | CONFIG_DM_MIRROR=m | ||
112 | CONFIG_DM_LOG_USERSPACE=m | ||
113 | CONFIG_DM_RAID=m | ||
114 | CONFIG_DM_ZERO=m | ||
115 | CONFIG_DM_MULTIPATH=m | ||
116 | CONFIG_DM_MULTIPATH_QL=m | ||
117 | CONFIG_DM_MULTIPATH_ST=m | ||
118 | CONFIG_DM_UEVENT=y | ||
119 | CONFIG_DM_VERITY=m | ||
120 | CONFIG_DM_SWITCH=m | ||
96 | CONFIG_NETDEVICES=y | 121 | CONFIG_NETDEVICES=y |
97 | CONFIG_BONDING=m | 122 | CONFIG_BONDING=m |
98 | CONFIG_DUMMY=m | 123 | CONFIG_DUMMY=m |
@@ -137,7 +162,6 @@ CONFIG_DEBUG_PI_LIST=y | |||
137 | CONFIG_DEBUG_SG=y | 162 | CONFIG_DEBUG_SG=y |
138 | CONFIG_DEBUG_NOTIFIERS=y | 163 | CONFIG_DEBUG_NOTIFIERS=y |
139 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 | 164 | CONFIG_RCU_CPU_STALL_TIMEOUT=60 |
140 | # CONFIG_RCU_CPU_STALL_INFO is not set | ||
141 | CONFIG_RCU_TRACE=y | 165 | CONFIG_RCU_TRACE=y |
142 | CONFIG_LATENCYTOP=y | 166 | CONFIG_LATENCYTOP=y |
143 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y | 167 | CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h index d350ed9d0fbb..352f7bdaf11f 100644 --- a/arch/s390/include/asm/compat.h +++ b/arch/s390/include/asm/compat.h | |||
@@ -284,7 +284,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
284 | 284 | ||
285 | static inline int is_compat_task(void) | 285 | static inline int is_compat_task(void) |
286 | { | 286 | { |
287 | return is_32bit_task(); | 287 | return test_thread_flag(TIF_31BIT); |
288 | } | 288 | } |
289 | 289 | ||
290 | static inline void __user *arch_compat_alloc_user_space(long len) | 290 | static inline void __user *arch_compat_alloc_user_space(long len) |
diff --git a/arch/s390/include/asm/crw.h b/arch/s390/include/asm/crw.h index 7c31d3e25cd1..bcb9cd2a730a 100644 --- a/arch/s390/include/asm/crw.h +++ b/arch/s390/include/asm/crw.h | |||
@@ -52,18 +52,4 @@ void crw_wait_for_channel_report(void); | |||
52 | #define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ | 52 | #define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ |
53 | #define CRW_ERC_PMOD 0x08 /* installed parameters modified */ | 53 | #define CRW_ERC_PMOD 0x08 /* installed parameters modified */ |
54 | 54 | ||
55 | static inline int stcrw(struct crw *pcrw) | ||
56 | { | ||
57 | int ccode; | ||
58 | |||
59 | asm volatile( | ||
60 | " stcrw 0(%2)\n" | ||
61 | " ipm %0\n" | ||
62 | " srl %0,28\n" | ||
63 | : "=d" (ccode), "=m" (*pcrw) | ||
64 | : "a" (pcrw) | ||
65 | : "cc" ); | ||
66 | return ccode; | ||
67 | } | ||
68 | |||
69 | #endif /* _ASM_S390_CRW_H */ | 55 | #endif /* _ASM_S390_CRW_H */ |
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h index 08e34a5dc909..563ab9f44874 100644 --- a/arch/s390/include/asm/elf.h +++ b/arch/s390/include/asm/elf.h | |||
@@ -129,6 +129,7 @@ typedef s390_regs elf_gregset_t; | |||
129 | typedef s390_fp_regs compat_elf_fpregset_t; | 129 | typedef s390_fp_regs compat_elf_fpregset_t; |
130 | typedef s390_compat_regs compat_elf_gregset_t; | 130 | typedef s390_compat_regs compat_elf_gregset_t; |
131 | 131 | ||
132 | #include <linux/compat.h> | ||
132 | #include <linux/sched.h> /* for task_struct */ | 133 | #include <linux/sched.h> /* for task_struct */ |
133 | #include <asm/mmu_context.h> | 134 | #include <asm/mmu_context.h> |
134 | 135 | ||
@@ -162,7 +163,7 @@ extern unsigned int vdso_enabled; | |||
162 | the loader. We need to make sure that it is out of the way of the program | 163 | the loader. We need to make sure that it is out of the way of the program |
163 | that it will "exec", and that there is sufficient room for the brk. 64-bit | 164 | that it will "exec", and that there is sufficient room for the brk. 64-bit |
164 | tasks are aligned to 4GB. */ | 165 | tasks are aligned to 4GB. */ |
165 | #define ELF_ET_DYN_BASE (is_32bit_task() ? \ | 166 | #define ELF_ET_DYN_BASE (is_compat_task() ? \ |
166 | (STACK_TOP / 3 * 2) : \ | 167 | (STACK_TOP / 3 * 2) : \ |
167 | (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)) | 168 | (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)) |
168 | 169 | ||
@@ -219,9 +220,9 @@ do { \ | |||
219 | * of up to 1GB. For 31-bit processes the virtual address space is limited, | 220 | * of up to 1GB. For 31-bit processes the virtual address space is limited, |
220 | * use no alignment and limit the randomization to 8MB. | 221 | * use no alignment and limit the randomization to 8MB. |
221 | */ | 222 | */ |
222 | #define BRK_RND_MASK (is_32bit_task() ? 0x7ffUL : 0x3ffffUL) | 223 | #define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ffffUL) |
223 | #define MMAP_RND_MASK (is_32bit_task() ? 0x7ffUL : 0x3ff80UL) | 224 | #define MMAP_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ff80UL) |
224 | #define MMAP_ALIGN_MASK (is_32bit_task() ? 0 : 0x7fUL) | 225 | #define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL) |
225 | #define STACK_RND_MASK MMAP_RND_MASK | 226 | #define STACK_RND_MASK MMAP_RND_MASK |
226 | 227 | ||
227 | #define ARCH_DLINFO \ | 228 | #define ARCH_DLINFO \ |
@@ -236,6 +237,4 @@ struct linux_binprm; | |||
236 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 | 237 | #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 |
237 | int arch_setup_additional_pages(struct linux_binprm *, int); | 238 | int arch_setup_additional_pages(struct linux_binprm *, int); |
238 | 239 | ||
239 | void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vxrs); | ||
240 | |||
241 | #endif | 240 | #endif |
diff --git a/arch/s390/include/asm/facilities_src.h b/arch/s390/include/asm/facilities_src.h new file mode 100644 index 000000000000..4917728e5828 --- /dev/null +++ b/arch/s390/include/asm/facilities_src.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2015 | ||
3 | */ | ||
4 | |||
5 | #ifndef S390_GEN_FACILITIES_C | ||
6 | #error "This file can only be included by gen_facilities.c" | ||
7 | #endif | ||
8 | |||
9 | #include <linux/kconfig.h> | ||
10 | |||
11 | struct facility_def { | ||
12 | char *name; | ||
13 | int *bits; | ||
14 | }; | ||
15 | |||
16 | static struct facility_def facility_defs[] = { | ||
17 | { | ||
18 | /* | ||
19 | * FACILITIES_ALS contains the list of facilities that are | ||
20 | * required to run a kernel that is compiled e.g. with | ||
21 | * -march=<machine>. | ||
22 | */ | ||
23 | .name = "FACILITIES_ALS", | ||
24 | .bits = (int[]){ | ||
25 | #ifdef CONFIG_HAVE_MARCH_Z900_FEATURES | ||
26 | 0, /* N3 instructions */ | ||
27 | 1, /* z/Arch mode installed */ | ||
28 | #endif | ||
29 | #ifdef CONFIG_HAVE_MARCH_Z990_FEATURES | ||
30 | 18, /* long displacement facility */ | ||
31 | #endif | ||
32 | #ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES | ||
33 | 7, /* stfle */ | ||
34 | 17, /* message security assist */ | ||
35 | 21, /* extended-immediate facility */ | ||
36 | 25, /* store clock fast */ | ||
37 | #endif | ||
38 | #ifdef CONFIG_HAVE_MARCH_Z10_FEATURES | ||
39 | 27, /* mvcos */ | ||
40 | 32, /* compare and swap and store */ | ||
41 | 33, /* compare and swap and store 2 */ | ||
42 | 34, /* general extension facility */ | ||
43 | 35, /* execute extensions */ | ||
44 | #endif | ||
45 | #ifdef CONFIG_HAVE_MARCH_Z196_FEATURES | ||
46 | 45, /* fast-BCR, etc. */ | ||
47 | #endif | ||
48 | #ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES | ||
49 | 49, /* misc-instruction-extensions */ | ||
50 | 52, /* interlocked facility 2 */ | ||
51 | #endif | ||
52 | #ifdef CONFIG_HAVE_MARCH_Z13_FEATURES | ||
53 | 53, /* load-and-zero-rightmost-byte, etc. */ | ||
54 | #endif | ||
55 | -1 /* END */ | ||
56 | } | ||
57 | }, | ||
58 | }; | ||
diff --git a/arch/s390/include/asm/facility.h b/arch/s390/include/asm/facility.h index 0aa6a7ed95a3..09b406db7529 100644 --- a/arch/s390/include/asm/facility.h +++ b/arch/s390/include/asm/facility.h | |||
@@ -7,6 +7,10 @@ | |||
7 | #ifndef __ASM_FACILITY_H | 7 | #ifndef __ASM_FACILITY_H |
8 | #define __ASM_FACILITY_H | 8 | #define __ASM_FACILITY_H |
9 | 9 | ||
10 | #include <generated/facilities.h> | ||
11 | |||
12 | #ifndef __ASSEMBLY__ | ||
13 | |||
10 | #include <linux/string.h> | 14 | #include <linux/string.h> |
11 | #include <linux/preempt.h> | 15 | #include <linux/preempt.h> |
12 | #include <asm/lowcore.h> | 16 | #include <asm/lowcore.h> |
@@ -30,6 +34,12 @@ static inline int __test_facility(unsigned long nr, void *facilities) | |||
30 | */ | 34 | */ |
31 | static inline int test_facility(unsigned long nr) | 35 | static inline int test_facility(unsigned long nr) |
32 | { | 36 | { |
37 | unsigned long facilities_als[] = { FACILITIES_ALS }; | ||
38 | |||
39 | if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) { | ||
40 | if (__test_facility(nr, &facilities_als)) | ||
41 | return 1; | ||
42 | } | ||
33 | return __test_facility(nr, &S390_lowcore.stfle_fac_list); | 43 | return __test_facility(nr, &S390_lowcore.stfle_fac_list); |
34 | } | 44 | } |
35 | 45 | ||
@@ -44,10 +54,8 @@ static inline void stfle(u64 *stfle_fac_list, int size) | |||
44 | 54 | ||
45 | preempt_disable(); | 55 | preempt_disable(); |
46 | asm volatile( | 56 | asm volatile( |
47 | " .insn s,0xb2b10000,0(0)\n" /* stfl */ | 57 | " stfl 0(0)\n" |
48 | "0:\n" | 58 | : "=m" (S390_lowcore.stfl_fac_list)); |
49 | EX_TABLE(0b, 0b) | ||
50 | : "+m" (S390_lowcore.stfl_fac_list)); | ||
51 | nr = 4; /* bytes stored by stfl */ | 59 | nr = 4; /* bytes stored by stfl */ |
52 | memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); | 60 | memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); |
53 | if (S390_lowcore.stfl_fac_list & 0x01000000) { | 61 | if (S390_lowcore.stfl_fac_list & 0x01000000) { |
@@ -64,4 +72,5 @@ static inline void stfle(u64 *stfle_fac_list, int size) | |||
64 | preempt_enable(); | 72 | preempt_enable(); |
65 | } | 73 | } |
66 | 74 | ||
75 | #endif /* __ASSEMBLY__ */ | ||
67 | #endif /* __ASM_FACILITY_H */ | 76 | #endif /* __ASM_FACILITY_H */ |
diff --git a/arch/s390/include/asm/fpu/internal.h b/arch/s390/include/asm/fpu/internal.h index 2559b16da525..ea91ddfe54eb 100644 --- a/arch/s390/include/asm/fpu/internal.h +++ b/arch/s390/include/asm/fpu/internal.h | |||
@@ -12,21 +12,13 @@ | |||
12 | #include <asm/ctl_reg.h> | 12 | #include <asm/ctl_reg.h> |
13 | #include <asm/fpu/types.h> | 13 | #include <asm/fpu/types.h> |
14 | 14 | ||
15 | static inline void save_vx_regs_safe(__vector128 *vxrs) | 15 | static inline void save_vx_regs(__vector128 *vxrs) |
16 | { | 16 | { |
17 | unsigned long cr0, flags; | ||
18 | |||
19 | flags = arch_local_irq_save(); | ||
20 | __ctl_store(cr0, 0, 0); | ||
21 | __ctl_set_bit(0, 17); | ||
22 | __ctl_set_bit(0, 18); | ||
23 | asm volatile( | 17 | asm volatile( |
24 | " la 1,%0\n" | 18 | " la 1,%0\n" |
25 | " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ | 19 | " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ |
26 | " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ | 20 | " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ |
27 | : "=Q" (*(struct vx_array *) vxrs) : : "1"); | 21 | : "=Q" (*(struct vx_array *) vxrs) : : "1"); |
28 | __ctl_load(cr0, 0, 0); | ||
29 | arch_local_irq_restore(flags); | ||
30 | } | 22 | } |
31 | 23 | ||
32 | static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs) | 24 | static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs) |
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h index 86634e71b69f..6fc44dca193e 100644 --- a/arch/s390/include/asm/ipl.h +++ b/arch/s390/include/asm/ipl.h | |||
@@ -87,14 +87,12 @@ struct ipl_parameter_block { | |||
87 | * IPL validity flags | 87 | * IPL validity flags |
88 | */ | 88 | */ |
89 | extern u32 ipl_flags; | 89 | extern u32 ipl_flags; |
90 | extern u32 dump_prefix_page; | ||
91 | 90 | ||
92 | struct dump_save_areas { | 91 | struct save_area; |
93 | struct save_area_ext **areas; | 92 | struct save_area * __init save_area_alloc(bool is_boot_cpu); |
94 | int count; | 93 | struct save_area * __init save_area_boot_cpu(void); |
95 | }; | 94 | void __init save_area_add_regs(struct save_area *, void *regs); |
96 | 95 | void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs); | |
97 | extern struct dump_save_areas dump_save_areas; | ||
98 | 96 | ||
99 | extern void do_reipl(void); | 97 | extern void do_reipl(void); |
100 | extern void do_halt(void); | 98 | extern void do_halt(void); |
@@ -176,7 +174,7 @@ enum diag308_rc { | |||
176 | 174 | ||
177 | extern int diag308(unsigned long subcode, void *addr); | 175 | extern int diag308(unsigned long subcode, void *addr); |
178 | extern void diag308_reset(void); | 176 | extern void diag308_reset(void); |
179 | extern void store_status(void); | 177 | extern void store_status(void (*fn)(void *), void *data); |
180 | extern void lgr_info_log(void); | 178 | extern void lgr_info_log(void); |
181 | 179 | ||
182 | #endif /* _ASM_S390_IPL_H */ | 180 | #endif /* _ASM_S390_IPL_H */ |
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index afe1cfebf1a4..d79ba7cf75b0 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
@@ -16,28 +16,7 @@ | |||
16 | #define LC_ORDER 1 | 16 | #define LC_ORDER 1 |
17 | #define LC_PAGES 2 | 17 | #define LC_PAGES 2 |
18 | 18 | ||
19 | struct save_area { | 19 | struct lowcore { |
20 | u64 fp_regs[16]; | ||
21 | u64 gp_regs[16]; | ||
22 | u8 psw[16]; | ||
23 | u8 pad1[8]; | ||
24 | u32 pref_reg; | ||
25 | u32 fp_ctrl_reg; | ||
26 | u8 pad2[4]; | ||
27 | u32 tod_reg; | ||
28 | u64 timer; | ||
29 | u64 clk_cmp; | ||
30 | u8 pad3[8]; | ||
31 | u32 acc_regs[16]; | ||
32 | u64 ctrl_regs[16]; | ||
33 | } __packed; | ||
34 | |||
35 | struct save_area_ext { | ||
36 | struct save_area sa; | ||
37 | __vector128 vx_regs[32]; | ||
38 | }; | ||
39 | |||
40 | struct _lowcore { | ||
41 | __u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */ | 20 | __u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */ |
42 | __u32 ipl_parmblock_ptr; /* 0x0014 */ | 21 | __u32 ipl_parmblock_ptr; /* 0x0014 */ |
43 | __u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */ | 22 | __u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */ |
@@ -204,9 +183,9 @@ struct _lowcore { | |||
204 | __u8 vector_save_area[1024]; /* 0x1c00 */ | 183 | __u8 vector_save_area[1024]; /* 0x1c00 */ |
205 | } __packed; | 184 | } __packed; |
206 | 185 | ||
207 | #define S390_lowcore (*((struct _lowcore *) 0)) | 186 | #define S390_lowcore (*((struct lowcore *) 0)) |
208 | 187 | ||
209 | extern struct _lowcore *lowcore_ptr[]; | 188 | extern struct lowcore *lowcore_ptr[]; |
210 | 189 | ||
211 | static inline void set_prefix(__u32 address) | 190 | static inline void set_prefix(__u32 address) |
212 | { | 191 | { |
diff --git a/arch/s390/include/asm/os_info.h b/arch/s390/include/asm/os_info.h index 295f2c4f1c96..943475382d51 100644 --- a/arch/s390/include/asm/os_info.h +++ b/arch/s390/include/asm/os_info.h | |||
@@ -38,7 +38,7 @@ u32 os_info_csum(struct os_info *os_info); | |||
38 | 38 | ||
39 | #ifdef CONFIG_CRASH_DUMP | 39 | #ifdef CONFIG_CRASH_DUMP |
40 | void *os_info_old_entry(int nr, unsigned long *size); | 40 | void *os_info_old_entry(int nr, unsigned long *size); |
41 | int copy_from_oldmem(void *dest, void *src, size_t count); | 41 | int copy_oldmem_kernel(void *dst, void *src, size_t count); |
42 | #else | 42 | #else |
43 | static inline void *os_info_old_entry(int nr, unsigned long *size) | 43 | static inline void *os_info_old_entry(int nr, unsigned long *size) |
44 | { | 44 | { |
diff --git a/arch/s390/include/asm/pci_dma.h b/arch/s390/include/asm/pci_dma.h index 1aac41e83ea1..92df3eb8d14e 100644 --- a/arch/s390/include/asm/pci_dma.h +++ b/arch/s390/include/asm/pci_dma.h | |||
@@ -23,6 +23,8 @@ enum zpci_ioat_dtype { | |||
23 | #define ZPCI_IOTA_FS_2G 2 | 23 | #define ZPCI_IOTA_FS_2G 2 |
24 | #define ZPCI_KEY (PAGE_DEFAULT_KEY << 5) | 24 | #define ZPCI_KEY (PAGE_DEFAULT_KEY << 5) |
25 | 25 | ||
26 | #define ZPCI_TABLE_SIZE_RT (1UL << 42) | ||
27 | |||
26 | #define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST) | 28 | #define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST) |
27 | #define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT) | 29 | #define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT) |
28 | #define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS) | 30 | #define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS) |
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index b16c3d0a1b9f..f16debf6a612 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -18,12 +18,14 @@ | |||
18 | #define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */ | 18 | #define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */ |
19 | #define CIF_FPU 3 /* restore FPU registers */ | 19 | #define CIF_FPU 3 /* restore FPU registers */ |
20 | #define CIF_IGNORE_IRQ 4 /* ignore interrupt (for udelay) */ | 20 | #define CIF_IGNORE_IRQ 4 /* ignore interrupt (for udelay) */ |
21 | #define CIF_ENABLED_WAIT 5 /* in enabled wait state */ | ||
21 | 22 | ||
22 | #define _CIF_MCCK_PENDING _BITUL(CIF_MCCK_PENDING) | 23 | #define _CIF_MCCK_PENDING _BITUL(CIF_MCCK_PENDING) |
23 | #define _CIF_ASCE _BITUL(CIF_ASCE) | 24 | #define _CIF_ASCE _BITUL(CIF_ASCE) |
24 | #define _CIF_NOHZ_DELAY _BITUL(CIF_NOHZ_DELAY) | 25 | #define _CIF_NOHZ_DELAY _BITUL(CIF_NOHZ_DELAY) |
25 | #define _CIF_FPU _BITUL(CIF_FPU) | 26 | #define _CIF_FPU _BITUL(CIF_FPU) |
26 | #define _CIF_IGNORE_IRQ _BITUL(CIF_IGNORE_IRQ) | 27 | #define _CIF_IGNORE_IRQ _BITUL(CIF_IGNORE_IRQ) |
28 | #define _CIF_ENABLED_WAIT _BITUL(CIF_ENABLED_WAIT) | ||
27 | 29 | ||
28 | #ifndef __ASSEMBLY__ | 30 | #ifndef __ASSEMBLY__ |
29 | 31 | ||
@@ -52,6 +54,16 @@ static inline int test_cpu_flag(int flag) | |||
52 | return !!(S390_lowcore.cpu_flags & (1UL << flag)); | 54 | return !!(S390_lowcore.cpu_flags & (1UL << flag)); |
53 | } | 55 | } |
54 | 56 | ||
57 | /* | ||
58 | * Test CIF flag of another CPU. The caller needs to ensure that | ||
59 | * CPU hotplug can not happen, e.g. by disabling preemption. | ||
60 | */ | ||
61 | static inline int test_cpu_flag_of(int flag, int cpu) | ||
62 | { | ||
63 | struct lowcore *lc = lowcore_ptr[cpu]; | ||
64 | return !!(lc->cpu_flags & (1UL << flag)); | ||
65 | } | ||
66 | |||
55 | #define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY) | 67 | #define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY) |
56 | 68 | ||
57 | /* | 69 | /* |
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h index 37cbc50947f2..f00cd35c8ac4 100644 --- a/arch/s390/include/asm/ptrace.h +++ b/arch/s390/include/asm/ptrace.h | |||
@@ -24,25 +24,25 @@ | |||
24 | PSW_MASK_PSTATE | PSW_ASC_PRIMARY) | 24 | PSW_MASK_PSTATE | PSW_ASC_PRIMARY) |
25 | 25 | ||
26 | struct psw_bits { | 26 | struct psw_bits { |
27 | unsigned long long : 1; | 27 | unsigned long : 1; |
28 | unsigned long long r : 1; /* PER-Mask */ | 28 | unsigned long r : 1; /* PER-Mask */ |
29 | unsigned long long : 3; | 29 | unsigned long : 3; |
30 | unsigned long long t : 1; /* DAT Mode */ | 30 | unsigned long t : 1; /* DAT Mode */ |
31 | unsigned long long i : 1; /* Input/Output Mask */ | 31 | unsigned long i : 1; /* Input/Output Mask */ |
32 | unsigned long long e : 1; /* External Mask */ | 32 | unsigned long e : 1; /* External Mask */ |
33 | unsigned long long key : 4; /* PSW Key */ | 33 | unsigned long key : 4; /* PSW Key */ |
34 | unsigned long long : 1; | 34 | unsigned long : 1; |
35 | unsigned long long m : 1; /* Machine-Check Mask */ | 35 | unsigned long m : 1; /* Machine-Check Mask */ |
36 | unsigned long long w : 1; /* Wait State */ | 36 | unsigned long w : 1; /* Wait State */ |
37 | unsigned long long p : 1; /* Problem State */ | 37 | unsigned long p : 1; /* Problem State */ |
38 | unsigned long long as : 2; /* Address Space Control */ | 38 | unsigned long as : 2; /* Address Space Control */ |
39 | unsigned long long cc : 2; /* Condition Code */ | 39 | unsigned long cc : 2; /* Condition Code */ |
40 | unsigned long long pm : 4; /* Program Mask */ | 40 | unsigned long pm : 4; /* Program Mask */ |
41 | unsigned long long ri : 1; /* Runtime Instrumentation */ | 41 | unsigned long ri : 1; /* Runtime Instrumentation */ |
42 | unsigned long long : 6; | 42 | unsigned long : 6; |
43 | unsigned long long eaba : 2; /* Addressing Mode */ | 43 | unsigned long eaba : 2; /* Addressing Mode */ |
44 | unsigned long long : 31; | 44 | unsigned long : 31; |
45 | unsigned long long ia : 64;/* Instruction Address */ | 45 | unsigned long ia : 64; /* Instruction Address */ |
46 | }; | 46 | }; |
47 | 47 | ||
48 | enum { | 48 | enum { |
diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h index 72786067b300..fe11fa88a0e0 100644 --- a/arch/s390/include/asm/reset.h +++ b/arch/s390/include/asm/reset.h | |||
@@ -15,6 +15,5 @@ struct reset_call { | |||
15 | 15 | ||
16 | extern void register_reset_call(struct reset_call *reset); | 16 | extern void register_reset_call(struct reset_call *reset); |
17 | extern void unregister_reset_call(struct reset_call *reset); | 17 | extern void unregister_reset_call(struct reset_call *reset); |
18 | extern void s390_reset_system(void (*fn_pre)(void), | 18 | extern void s390_reset_system(void); |
19 | void (*fn_post)(void *), void *data); | ||
20 | #endif /* _ASM_S390_RESET_H */ | 19 | #endif /* _ASM_S390_RESET_H */ |
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h index dea883f85d66..bab456be9a4f 100644 --- a/arch/s390/include/asm/sclp.h +++ b/arch/s390/include/asm/sclp.h | |||
@@ -63,12 +63,12 @@ struct sclp_info { | |||
63 | unsigned int mtid; | 63 | unsigned int mtid; |
64 | unsigned int mtid_cp; | 64 | unsigned int mtid_cp; |
65 | unsigned int mtid_prev; | 65 | unsigned int mtid_prev; |
66 | unsigned long long rzm; | 66 | unsigned long rzm; |
67 | unsigned long long rnmax; | 67 | unsigned long rnmax; |
68 | unsigned long long hamax; | 68 | unsigned long hamax; |
69 | unsigned int max_cores; | 69 | unsigned int max_cores; |
70 | unsigned long hsa_size; | 70 | unsigned long hsa_size; |
71 | unsigned long long facilities; | 71 | unsigned long facilities; |
72 | }; | 72 | }; |
73 | extern struct sclp_info sclp; | 73 | extern struct sclp_info sclp; |
74 | 74 | ||
@@ -83,8 +83,9 @@ int sclp_chp_read_info(struct sclp_chp_info *info); | |||
83 | void sclp_get_ipl_info(struct sclp_ipl_info *info); | 83 | void sclp_get_ipl_info(struct sclp_ipl_info *info); |
84 | int sclp_pci_configure(u32 fid); | 84 | int sclp_pci_configure(u32 fid); |
85 | int sclp_pci_deconfigure(u32 fid); | 85 | int sclp_pci_deconfigure(u32 fid); |
86 | int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); | 86 | int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count); |
87 | int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count); | ||
87 | void sclp_early_detect(void); | 88 | void sclp_early_detect(void); |
88 | int _sclp_print_early(const char *); | 89 | void _sclp_print_early(const char *); |
89 | 90 | ||
90 | #endif /* _ASM_S390_SCLP_H */ | 91 | #endif /* _ASM_S390_SCLP_H */ |
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 23537661da0e..69837225119e 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
@@ -12,27 +12,24 @@ | |||
12 | #define PARMAREA 0x10400 | 12 | #define PARMAREA 0x10400 |
13 | 13 | ||
14 | /* | 14 | /* |
15 | * Machine features detected in head.S | 15 | * Machine features detected in early.c |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define MACHINE_FLAG_VM _BITUL(0) | 18 | #define MACHINE_FLAG_VM _BITUL(0) |
19 | #define MACHINE_FLAG_IEEE _BITUL(1) | 19 | #define MACHINE_FLAG_KVM _BITUL(1) |
20 | #define MACHINE_FLAG_CSP _BITUL(2) | 20 | #define MACHINE_FLAG_LPAR _BITUL(2) |
21 | #define MACHINE_FLAG_MVPG _BITUL(3) | 21 | #define MACHINE_FLAG_DIAG9C _BITUL(3) |
22 | #define MACHINE_FLAG_DIAG44 _BITUL(4) | 22 | #define MACHINE_FLAG_ESOP _BITUL(4) |
23 | #define MACHINE_FLAG_IDTE _BITUL(5) | 23 | #define MACHINE_FLAG_IDTE _BITUL(5) |
24 | #define MACHINE_FLAG_DIAG9C _BITUL(6) | 24 | #define MACHINE_FLAG_DIAG44 _BITUL(6) |
25 | #define MACHINE_FLAG_KVM _BITUL(8) | 25 | #define MACHINE_FLAG_EDAT1 _BITUL(7) |
26 | #define MACHINE_FLAG_ESOP _BITUL(9) | 26 | #define MACHINE_FLAG_EDAT2 _BITUL(8) |
27 | #define MACHINE_FLAG_EDAT1 _BITUL(10) | 27 | #define MACHINE_FLAG_LPP _BITUL(9) |
28 | #define MACHINE_FLAG_EDAT2 _BITUL(11) | 28 | #define MACHINE_FLAG_TOPOLOGY _BITUL(10) |
29 | #define MACHINE_FLAG_LPAR _BITUL(12) | 29 | #define MACHINE_FLAG_TE _BITUL(11) |
30 | #define MACHINE_FLAG_LPP _BITUL(13) | 30 | #define MACHINE_FLAG_TLB_LC _BITUL(12) |
31 | #define MACHINE_FLAG_TOPOLOGY _BITUL(14) | 31 | #define MACHINE_FLAG_VX _BITUL(13) |
32 | #define MACHINE_FLAG_TE _BITUL(15) | 32 | #define MACHINE_FLAG_CAD _BITUL(14) |
33 | #define MACHINE_FLAG_TLB_LC _BITUL(17) | ||
34 | #define MACHINE_FLAG_VX _BITUL(18) | ||
35 | #define MACHINE_FLAG_CAD _BITUL(19) | ||
36 | 33 | ||
37 | #define LPP_MAGIC _BITUL(31) | 34 | #define LPP_MAGIC _BITUL(31) |
38 | #define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL) | 35 | #define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL) |
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h index 5df26b11cf47..0cc383b9be7f 100644 --- a/arch/s390/include/asm/smp.h +++ b/arch/s390/include/asm/smp.h | |||
@@ -18,6 +18,7 @@ | |||
18 | extern struct mutex smp_cpu_state_mutex; | 18 | extern struct mutex smp_cpu_state_mutex; |
19 | extern unsigned int smp_cpu_mt_shift; | 19 | extern unsigned int smp_cpu_mt_shift; |
20 | extern unsigned int smp_cpu_mtid; | 20 | extern unsigned int smp_cpu_mtid; |
21 | extern __vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS]; | ||
21 | 22 | ||
22 | extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); | 23 | extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); |
23 | 24 | ||
@@ -55,7 +56,6 @@ static inline int smp_store_status(int cpu) { return 0; } | |||
55 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } | 56 | static inline int smp_vcpu_scheduled(int cpu) { return 1; } |
56 | static inline void smp_yield_cpu(int cpu) { } | 57 | static inline void smp_yield_cpu(int cpu) { } |
57 | static inline void smp_fill_possible_mask(void) { } | 58 | static inline void smp_fill_possible_mask(void) { } |
58 | static inline void smp_save_dump_cpus(void) { } | ||
59 | 59 | ||
60 | #endif /* CONFIG_SMP */ | 60 | #endif /* CONFIG_SMP */ |
61 | 61 | ||
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h index f7054a892d9e..2728114d5484 100644 --- a/arch/s390/include/asm/sysinfo.h +++ b/arch/s390/include/asm/sysinfo.h | |||
@@ -56,7 +56,12 @@ struct sysinfo_1_2_2 { | |||
56 | char format; | 56 | char format; |
57 | char reserved_0[1]; | 57 | char reserved_0[1]; |
58 | unsigned short acc_offset; | 58 | unsigned short acc_offset; |
59 | char reserved_1[20]; | 59 | unsigned char mt_installed :1; |
60 | unsigned char :2; | ||
61 | unsigned char mt_stid :5; | ||
62 | unsigned char :3; | ||
63 | unsigned char mt_gtid :5; | ||
64 | char reserved_1[18]; | ||
60 | unsigned int nominal_cap; | 65 | unsigned int nominal_cap; |
61 | unsigned int secondary_cap; | 66 | unsigned int secondary_cap; |
62 | unsigned int capability; | 67 | unsigned int capability; |
@@ -92,9 +97,13 @@ struct sysinfo_2_2_2 { | |||
92 | char name[8]; | 97 | char name[8]; |
93 | unsigned int caf; | 98 | unsigned int caf; |
94 | char reserved_2[8]; | 99 | char reserved_2[8]; |
95 | unsigned char mt_installed; | 100 | unsigned char mt_installed :1; |
96 | unsigned char mt_general; | 101 | unsigned char :2; |
97 | unsigned char mt_psmtid; | 102 | unsigned char mt_stid :5; |
103 | unsigned char :3; | ||
104 | unsigned char mt_gtid :5; | ||
105 | unsigned char :3; | ||
106 | unsigned char mt_psmtid :5; | ||
98 | char reserved_3[5]; | 107 | char reserved_3[5]; |
99 | unsigned short cpus_dedicated; | 108 | unsigned short cpus_dedicated; |
100 | unsigned short cpus_shared; | 109 | unsigned short cpus_shared; |
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index 692b9247c019..2fffc2c27581 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -96,6 +96,4 @@ void arch_release_task_struct(struct task_struct *tsk); | |||
96 | #define _TIF_31BIT _BITUL(TIF_31BIT) | 96 | #define _TIF_31BIT _BITUL(TIF_31BIT) |
97 | #define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP) | 97 | #define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP) |
98 | 98 | ||
99 | #define is_32bit_task() (test_thread_flag(TIF_31BIT)) | ||
100 | |||
101 | #endif /* _ASM_THREAD_INFO_H */ | 99 | #endif /* _ASM_THREAD_INFO_H */ |
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index 94fc55fc72ce..6b53962e807e 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h | |||
@@ -7,7 +7,7 @@ | |||
7 | struct sysinfo_15_1_x; | 7 | struct sysinfo_15_1_x; |
8 | struct cpu; | 8 | struct cpu; |
9 | 9 | ||
10 | #ifdef CONFIG_SCHED_BOOK | 10 | #ifdef CONFIG_SCHED_TOPOLOGY |
11 | 11 | ||
12 | struct cpu_topology_s390 { | 12 | struct cpu_topology_s390 { |
13 | unsigned short thread_id; | 13 | unsigned short thread_id; |
@@ -40,13 +40,13 @@ void store_topology(struct sysinfo_15_1_x *info); | |||
40 | void topology_expect_change(void); | 40 | void topology_expect_change(void); |
41 | const struct cpumask *cpu_coregroup_mask(int cpu); | 41 | const struct cpumask *cpu_coregroup_mask(int cpu); |
42 | 42 | ||
43 | #else /* CONFIG_SCHED_BOOK */ | 43 | #else /* CONFIG_SCHED_TOPOLOGY */ |
44 | 44 | ||
45 | static inline void topology_schedule_update(void) { } | 45 | static inline void topology_schedule_update(void) { } |
46 | static inline int topology_cpu_init(struct cpu *cpu) { return 0; } | 46 | static inline int topology_cpu_init(struct cpu *cpu) { return 0; } |
47 | static inline void topology_expect_change(void) { } | 47 | static inline void topology_expect_change(void) { } |
48 | 48 | ||
49 | #endif /* CONFIG_SCHED_BOOK */ | 49 | #endif /* CONFIG_SCHED_TOPOLOGY */ |
50 | 50 | ||
51 | #define POLARIZATION_UNKNOWN (-1) | 51 | #define POLARIZATION_UNKNOWN (-1) |
52 | #define POLARIZATION_HRZ (0) | 52 | #define POLARIZATION_HRZ (0) |
diff --git a/arch/s390/include/asm/vdso.h b/arch/s390/include/asm/vdso.h index 787acd4f9668..d0a2dbf2433d 100644 --- a/arch/s390/include/asm/vdso.h +++ b/arch/s390/include/asm/vdso.h | |||
@@ -38,12 +38,14 @@ struct vdso_data { | |||
38 | struct vdso_per_cpu_data { | 38 | struct vdso_per_cpu_data { |
39 | __u64 ectg_timer_base; | 39 | __u64 ectg_timer_base; |
40 | __u64 ectg_user_time; | 40 | __u64 ectg_user_time; |
41 | __u32 cpu_nr; | ||
42 | __u32 node_id; | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | extern struct vdso_data *vdso_data; | 45 | extern struct vdso_data *vdso_data; |
44 | 46 | ||
45 | int vdso_alloc_per_cpu(struct _lowcore *lowcore); | 47 | int vdso_alloc_per_cpu(struct lowcore *lowcore); |
46 | void vdso_free_per_cpu(struct _lowcore *lowcore); | 48 | void vdso_free_per_cpu(struct lowcore *lowcore); |
47 | 49 | ||
48 | #endif /* __ASSEMBLY__ */ | 50 | #endif /* __ASSEMBLY__ */ |
49 | #endif /* __S390_VDSO_H__ */ | 51 | #endif /* __S390_VDSO_H__ */ |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index dc167a23b920..2f5586ab8a6a 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -34,8 +34,10 @@ CFLAGS_sysinfo.o += -w | |||
34 | # | 34 | # |
35 | CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE) | 35 | CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE) |
36 | ifneq ($(CC_FLAGS_MARCH),-march=z900) | 36 | ifneq ($(CC_FLAGS_MARCH),-march=z900) |
37 | CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH) | 37 | CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH) |
38 | CFLAGS_sclp.o += -march=z900 | 38 | CFLAGS_sclp.o += -march=z900 |
39 | AFLAGS_REMOVE_head.o += $(CC_FLAGS_MARCH) | ||
40 | AFLAGS_head.o += -march=z900 | ||
39 | endif | 41 | endif |
40 | GCOV_PROFILE_sclp.o := n | 42 | GCOV_PROFILE_sclp.o := n |
41 | 43 | ||
@@ -50,7 +52,7 @@ extra-y += head.o head64.o vmlinux.lds | |||
50 | 52 | ||
51 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o | 53 | obj-$(CONFIG_MODULES) += s390_ksyms.o module.o |
52 | obj-$(CONFIG_SMP) += smp.o | 54 | obj-$(CONFIG_SMP) += smp.o |
53 | obj-$(CONFIG_SCHED_BOOK) += topology.o | 55 | obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o |
54 | obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o | 56 | obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o |
55 | obj-$(CONFIG_AUDIT) += audit.o | 57 | obj-$(CONFIG_AUDIT) += audit.o |
56 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o | 58 | compat-obj-$(CONFIG_AUDIT) += compat_audit.o |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 9cd248f637c7..53bbc9e8b281 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -80,6 +80,8 @@ int main(void) | |||
80 | OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); | 80 | OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); |
81 | OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); | 81 | OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); |
82 | OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); | 82 | OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); |
83 | OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr); | ||
84 | OFFSET(__VDSO_NODE_ID, vdso_per_cpu_data, node_id); | ||
83 | BLANK(); | 85 | BLANK(); |
84 | /* constants used by the vdso */ | 86 | /* constants used by the vdso */ |
85 | DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); | 87 | DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); |
@@ -97,95 +99,96 @@ int main(void) | |||
97 | OFFSET(__TIMER_IDLE_EXIT, s390_idle_data, timer_idle_exit); | 99 | OFFSET(__TIMER_IDLE_EXIT, s390_idle_data, timer_idle_exit); |
98 | BLANK(); | 100 | BLANK(); |
99 | /* hardware defined lowcore locations 0x000 - 0x1ff */ | 101 | /* hardware defined lowcore locations 0x000 - 0x1ff */ |
100 | OFFSET(__LC_EXT_PARAMS, _lowcore, ext_params); | 102 | OFFSET(__LC_EXT_PARAMS, lowcore, ext_params); |
101 | OFFSET(__LC_EXT_CPU_ADDR, _lowcore, ext_cpu_addr); | 103 | OFFSET(__LC_EXT_CPU_ADDR, lowcore, ext_cpu_addr); |
102 | OFFSET(__LC_EXT_INT_CODE, _lowcore, ext_int_code); | 104 | OFFSET(__LC_EXT_INT_CODE, lowcore, ext_int_code); |
103 | OFFSET(__LC_SVC_ILC, _lowcore, svc_ilc); | 105 | OFFSET(__LC_SVC_ILC, lowcore, svc_ilc); |
104 | OFFSET(__LC_SVC_INT_CODE, _lowcore, svc_code); | 106 | OFFSET(__LC_SVC_INT_CODE, lowcore, svc_code); |
105 | OFFSET(__LC_PGM_ILC, _lowcore, pgm_ilc); | 107 | OFFSET(__LC_PGM_ILC, lowcore, pgm_ilc); |
106 | OFFSET(__LC_PGM_INT_CODE, _lowcore, pgm_code); | 108 | OFFSET(__LC_PGM_INT_CODE, lowcore, pgm_code); |
107 | OFFSET(__LC_DATA_EXC_CODE, _lowcore, data_exc_code); | 109 | OFFSET(__LC_DATA_EXC_CODE, lowcore, data_exc_code); |
108 | OFFSET(__LC_MON_CLASS_NR, _lowcore, mon_class_num); | 110 | OFFSET(__LC_MON_CLASS_NR, lowcore, mon_class_num); |
109 | OFFSET(__LC_PER_CODE, _lowcore, per_code); | 111 | OFFSET(__LC_PER_CODE, lowcore, per_code); |
110 | OFFSET(__LC_PER_ATMID, _lowcore, per_atmid); | 112 | OFFSET(__LC_PER_ATMID, lowcore, per_atmid); |
111 | OFFSET(__LC_PER_ADDRESS, _lowcore, per_address); | 113 | OFFSET(__LC_PER_ADDRESS, lowcore, per_address); |
112 | OFFSET(__LC_EXC_ACCESS_ID, _lowcore, exc_access_id); | 114 | OFFSET(__LC_EXC_ACCESS_ID, lowcore, exc_access_id); |
113 | OFFSET(__LC_PER_ACCESS_ID, _lowcore, per_access_id); | 115 | OFFSET(__LC_PER_ACCESS_ID, lowcore, per_access_id); |
114 | OFFSET(__LC_OP_ACCESS_ID, _lowcore, op_access_id); | 116 | OFFSET(__LC_OP_ACCESS_ID, lowcore, op_access_id); |
115 | OFFSET(__LC_AR_MODE_ID, _lowcore, ar_mode_id); | 117 | OFFSET(__LC_AR_MODE_ID, lowcore, ar_mode_id); |
116 | OFFSET(__LC_TRANS_EXC_CODE, _lowcore, trans_exc_code); | 118 | OFFSET(__LC_TRANS_EXC_CODE, lowcore, trans_exc_code); |
117 | OFFSET(__LC_MON_CODE, _lowcore, monitor_code); | 119 | OFFSET(__LC_MON_CODE, lowcore, monitor_code); |
118 | OFFSET(__LC_SUBCHANNEL_ID, _lowcore, subchannel_id); | 120 | OFFSET(__LC_SUBCHANNEL_ID, lowcore, subchannel_id); |
119 | OFFSET(__LC_SUBCHANNEL_NR, _lowcore, subchannel_nr); | 121 | OFFSET(__LC_SUBCHANNEL_NR, lowcore, subchannel_nr); |
120 | OFFSET(__LC_IO_INT_PARM, _lowcore, io_int_parm); | 122 | OFFSET(__LC_IO_INT_PARM, lowcore, io_int_parm); |
121 | OFFSET(__LC_IO_INT_WORD, _lowcore, io_int_word); | 123 | OFFSET(__LC_IO_INT_WORD, lowcore, io_int_word); |
122 | OFFSET(__LC_STFL_FAC_LIST, _lowcore, stfl_fac_list); | 124 | OFFSET(__LC_STFL_FAC_LIST, lowcore, stfl_fac_list); |
123 | OFFSET(__LC_MCCK_CODE, _lowcore, mcck_interruption_code); | 125 | OFFSET(__LC_STFLE_FAC_LIST, lowcore, stfle_fac_list); |
124 | OFFSET(__LC_MCCK_FAIL_STOR_ADDR, _lowcore, failing_storage_address); | 126 | OFFSET(__LC_MCCK_CODE, lowcore, mcck_interruption_code); |
125 | OFFSET(__LC_LAST_BREAK, _lowcore, breaking_event_addr); | 127 | OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address); |
126 | OFFSET(__LC_RST_OLD_PSW, _lowcore, restart_old_psw); | 128 | OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr); |
127 | OFFSET(__LC_EXT_OLD_PSW, _lowcore, external_old_psw); | 129 | OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw); |
128 | OFFSET(__LC_SVC_OLD_PSW, _lowcore, svc_old_psw); | 130 | OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw); |
129 | OFFSET(__LC_PGM_OLD_PSW, _lowcore, program_old_psw); | 131 | OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw); |
130 | OFFSET(__LC_MCK_OLD_PSW, _lowcore, mcck_old_psw); | 132 | OFFSET(__LC_PGM_OLD_PSW, lowcore, program_old_psw); |
131 | OFFSET(__LC_IO_OLD_PSW, _lowcore, io_old_psw); | 133 | OFFSET(__LC_MCK_OLD_PSW, lowcore, mcck_old_psw); |
132 | OFFSET(__LC_RST_NEW_PSW, _lowcore, restart_psw); | 134 | OFFSET(__LC_IO_OLD_PSW, lowcore, io_old_psw); |
133 | OFFSET(__LC_EXT_NEW_PSW, _lowcore, external_new_psw); | 135 | OFFSET(__LC_RST_NEW_PSW, lowcore, restart_psw); |
134 | OFFSET(__LC_SVC_NEW_PSW, _lowcore, svc_new_psw); | 136 | OFFSET(__LC_EXT_NEW_PSW, lowcore, external_new_psw); |
135 | OFFSET(__LC_PGM_NEW_PSW, _lowcore, program_new_psw); | 137 | OFFSET(__LC_SVC_NEW_PSW, lowcore, svc_new_psw); |
136 | OFFSET(__LC_MCK_NEW_PSW, _lowcore, mcck_new_psw); | 138 | OFFSET(__LC_PGM_NEW_PSW, lowcore, program_new_psw); |
137 | OFFSET(__LC_IO_NEW_PSW, _lowcore, io_new_psw); | 139 | OFFSET(__LC_MCK_NEW_PSW, lowcore, mcck_new_psw); |
140 | OFFSET(__LC_IO_NEW_PSW, lowcore, io_new_psw); | ||
138 | /* software defined lowcore locations 0x200 - 0xdff*/ | 141 | /* software defined lowcore locations 0x200 - 0xdff*/ |
139 | OFFSET(__LC_SAVE_AREA_SYNC, _lowcore, save_area_sync); | 142 | OFFSET(__LC_SAVE_AREA_SYNC, lowcore, save_area_sync); |
140 | OFFSET(__LC_SAVE_AREA_ASYNC, _lowcore, save_area_async); | 143 | OFFSET(__LC_SAVE_AREA_ASYNC, lowcore, save_area_async); |
141 | OFFSET(__LC_SAVE_AREA_RESTART, _lowcore, save_area_restart); | 144 | OFFSET(__LC_SAVE_AREA_RESTART, lowcore, save_area_restart); |
142 | OFFSET(__LC_CPU_FLAGS, _lowcore, cpu_flags); | 145 | OFFSET(__LC_CPU_FLAGS, lowcore, cpu_flags); |
143 | OFFSET(__LC_RETURN_PSW, _lowcore, return_psw); | 146 | OFFSET(__LC_RETURN_PSW, lowcore, return_psw); |
144 | OFFSET(__LC_RETURN_MCCK_PSW, _lowcore, return_mcck_psw); | 147 | OFFSET(__LC_RETURN_MCCK_PSW, lowcore, return_mcck_psw); |
145 | OFFSET(__LC_SYNC_ENTER_TIMER, _lowcore, sync_enter_timer); | 148 | OFFSET(__LC_SYNC_ENTER_TIMER, lowcore, sync_enter_timer); |
146 | OFFSET(__LC_ASYNC_ENTER_TIMER, _lowcore, async_enter_timer); | 149 | OFFSET(__LC_ASYNC_ENTER_TIMER, lowcore, async_enter_timer); |
147 | OFFSET(__LC_MCCK_ENTER_TIMER, _lowcore, mcck_enter_timer); | 150 | OFFSET(__LC_MCCK_ENTER_TIMER, lowcore, mcck_enter_timer); |
148 | OFFSET(__LC_EXIT_TIMER, _lowcore, exit_timer); | 151 | OFFSET(__LC_EXIT_TIMER, lowcore, exit_timer); |
149 | OFFSET(__LC_USER_TIMER, _lowcore, user_timer); | 152 | OFFSET(__LC_USER_TIMER, lowcore, user_timer); |
150 | OFFSET(__LC_SYSTEM_TIMER, _lowcore, system_timer); | 153 | OFFSET(__LC_SYSTEM_TIMER, lowcore, system_timer); |
151 | OFFSET(__LC_STEAL_TIMER, _lowcore, steal_timer); | 154 | OFFSET(__LC_STEAL_TIMER, lowcore, steal_timer); |
152 | OFFSET(__LC_LAST_UPDATE_TIMER, _lowcore, last_update_timer); | 155 | OFFSET(__LC_LAST_UPDATE_TIMER, lowcore, last_update_timer); |
153 | OFFSET(__LC_LAST_UPDATE_CLOCK, _lowcore, last_update_clock); | 156 | OFFSET(__LC_LAST_UPDATE_CLOCK, lowcore, last_update_clock); |
154 | OFFSET(__LC_INT_CLOCK, _lowcore, int_clock); | 157 | OFFSET(__LC_INT_CLOCK, lowcore, int_clock); |
155 | OFFSET(__LC_MCCK_CLOCK, _lowcore, mcck_clock); | 158 | OFFSET(__LC_MCCK_CLOCK, lowcore, mcck_clock); |
156 | OFFSET(__LC_CURRENT, _lowcore, current_task); | 159 | OFFSET(__LC_CURRENT, lowcore, current_task); |
157 | OFFSET(__LC_THREAD_INFO, _lowcore, thread_info); | 160 | OFFSET(__LC_THREAD_INFO, lowcore, thread_info); |
158 | OFFSET(__LC_KERNEL_STACK, _lowcore, kernel_stack); | 161 | OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack); |
159 | OFFSET(__LC_ASYNC_STACK, _lowcore, async_stack); | 162 | OFFSET(__LC_ASYNC_STACK, lowcore, async_stack); |
160 | OFFSET(__LC_PANIC_STACK, _lowcore, panic_stack); | 163 | OFFSET(__LC_PANIC_STACK, lowcore, panic_stack); |
161 | OFFSET(__LC_RESTART_STACK, _lowcore, restart_stack); | 164 | OFFSET(__LC_RESTART_STACK, lowcore, restart_stack); |
162 | OFFSET(__LC_RESTART_FN, _lowcore, restart_fn); | 165 | OFFSET(__LC_RESTART_FN, lowcore, restart_fn); |
163 | OFFSET(__LC_RESTART_DATA, _lowcore, restart_data); | 166 | OFFSET(__LC_RESTART_DATA, lowcore, restart_data); |
164 | OFFSET(__LC_RESTART_SOURCE, _lowcore, restart_source); | 167 | OFFSET(__LC_RESTART_SOURCE, lowcore, restart_source); |
165 | OFFSET(__LC_USER_ASCE, _lowcore, user_asce); | 168 | OFFSET(__LC_USER_ASCE, lowcore, user_asce); |
166 | OFFSET(__LC_LPP, _lowcore, lpp); | 169 | OFFSET(__LC_LPP, lowcore, lpp); |
167 | OFFSET(__LC_CURRENT_PID, _lowcore, current_pid); | 170 | OFFSET(__LC_CURRENT_PID, lowcore, current_pid); |
168 | OFFSET(__LC_PERCPU_OFFSET, _lowcore, percpu_offset); | 171 | OFFSET(__LC_PERCPU_OFFSET, lowcore, percpu_offset); |
169 | OFFSET(__LC_VDSO_PER_CPU, _lowcore, vdso_per_cpu_data); | 172 | OFFSET(__LC_VDSO_PER_CPU, lowcore, vdso_per_cpu_data); |
170 | OFFSET(__LC_MACHINE_FLAGS, _lowcore, machine_flags); | 173 | OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags); |
171 | OFFSET(__LC_GMAP, _lowcore, gmap); | 174 | OFFSET(__LC_GMAP, lowcore, gmap); |
172 | OFFSET(__LC_PASTE, _lowcore, paste); | 175 | OFFSET(__LC_PASTE, lowcore, paste); |
173 | /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ | 176 | /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ |
174 | OFFSET(__LC_DUMP_REIPL, _lowcore, ipib); | 177 | OFFSET(__LC_DUMP_REIPL, lowcore, ipib); |
175 | /* hardware defined lowcore locations 0x1000 - 0x18ff */ | 178 | /* hardware defined lowcore locations 0x1000 - 0x18ff */ |
176 | OFFSET(__LC_VX_SAVE_AREA_ADDR, _lowcore, vector_save_area_addr); | 179 | OFFSET(__LC_VX_SAVE_AREA_ADDR, lowcore, vector_save_area_addr); |
177 | OFFSET(__LC_EXT_PARAMS2, _lowcore, ext_params2); | 180 | OFFSET(__LC_EXT_PARAMS2, lowcore, ext_params2); |
178 | OFFSET(SAVE_AREA_BASE, _lowcore, floating_pt_save_area); | 181 | OFFSET(__LC_FPREGS_SAVE_AREA, lowcore, floating_pt_save_area); |
179 | OFFSET(__LC_FPREGS_SAVE_AREA, _lowcore, floating_pt_save_area); | 182 | OFFSET(__LC_GPREGS_SAVE_AREA, lowcore, gpregs_save_area); |
180 | OFFSET(__LC_GPREGS_SAVE_AREA, _lowcore, gpregs_save_area); | 183 | OFFSET(__LC_PSW_SAVE_AREA, lowcore, psw_save_area); |
181 | OFFSET(__LC_PSW_SAVE_AREA, _lowcore, psw_save_area); | 184 | OFFSET(__LC_PREFIX_SAVE_AREA, lowcore, prefixreg_save_area); |
182 | OFFSET(__LC_PREFIX_SAVE_AREA, _lowcore, prefixreg_save_area); | 185 | OFFSET(__LC_FP_CREG_SAVE_AREA, lowcore, fpt_creg_save_area); |
183 | OFFSET(__LC_FP_CREG_SAVE_AREA, _lowcore, fpt_creg_save_area); | 186 | OFFSET(__LC_TOD_PROGREG_SAVE_AREA, lowcore, tod_progreg_save_area); |
184 | OFFSET(__LC_CPU_TIMER_SAVE_AREA, _lowcore, cpu_timer_save_area); | 187 | OFFSET(__LC_CPU_TIMER_SAVE_AREA, lowcore, cpu_timer_save_area); |
185 | OFFSET(__LC_CLOCK_COMP_SAVE_AREA, _lowcore, clock_comp_save_area); | 188 | OFFSET(__LC_CLOCK_COMP_SAVE_AREA, lowcore, clock_comp_save_area); |
186 | OFFSET(__LC_AREGS_SAVE_AREA, _lowcore, access_regs_save_area); | 189 | OFFSET(__LC_AREGS_SAVE_AREA, lowcore, access_regs_save_area); |
187 | OFFSET(__LC_CREGS_SAVE_AREA, _lowcore, cregs_save_area); | 190 | OFFSET(__LC_CREGS_SAVE_AREA, lowcore, cregs_save_area); |
188 | OFFSET(__LC_PGM_TDB, _lowcore, pgm_tdb); | 191 | OFFSET(__LC_PGM_TDB, lowcore, pgm_tdb); |
189 | BLANK(); | 192 | BLANK(); |
190 | /* gmap/sie offsets */ | 193 | /* gmap/sie offsets */ |
191 | OFFSET(__GMAP_ASCE, gmap, asce); | 194 | OFFSET(__GMAP_ASCE, gmap, asce); |
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index 171e09bb8ea2..a92b39fd0e63 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/bootmem.h> | 14 | #include <linux/bootmem.h> |
15 | #include <linux/elf.h> | 15 | #include <linux/elf.h> |
16 | #include <asm/asm-offsets.h> | ||
16 | #include <linux/memblock.h> | 17 | #include <linux/memblock.h> |
17 | #include <asm/os_info.h> | 18 | #include <asm/os_info.h> |
18 | #include <asm/elf.h> | 19 | #include <asm/elf.h> |
@@ -32,7 +33,84 @@ static struct memblock_type oldmem_type = { | |||
32 | .regions = &oldmem_region, | 33 | .regions = &oldmem_region, |
33 | }; | 34 | }; |
34 | 35 | ||
35 | struct dump_save_areas dump_save_areas; | 36 | struct save_area { |
37 | struct list_head list; | ||
38 | u64 psw[2]; | ||
39 | u64 ctrs[16]; | ||
40 | u64 gprs[16]; | ||
41 | u32 acrs[16]; | ||
42 | u64 fprs[16]; | ||
43 | u32 fpc; | ||
44 | u32 prefix; | ||
45 | u64 todpreg; | ||
46 | u64 timer; | ||
47 | u64 todcmp; | ||
48 | u64 vxrs_low[16]; | ||
49 | __vector128 vxrs_high[16]; | ||
50 | }; | ||
51 | |||
52 | static LIST_HEAD(dump_save_areas); | ||
53 | |||
54 | /* | ||
55 | * Allocate a save area | ||
56 | */ | ||
57 | struct save_area * __init save_area_alloc(bool is_boot_cpu) | ||
58 | { | ||
59 | struct save_area *sa; | ||
60 | |||
61 | sa = (void *) memblock_alloc(sizeof(*sa), 8); | ||
62 | if (!sa) | ||
63 | return NULL; | ||
64 | if (is_boot_cpu) | ||
65 | list_add(&sa->list, &dump_save_areas); | ||
66 | else | ||
67 | list_add_tail(&sa->list, &dump_save_areas); | ||
68 | return sa; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * Return the address of the save area for the boot CPU | ||
73 | */ | ||
74 | struct save_area * __init save_area_boot_cpu(void) | ||
75 | { | ||
76 | if (list_empty(&dump_save_areas)) | ||
77 | return NULL; | ||
78 | return list_first_entry(&dump_save_areas, struct save_area, list); | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Copy CPU registers into the save area | ||
83 | */ | ||
84 | void __init save_area_add_regs(struct save_area *sa, void *regs) | ||
85 | { | ||
86 | struct lowcore *lc; | ||
87 | |||
88 | lc = (struct lowcore *)(regs - __LC_FPREGS_SAVE_AREA); | ||
89 | memcpy(&sa->psw, &lc->psw_save_area, sizeof(sa->psw)); | ||
90 | memcpy(&sa->ctrs, &lc->cregs_save_area, sizeof(sa->ctrs)); | ||
91 | memcpy(&sa->gprs, &lc->gpregs_save_area, sizeof(sa->gprs)); | ||
92 | memcpy(&sa->acrs, &lc->access_regs_save_area, sizeof(sa->acrs)); | ||
93 | memcpy(&sa->fprs, &lc->floating_pt_save_area, sizeof(sa->fprs)); | ||
94 | memcpy(&sa->fpc, &lc->fpt_creg_save_area, sizeof(sa->fpc)); | ||
95 | memcpy(&sa->prefix, &lc->prefixreg_save_area, sizeof(sa->prefix)); | ||
96 | memcpy(&sa->todpreg, &lc->tod_progreg_save_area, sizeof(sa->todpreg)); | ||
97 | memcpy(&sa->timer, &lc->cpu_timer_save_area, sizeof(sa->timer)); | ||
98 | memcpy(&sa->todcmp, &lc->clock_comp_save_area, sizeof(sa->todcmp)); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Copy vector registers into the save area | ||
103 | */ | ||
104 | void __init save_area_add_vxrs(struct save_area *sa, __vector128 *vxrs) | ||
105 | { | ||
106 | int i; | ||
107 | |||
108 | /* Copy lower halves of vector registers 0-15 */ | ||
109 | for (i = 0; i < 16; i++) | ||
110 | memcpy(&sa->vxrs_low[i], &vxrs[i].u[2], 8); | ||
111 | /* Copy vector registers 16-31 */ | ||
112 | memcpy(sa->vxrs_high, vxrs + 16, 16 * sizeof(__vector128)); | ||
113 | } | ||
36 | 114 | ||
37 | /* | 115 | /* |
38 | * Return physical address for virtual address | 116 | * Return physical address for virtual address |
@@ -51,79 +129,85 @@ static inline void *load_real_addr(void *addr) | |||
51 | } | 129 | } |
52 | 130 | ||
53 | /* | 131 | /* |
54 | * Copy real to virtual or real memory | 132 | * Copy memory of the old, dumped system to a kernel space virtual address |
55 | */ | ||
56 | static int copy_from_realmem(void *dest, void *src, size_t count) | ||
57 | { | ||
58 | unsigned long size; | ||
59 | |||
60 | if (!count) | ||
61 | return 0; | ||
62 | if (!is_vmalloc_or_module_addr(dest)) | ||
63 | return memcpy_real(dest, src, count); | ||
64 | do { | ||
65 | size = min(count, PAGE_SIZE - (__pa(dest) & ~PAGE_MASK)); | ||
66 | if (memcpy_real(load_real_addr(dest), src, size)) | ||
67 | return -EFAULT; | ||
68 | count -= size; | ||
69 | dest += size; | ||
70 | src += size; | ||
71 | } while (count); | ||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * Pointer to ELF header in new kernel | ||
77 | */ | ||
78 | static void *elfcorehdr_newmem; | ||
79 | |||
80 | /* | ||
81 | * Copy one page from zfcpdump "oldmem" | ||
82 | * | ||
83 | * For pages below HSA size memory from the HSA is copied. Otherwise | ||
84 | * real memory copy is used. | ||
85 | */ | 133 | */ |
86 | static ssize_t copy_oldmem_page_zfcpdump(char *buf, size_t csize, | 134 | int copy_oldmem_kernel(void *dst, void *src, size_t count) |
87 | unsigned long src, int userbuf) | ||
88 | { | 135 | { |
136 | unsigned long from, len; | ||
137 | void *ra; | ||
89 | int rc; | 138 | int rc; |
90 | 139 | ||
91 | if (src < sclp.hsa_size) { | 140 | while (count) { |
92 | rc = memcpy_hsa(buf, src, csize, userbuf); | 141 | from = __pa(src); |
93 | } else { | 142 | if (!OLDMEM_BASE && from < sclp.hsa_size) { |
94 | if (userbuf) | 143 | /* Copy from zfcpdump HSA area */ |
95 | rc = copy_to_user_real((void __force __user *) buf, | 144 | len = min(count, sclp.hsa_size - from); |
96 | (void *) src, csize); | 145 | rc = memcpy_hsa_kernel(dst, from, len); |
97 | else | 146 | if (rc) |
98 | rc = memcpy_real(buf, (void *) src, csize); | 147 | return rc; |
148 | } else { | ||
149 | /* Check for swapped kdump oldmem areas */ | ||
150 | if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) { | ||
151 | from -= OLDMEM_BASE; | ||
152 | len = min(count, OLDMEM_SIZE - from); | ||
153 | } else if (OLDMEM_BASE && from < OLDMEM_SIZE) { | ||
154 | len = min(count, OLDMEM_SIZE - from); | ||
155 | from += OLDMEM_BASE; | ||
156 | } else { | ||
157 | len = count; | ||
158 | } | ||
159 | if (is_vmalloc_or_module_addr(dst)) { | ||
160 | ra = load_real_addr(dst); | ||
161 | len = min(PAGE_SIZE - offset_in_page(ra), len); | ||
162 | } else { | ||
163 | ra = dst; | ||
164 | } | ||
165 | if (memcpy_real(ra, (void *) from, len)) | ||
166 | return -EFAULT; | ||
167 | } | ||
168 | dst += len; | ||
169 | src += len; | ||
170 | count -= len; | ||
99 | } | 171 | } |
100 | return rc ? rc : csize; | 172 | return 0; |
101 | } | 173 | } |
102 | 174 | ||
103 | /* | 175 | /* |
104 | * Copy one page from kdump "oldmem" | 176 | * Copy memory of the old, dumped system to a user space virtual address |
105 | * | ||
106 | * For the kdump reserved memory this functions performs a swap operation: | ||
107 | * - [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] is mapped to [0 - OLDMEM_SIZE]. | ||
108 | * - [0 - OLDMEM_SIZE] is mapped to [OLDMEM_BASE - OLDMEM_BASE + OLDMEM_SIZE] | ||
109 | */ | 177 | */ |
110 | static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize, | 178 | int copy_oldmem_user(void __user *dst, void *src, size_t count) |
111 | unsigned long src, int userbuf) | ||
112 | |||
113 | { | 179 | { |
180 | unsigned long from, len; | ||
114 | int rc; | 181 | int rc; |
115 | 182 | ||
116 | if (src < OLDMEM_SIZE) | 183 | while (count) { |
117 | src += OLDMEM_BASE; | 184 | from = __pa(src); |
118 | else if (src > OLDMEM_BASE && | 185 | if (!OLDMEM_BASE && from < sclp.hsa_size) { |
119 | src < OLDMEM_BASE + OLDMEM_SIZE) | 186 | /* Copy from zfcpdump HSA area */ |
120 | src -= OLDMEM_BASE; | 187 | len = min(count, sclp.hsa_size - from); |
121 | if (userbuf) | 188 | rc = memcpy_hsa_user(dst, from, len); |
122 | rc = copy_to_user_real((void __force __user *) buf, | 189 | if (rc) |
123 | (void *) src, csize); | 190 | return rc; |
124 | else | 191 | } else { |
125 | rc = copy_from_realmem(buf, (void *) src, csize); | 192 | /* Check for swapped kdump oldmem areas */ |
126 | return (rc == 0) ? rc : csize; | 193 | if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) { |
194 | from -= OLDMEM_BASE; | ||
195 | len = min(count, OLDMEM_SIZE - from); | ||
196 | } else if (OLDMEM_BASE && from < OLDMEM_SIZE) { | ||
197 | len = min(count, OLDMEM_SIZE - from); | ||
198 | from += OLDMEM_BASE; | ||
199 | } else { | ||
200 | len = count; | ||
201 | } | ||
202 | rc = copy_to_user_real(dst, (void *) from, count); | ||
203 | if (rc) | ||
204 | return rc; | ||
205 | } | ||
206 | dst += len; | ||
207 | src += len; | ||
208 | count -= len; | ||
209 | } | ||
210 | return 0; | ||
127 | } | 211 | } |
128 | 212 | ||
129 | /* | 213 | /* |
@@ -132,15 +216,17 @@ static ssize_t copy_oldmem_page_kdump(char *buf, size_t csize, | |||
132 | ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, | 216 | ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, |
133 | unsigned long offset, int userbuf) | 217 | unsigned long offset, int userbuf) |
134 | { | 218 | { |
135 | unsigned long src; | 219 | void *src; |
220 | int rc; | ||
136 | 221 | ||
137 | if (!csize) | 222 | if (!csize) |
138 | return 0; | 223 | return 0; |
139 | src = (pfn << PAGE_SHIFT) + offset; | 224 | src = (void *) (pfn << PAGE_SHIFT) + offset; |
140 | if (OLDMEM_BASE) | 225 | if (userbuf) |
141 | return copy_oldmem_page_kdump(buf, csize, src, userbuf); | 226 | rc = copy_oldmem_user((void __force __user *) buf, src, csize); |
142 | else | 227 | else |
143 | return copy_oldmem_page_zfcpdump(buf, csize, src, userbuf); | 228 | rc = copy_oldmem_kernel((void *) buf, src, csize); |
229 | return rc; | ||
144 | } | 230 | } |
145 | 231 | ||
146 | /* | 232 | /* |
@@ -209,33 +295,6 @@ int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from, | |||
209 | } | 295 | } |
210 | 296 | ||
211 | /* | 297 | /* |
212 | * Copy memory from old kernel | ||
213 | */ | ||
214 | int copy_from_oldmem(void *dest, void *src, size_t count) | ||
215 | { | ||
216 | unsigned long copied = 0; | ||
217 | int rc; | ||
218 | |||
219 | if (OLDMEM_BASE) { | ||
220 | if ((unsigned long) src < OLDMEM_SIZE) { | ||
221 | copied = min(count, OLDMEM_SIZE - (unsigned long) src); | ||
222 | rc = copy_from_realmem(dest, src + OLDMEM_BASE, copied); | ||
223 | if (rc) | ||
224 | return rc; | ||
225 | } | ||
226 | } else { | ||
227 | unsigned long hsa_end = sclp.hsa_size; | ||
228 | if ((unsigned long) src < hsa_end) { | ||
229 | copied = min(count, hsa_end - (unsigned long) src); | ||
230 | rc = memcpy_hsa(dest, (unsigned long) src, copied, 0); | ||
231 | if (rc) | ||
232 | return rc; | ||
233 | } | ||
234 | } | ||
235 | return copy_from_realmem(dest + copied, src + copied, count - copied); | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * Alloc memory and panic in case of ENOMEM | 298 | * Alloc memory and panic in case of ENOMEM |
240 | */ | 299 | */ |
241 | static void *kzalloc_panic(int len) | 300 | static void *kzalloc_panic(int len) |
@@ -251,8 +310,8 @@ static void *kzalloc_panic(int len) | |||
251 | /* | 310 | /* |
252 | * Initialize ELF note | 311 | * Initialize ELF note |
253 | */ | 312 | */ |
254 | static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len, | 313 | static void *nt_init_name(void *buf, Elf64_Word type, void *desc, int d_len, |
255 | const char *name) | 314 | const char *name) |
256 | { | 315 | { |
257 | Elf64_Nhdr *note; | 316 | Elf64_Nhdr *note; |
258 | u64 len; | 317 | u64 len; |
@@ -272,136 +331,42 @@ static void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len, | |||
272 | return PTR_ADD(buf, len); | 331 | return PTR_ADD(buf, len); |
273 | } | 332 | } |
274 | 333 | ||
275 | /* | 334 | static inline void *nt_init(void *buf, Elf64_Word type, void *desc, int d_len) |
276 | * Initialize prstatus note | ||
277 | */ | ||
278 | static void *nt_prstatus(void *ptr, struct save_area *sa) | ||
279 | { | 335 | { |
280 | struct elf_prstatus nt_prstatus; | 336 | return nt_init_name(buf, type, desc, d_len, KEXEC_CORE_NOTE_NAME); |
281 | static int cpu_nr = 1; | ||
282 | |||
283 | memset(&nt_prstatus, 0, sizeof(nt_prstatus)); | ||
284 | memcpy(&nt_prstatus.pr_reg.gprs, sa->gp_regs, sizeof(sa->gp_regs)); | ||
285 | memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw)); | ||
286 | memcpy(&nt_prstatus.pr_reg.acrs, sa->acc_regs, sizeof(sa->acc_regs)); | ||
287 | nt_prstatus.pr_pid = cpu_nr; | ||
288 | cpu_nr++; | ||
289 | |||
290 | return nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus), | ||
291 | "CORE"); | ||
292 | } | 337 | } |
293 | 338 | ||
294 | /* | 339 | /* |
295 | * Initialize fpregset (floating point) note | 340 | * Fill ELF notes for one CPU with save area registers |
296 | */ | 341 | */ |
297 | static void *nt_fpregset(void *ptr, struct save_area *sa) | 342 | static void *fill_cpu_elf_notes(void *ptr, int cpu, struct save_area *sa) |
298 | { | 343 | { |
344 | struct elf_prstatus nt_prstatus; | ||
299 | elf_fpregset_t nt_fpregset; | 345 | elf_fpregset_t nt_fpregset; |
300 | 346 | ||
347 | /* Prepare prstatus note */ | ||
348 | memset(&nt_prstatus, 0, sizeof(nt_prstatus)); | ||
349 | memcpy(&nt_prstatus.pr_reg.gprs, sa->gprs, sizeof(sa->gprs)); | ||
350 | memcpy(&nt_prstatus.pr_reg.psw, sa->psw, sizeof(sa->psw)); | ||
351 | memcpy(&nt_prstatus.pr_reg.acrs, sa->acrs, sizeof(sa->acrs)); | ||
352 | nt_prstatus.pr_pid = cpu; | ||
353 | /* Prepare fpregset (floating point) note */ | ||
301 | memset(&nt_fpregset, 0, sizeof(nt_fpregset)); | 354 | memset(&nt_fpregset, 0, sizeof(nt_fpregset)); |
302 | memcpy(&nt_fpregset.fpc, &sa->fp_ctrl_reg, sizeof(sa->fp_ctrl_reg)); | 355 | memcpy(&nt_fpregset.fpc, &sa->fpc, sizeof(sa->fpc)); |
303 | memcpy(&nt_fpregset.fprs, &sa->fp_regs, sizeof(sa->fp_regs)); | 356 | memcpy(&nt_fpregset.fprs, &sa->fprs, sizeof(sa->fprs)); |
304 | 357 | /* Create ELF notes for the CPU */ | |
305 | return nt_init(ptr, NT_PRFPREG, &nt_fpregset, sizeof(nt_fpregset), | 358 | ptr = nt_init(ptr, NT_PRSTATUS, &nt_prstatus, sizeof(nt_prstatus)); |
306 | "CORE"); | 359 | ptr = nt_init(ptr, NT_PRFPREG, &nt_fpregset, sizeof(nt_fpregset)); |
307 | } | 360 | ptr = nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer)); |
308 | 361 | ptr = nt_init(ptr, NT_S390_TODCMP, &sa->todcmp, sizeof(sa->todcmp)); | |
309 | /* | 362 | ptr = nt_init(ptr, NT_S390_TODPREG, &sa->todpreg, sizeof(sa->todpreg)); |
310 | * Initialize timer note | 363 | ptr = nt_init(ptr, NT_S390_CTRS, &sa->ctrs, sizeof(sa->ctrs)); |
311 | */ | 364 | ptr = nt_init(ptr, NT_S390_PREFIX, &sa->prefix, sizeof(sa->prefix)); |
312 | static void *nt_s390_timer(void *ptr, struct save_area *sa) | 365 | if (MACHINE_HAS_VX) { |
313 | { | 366 | ptr = nt_init(ptr, NT_S390_VXRS_HIGH, |
314 | return nt_init(ptr, NT_S390_TIMER, &sa->timer, sizeof(sa->timer), | 367 | &sa->vxrs_high, sizeof(sa->vxrs_high)); |
315 | KEXEC_CORE_NOTE_NAME); | 368 | ptr = nt_init(ptr, NT_S390_VXRS_LOW, |
316 | } | 369 | &sa->vxrs_low, sizeof(sa->vxrs_low)); |
317 | |||
318 | /* | ||
319 | * Initialize TOD clock comparator note | ||
320 | */ | ||
321 | static void *nt_s390_tod_cmp(void *ptr, struct save_area *sa) | ||
322 | { | ||
323 | return nt_init(ptr, NT_S390_TODCMP, &sa->clk_cmp, | ||
324 | sizeof(sa->clk_cmp), KEXEC_CORE_NOTE_NAME); | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * Initialize TOD programmable register note | ||
329 | */ | ||
330 | static void *nt_s390_tod_preg(void *ptr, struct save_area *sa) | ||
331 | { | ||
332 | return nt_init(ptr, NT_S390_TODPREG, &sa->tod_reg, | ||
333 | sizeof(sa->tod_reg), KEXEC_CORE_NOTE_NAME); | ||
334 | } | ||
335 | |||
336 | /* | ||
337 | * Initialize control register note | ||
338 | */ | ||
339 | static void *nt_s390_ctrs(void *ptr, struct save_area *sa) | ||
340 | { | ||
341 | return nt_init(ptr, NT_S390_CTRS, &sa->ctrl_regs, | ||
342 | sizeof(sa->ctrl_regs), KEXEC_CORE_NOTE_NAME); | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * Initialize prefix register note | ||
347 | */ | ||
348 | static void *nt_s390_prefix(void *ptr, struct save_area *sa) | ||
349 | { | ||
350 | return nt_init(ptr, NT_S390_PREFIX, &sa->pref_reg, | ||
351 | sizeof(sa->pref_reg), KEXEC_CORE_NOTE_NAME); | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * Initialize vxrs high note (full 128 bit VX registers 16-31) | ||
356 | */ | ||
357 | static void *nt_s390_vx_high(void *ptr, __vector128 *vx_regs) | ||
358 | { | ||
359 | return nt_init(ptr, NT_S390_VXRS_HIGH, &vx_regs[16], | ||
360 | 16 * sizeof(__vector128), KEXEC_CORE_NOTE_NAME); | ||
361 | } | ||
362 | |||
363 | /* | ||
364 | * Initialize vxrs low note (lower halves of VX registers 0-15) | ||
365 | */ | ||
366 | static void *nt_s390_vx_low(void *ptr, __vector128 *vx_regs) | ||
367 | { | ||
368 | Elf64_Nhdr *note; | ||
369 | u64 len; | ||
370 | int i; | ||
371 | |||
372 | note = (Elf64_Nhdr *)ptr; | ||
373 | note->n_namesz = strlen(KEXEC_CORE_NOTE_NAME) + 1; | ||
374 | note->n_descsz = 16 * 8; | ||
375 | note->n_type = NT_S390_VXRS_LOW; | ||
376 | len = sizeof(Elf64_Nhdr); | ||
377 | |||
378 | memcpy(ptr + len, KEXEC_CORE_NOTE_NAME, note->n_namesz); | ||
379 | len = roundup(len + note->n_namesz, 4); | ||
380 | |||
381 | ptr += len; | ||
382 | /* Copy lower halves of SIMD registers 0-15 */ | ||
383 | for (i = 0; i < 16; i++) { | ||
384 | memcpy(ptr, &vx_regs[i].u[2], 8); | ||
385 | ptr += 8; | ||
386 | } | ||
387 | return ptr; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * Fill ELF notes for one CPU with save area registers | ||
392 | */ | ||
393 | void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vx_regs) | ||
394 | { | ||
395 | ptr = nt_prstatus(ptr, sa); | ||
396 | ptr = nt_fpregset(ptr, sa); | ||
397 | ptr = nt_s390_timer(ptr, sa); | ||
398 | ptr = nt_s390_tod_cmp(ptr, sa); | ||
399 | ptr = nt_s390_tod_preg(ptr, sa); | ||
400 | ptr = nt_s390_ctrs(ptr, sa); | ||
401 | ptr = nt_s390_prefix(ptr, sa); | ||
402 | if (MACHINE_HAS_VX && vx_regs) { | ||
403 | ptr = nt_s390_vx_low(ptr, vx_regs); | ||
404 | ptr = nt_s390_vx_high(ptr, vx_regs); | ||
405 | } | 370 | } |
406 | return ptr; | 371 | return ptr; |
407 | } | 372 | } |
@@ -416,8 +381,7 @@ static void *nt_prpsinfo(void *ptr) | |||
416 | memset(&prpsinfo, 0, sizeof(prpsinfo)); | 381 | memset(&prpsinfo, 0, sizeof(prpsinfo)); |
417 | prpsinfo.pr_sname = 'R'; | 382 | prpsinfo.pr_sname = 'R'; |
418 | strcpy(prpsinfo.pr_fname, "vmlinux"); | 383 | strcpy(prpsinfo.pr_fname, "vmlinux"); |
419 | return nt_init(ptr, NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo), | 384 | return nt_init(ptr, NT_PRPSINFO, &prpsinfo, sizeof(prpsinfo)); |
420 | KEXEC_CORE_NOTE_NAME); | ||
421 | } | 385 | } |
422 | 386 | ||
423 | /* | 387 | /* |
@@ -429,17 +393,18 @@ static void *get_vmcoreinfo_old(unsigned long *size) | |||
429 | Elf64_Nhdr note; | 393 | Elf64_Nhdr note; |
430 | void *addr; | 394 | void *addr; |
431 | 395 | ||
432 | if (copy_from_oldmem(&addr, &S390_lowcore.vmcore_info, sizeof(addr))) | 396 | if (copy_oldmem_kernel(&addr, &S390_lowcore.vmcore_info, sizeof(addr))) |
433 | return NULL; | 397 | return NULL; |
434 | memset(nt_name, 0, sizeof(nt_name)); | 398 | memset(nt_name, 0, sizeof(nt_name)); |
435 | if (copy_from_oldmem(¬e, addr, sizeof(note))) | 399 | if (copy_oldmem_kernel(¬e, addr, sizeof(note))) |
436 | return NULL; | 400 | return NULL; |
437 | if (copy_from_oldmem(nt_name, addr + sizeof(note), sizeof(nt_name) - 1)) | 401 | if (copy_oldmem_kernel(nt_name, addr + sizeof(note), |
402 | sizeof(nt_name) - 1)) | ||
438 | return NULL; | 403 | return NULL; |
439 | if (strcmp(nt_name, "VMCOREINFO") != 0) | 404 | if (strcmp(nt_name, "VMCOREINFO") != 0) |
440 | return NULL; | 405 | return NULL; |
441 | vmcoreinfo = kzalloc_panic(note.n_descsz); | 406 | vmcoreinfo = kzalloc_panic(note.n_descsz); |
442 | if (copy_from_oldmem(vmcoreinfo, addr + 24, note.n_descsz)) | 407 | if (copy_oldmem_kernel(vmcoreinfo, addr + 24, note.n_descsz)) |
443 | return NULL; | 408 | return NULL; |
444 | *size = note.n_descsz; | 409 | *size = note.n_descsz; |
445 | return vmcoreinfo; | 410 | return vmcoreinfo; |
@@ -458,7 +423,7 @@ static void *nt_vmcoreinfo(void *ptr) | |||
458 | vmcoreinfo = get_vmcoreinfo_old(&size); | 423 | vmcoreinfo = get_vmcoreinfo_old(&size); |
459 | if (!vmcoreinfo) | 424 | if (!vmcoreinfo) |
460 | return ptr; | 425 | return ptr; |
461 | return nt_init(ptr, 0, vmcoreinfo, size, "VMCOREINFO"); | 426 | return nt_init_name(ptr, 0, vmcoreinfo, size, "VMCOREINFO"); |
462 | } | 427 | } |
463 | 428 | ||
464 | /* | 429 | /* |
@@ -487,13 +452,12 @@ static void *ehdr_init(Elf64_Ehdr *ehdr, int mem_chunk_cnt) | |||
487 | */ | 452 | */ |
488 | static int get_cpu_cnt(void) | 453 | static int get_cpu_cnt(void) |
489 | { | 454 | { |
490 | int i, cpus = 0; | 455 | struct save_area *sa; |
456 | int cpus = 0; | ||
491 | 457 | ||
492 | for (i = 0; i < dump_save_areas.count; i++) { | 458 | list_for_each_entry(sa, &dump_save_areas, list) |
493 | if (dump_save_areas.areas[i]->sa.pref_reg == 0) | 459 | if (sa->prefix != 0) |
494 | continue; | 460 | cpus++; |
495 | cpus++; | ||
496 | } | ||
497 | return cpus; | 461 | return cpus; |
498 | } | 462 | } |
499 | 463 | ||
@@ -538,18 +502,16 @@ static void loads_init(Elf64_Phdr *phdr, u64 loads_offset) | |||
538 | */ | 502 | */ |
539 | static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) | 503 | static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) |
540 | { | 504 | { |
541 | struct save_area_ext *sa_ext; | 505 | struct save_area *sa; |
542 | void *ptr_start = ptr; | 506 | void *ptr_start = ptr; |
543 | int i; | 507 | int cpu; |
544 | 508 | ||
545 | ptr = nt_prpsinfo(ptr); | 509 | ptr = nt_prpsinfo(ptr); |
546 | 510 | ||
547 | for (i = 0; i < dump_save_areas.count; i++) { | 511 | cpu = 1; |
548 | sa_ext = dump_save_areas.areas[i]; | 512 | list_for_each_entry(sa, &dump_save_areas, list) |
549 | if (sa_ext->sa.pref_reg == 0) | 513 | if (sa->prefix != 0) |
550 | continue; | 514 | ptr = fill_cpu_elf_notes(ptr, cpu++, sa); |
551 | ptr = fill_cpu_elf_notes(ptr, &sa_ext->sa, sa_ext->vx_regs); | ||
552 | } | ||
553 | ptr = nt_vmcoreinfo(ptr); | 515 | ptr = nt_vmcoreinfo(ptr); |
554 | memset(phdr, 0, sizeof(*phdr)); | 516 | memset(phdr, 0, sizeof(*phdr)); |
555 | phdr->p_type = PT_NOTE; | 517 | phdr->p_type = PT_NOTE; |
@@ -573,9 +535,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) | |||
573 | /* If we are not in kdump or zfcpdump mode return */ | 535 | /* If we are not in kdump or zfcpdump mode return */ |
574 | if (!OLDMEM_BASE && ipl_info.type != IPL_TYPE_FCP_DUMP) | 536 | if (!OLDMEM_BASE && ipl_info.type != IPL_TYPE_FCP_DUMP) |
575 | return 0; | 537 | return 0; |
576 | /* If elfcorehdr= has been passed via cmdline, we use that one */ | ||
577 | if (elfcorehdr_addr != ELFCORE_ADDR_MAX) | ||
578 | return 0; | ||
579 | /* If we cannot get HSA size for zfcpdump return error */ | 538 | /* If we cannot get HSA size for zfcpdump return error */ |
580 | if (ipl_info.type == IPL_TYPE_FCP_DUMP && !sclp.hsa_size) | 539 | if (ipl_info.type == IPL_TYPE_FCP_DUMP && !sclp.hsa_size) |
581 | return -ENODEV; | 540 | return -ENODEV; |
@@ -606,7 +565,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) | |||
606 | hdr_off = PTR_DIFF(ptr, hdr); | 565 | hdr_off = PTR_DIFF(ptr, hdr); |
607 | loads_init(phdr_loads, hdr_off); | 566 | loads_init(phdr_loads, hdr_off); |
608 | *addr = (unsigned long long) hdr; | 567 | *addr = (unsigned long long) hdr; |
609 | elfcorehdr_newmem = hdr; | ||
610 | *size = (unsigned long long) hdr_off; | 568 | *size = (unsigned long long) hdr_off; |
611 | BUG_ON(elfcorehdr_size > alloc_size); | 569 | BUG_ON(elfcorehdr_size > alloc_size); |
612 | return 0; | 570 | return 0; |
@@ -617,8 +575,6 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size) | |||
617 | */ | 575 | */ |
618 | void elfcorehdr_free(unsigned long long addr) | 576 | void elfcorehdr_free(unsigned long long addr) |
619 | { | 577 | { |
620 | if (!elfcorehdr_newmem) | ||
621 | return; | ||
622 | kfree((void *)(unsigned long)addr); | 578 | kfree((void *)(unsigned long)addr); |
623 | } | 579 | } |
624 | 580 | ||
@@ -629,7 +585,6 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) | |||
629 | { | 585 | { |
630 | void *src = (void *)(unsigned long)*ppos; | 586 | void *src = (void *)(unsigned long)*ppos; |
631 | 587 | ||
632 | src = elfcorehdr_newmem ? src : src - OLDMEM_BASE; | ||
633 | memcpy(buf, src, count); | 588 | memcpy(buf, src, count); |
634 | *ppos += count; | 589 | *ppos += count; |
635 | return count; | 590 | return count; |
@@ -641,15 +596,8 @@ ssize_t elfcorehdr_read(char *buf, size_t count, u64 *ppos) | |||
641 | ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) | 596 | ssize_t elfcorehdr_read_notes(char *buf, size_t count, u64 *ppos) |
642 | { | 597 | { |
643 | void *src = (void *)(unsigned long)*ppos; | 598 | void *src = (void *)(unsigned long)*ppos; |
644 | int rc; | ||
645 | 599 | ||
646 | if (elfcorehdr_newmem) { | 600 | memcpy(buf, src, count); |
647 | memcpy(buf, src, count); | ||
648 | } else { | ||
649 | rc = copy_from_oldmem(buf, src, count); | ||
650 | if (rc) | ||
651 | return rc; | ||
652 | } | ||
653 | *ppos += count; | 601 | *ppos += count; |
654 | return count; | 602 | return count; |
655 | } | 603 | } |
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c index 6e72961608f0..62973efd214a 100644 --- a/arch/s390/kernel/dis.c +++ b/arch/s390/kernel/dis.c | |||
@@ -2022,7 +2022,7 @@ void show_code(struct pt_regs *regs) | |||
2022 | *ptr++ = '\t'; | 2022 | *ptr++ = '\t'; |
2023 | ptr += print_insn(ptr, code + start, addr); | 2023 | ptr += print_insn(ptr, code + start, addr); |
2024 | start += opsize; | 2024 | start += opsize; |
2025 | printk(buffer); | 2025 | printk("%s", buffer); |
2026 | ptr = buffer; | 2026 | ptr = buffer; |
2027 | ptr += sprintf(ptr, "\n "); | 2027 | ptr += sprintf(ptr, "\n "); |
2028 | hops++; | 2028 | hops++; |
@@ -2049,7 +2049,7 @@ void print_fn_code(unsigned char *code, unsigned long len) | |||
2049 | ptr += print_insn(ptr, code, (unsigned long) code); | 2049 | ptr += print_insn(ptr, code, (unsigned long) code); |
2050 | *ptr++ = '\n'; | 2050 | *ptr++ = '\n'; |
2051 | *ptr++ = 0; | 2051 | *ptr++ = 0; |
2052 | printk(buffer); | 2052 | printk("%s", buffer); |
2053 | code += opsize; | 2053 | code += opsize; |
2054 | len -= opsize; | 2054 | len -= opsize; |
2055 | } | 2055 | } |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 3c31609df959..20a5caf6d981 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -335,6 +335,14 @@ static __init void detect_machine_facilities(void) | |||
335 | } | 335 | } |
336 | } | 336 | } |
337 | 337 | ||
338 | static inline void save_vector_registers(void) | ||
339 | { | ||
340 | #ifdef CONFIG_CRASH_DUMP | ||
341 | if (test_facility(129)) | ||
342 | save_vx_regs(boot_cpu_vector_save_area); | ||
343 | #endif | ||
344 | } | ||
345 | |||
338 | static int __init disable_vector_extension(char *str) | 346 | static int __init disable_vector_extension(char *str) |
339 | { | 347 | { |
340 | S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; | 348 | S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; |
@@ -451,6 +459,7 @@ void __init startup_init(void) | |||
451 | detect_diag9c(); | 459 | detect_diag9c(); |
452 | detect_diag44(); | 460 | detect_diag44(); |
453 | detect_machine_facilities(); | 461 | detect_machine_facilities(); |
462 | save_vector_registers(); | ||
454 | setup_topology(); | 463 | setup_topology(); |
455 | sclp_early_detect(); | 464 | sclp_early_detect(); |
456 | lockdep_on(); | 465 | lockdep_on(); |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 857b6526d298..cd5a191381b9 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -764,6 +764,7 @@ ENTRY(psw_idle) | |||
764 | .insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15) | 764 | .insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15) |
765 | .Lpsw_idle_stcctm: | 765 | .Lpsw_idle_stcctm: |
766 | #endif | 766 | #endif |
767 | oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT | ||
767 | STCK __CLOCK_IDLE_ENTER(%r2) | 768 | STCK __CLOCK_IDLE_ENTER(%r2) |
768 | stpt __TIMER_IDLE_ENTER(%r2) | 769 | stpt __TIMER_IDLE_ENTER(%r2) |
769 | .Lpsw_idle_lpsw: | 770 | .Lpsw_idle_lpsw: |
@@ -1146,6 +1147,7 @@ cleanup_critical: | |||
1146 | .quad .Lio_done - 4 | 1147 | .quad .Lio_done - 4 |
1147 | 1148 | ||
1148 | .Lcleanup_idle: | 1149 | .Lcleanup_idle: |
1150 | ni __LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT | ||
1149 | # copy interrupt clock & cpu timer | 1151 | # copy interrupt clock & cpu timer |
1150 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK | 1152 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK |
1151 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER | 1153 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER |
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S index 301ee9c70688..fcaefb041364 100644 --- a/arch/s390/kernel/head.S +++ b/arch/s390/kernel/head.S | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/linkage.h> | 25 | #include <linux/linkage.h> |
26 | #include <asm/asm-offsets.h> | 26 | #include <asm/asm-offsets.h> |
27 | #include <asm/thread_info.h> | 27 | #include <asm/thread_info.h> |
28 | #include <asm/facility.h> | ||
28 | #include <asm/page.h> | 29 | #include <asm/page.h> |
29 | #include <asm/ptrace.h> | 30 | #include <asm/ptrace.h> |
30 | 31 | ||
@@ -300,27 +301,27 @@ ENTRY(startup_kdump) | |||
300 | xc 0x200(256),0x200 # partially clear lowcore | 301 | xc 0x200(256),0x200 # partially clear lowcore |
301 | xc 0x300(256),0x300 | 302 | xc 0x300(256),0x300 |
302 | xc 0xe00(256),0xe00 | 303 | xc 0xe00(256),0xe00 |
304 | xc 0xf00(256),0xf00 | ||
303 | lctlg %c0,%c15,0x200(%r0) # initialize control registers | 305 | lctlg %c0,%c15,0x200(%r0) # initialize control registers |
304 | stck __LC_LAST_UPDATE_CLOCK | 306 | stck __LC_LAST_UPDATE_CLOCK |
305 | spt 6f-.LPG0(%r13) | 307 | spt 6f-.LPG0(%r13) |
306 | mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) | 308 | mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) |
307 | xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST | 309 | stfl 0(%r0) # store facilities @ __LC_STFL_FAC_LIST |
308 | # check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} | 310 | mvc __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST |
309 | .insn s,0xb2b10000,0 # store facilities @ __LC_STFL_FAC_LIST | 311 | tm __LC_STFLE_FAC_LIST,0x01 # stfle available ? |
310 | tm __LC_STFL_FAC_LIST,0x01 # stfle available ? | ||
311 | jz 0f | 312 | jz 0f |
312 | la %r0,1 | 313 | lghi %r0,FACILITIES_ALS_DWORDS-1 |
313 | .insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended | 314 | .insn s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended |
314 | # verify if all required facilities are supported by the machine | 315 | # verify if all required facilities are supported by the machine |
315 | 0: la %r1,__LC_STFL_FAC_LIST | 316 | 0: la %r1,__LC_STFLE_FAC_LIST |
316 | la %r2,3f+8-.LPG0(%r13) | 317 | la %r2,3f+8-.LPG0(%r13) |
317 | l %r3,0(%r2) | 318 | lhi %r3,FACILITIES_ALS_DWORDS |
318 | 1: l %r0,0(%r1) | 319 | 1: lg %r0,0(%r1) |
319 | n %r0,4(%r2) | 320 | ng %r0,0(%r2) |
320 | cl %r0,4(%r2) | 321 | clg %r0,0(%r2) |
321 | jne 2f | 322 | jne 2f |
322 | la %r1,4(%r1) | 323 | la %r1,8(%r1) |
323 | la %r2,4(%r2) | 324 | la %r2,8(%r2) |
324 | ahi %r3,-1 | 325 | ahi %r3,-1 |
325 | jnz 1b | 326 | jnz 1b |
326 | j 4f | 327 | j 4f |
@@ -340,24 +341,10 @@ ENTRY(startup_kdump) | |||
340 | 3: .long 0x000a0000,0x8badcccc | 341 | 3: .long 0x000a0000,0x8badcccc |
341 | 342 | ||
342 | # List of facilities that are required. If not all facilities are present | 343 | # List of facilities that are required. If not all facilities are present |
343 | # the kernel will crash. Format is number of facility words with bits set, | 344 | # the kernel will crash. |
344 | # followed by the facility words. | 345 | |
346 | .quad FACILITIES_ALS | ||
345 | 347 | ||
346 | #if defined(CONFIG_MARCH_Z13) | ||
347 | .long 2, 0xc100eff2, 0xf46cc800 | ||
348 | #elif defined(CONFIG_MARCH_ZEC12) | ||
349 | .long 2, 0xc100eff2, 0xf46cc800 | ||
350 | #elif defined(CONFIG_MARCH_Z196) | ||
351 | .long 2, 0xc100eff2, 0xf46c0000 | ||
352 | #elif defined(CONFIG_MARCH_Z10) | ||
353 | .long 2, 0xc100eff2, 0xf0680000 | ||
354 | #elif defined(CONFIG_MARCH_Z9_109) | ||
355 | .long 1, 0xc100efc2 | ||
356 | #elif defined(CONFIG_MARCH_Z990) | ||
357 | .long 1, 0xc0002000 | ||
358 | #elif defined(CONFIG_MARCH_Z900) | ||
359 | .long 1, 0xc0000000 | ||
360 | #endif | ||
361 | 4: | 348 | 4: |
362 | /* Continue with startup code in head64.S */ | 349 | /* Continue with startup code in head64.S */ |
363 | jg startup_continue | 350 | jg startup_continue |
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 58b719fa8067..c5febe84eba6 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S | |||
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | __HEAD | 17 | __HEAD |
18 | ENTRY(startup_continue) | 18 | ENTRY(startup_continue) |
19 | tm __LC_STFL_FAC_LIST+6,0x80 # LPP available ? | 19 | tm __LC_STFLE_FAC_LIST+6,0x80 # LPP available ? |
20 | jz 0f | 20 | jz 0f |
21 | xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid | 21 | xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid |
22 | mvi __LC_LPP,0x80 # and set LPP_MAGIC | 22 | mvi __LC_LPP,0x80 # and set LPP_MAGIC |
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index b1f0a90f933b..0a5a6b661b93 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -2039,21 +2039,15 @@ static void do_reset_calls(void) | |||
2039 | reset->fn(); | 2039 | reset->fn(); |
2040 | } | 2040 | } |
2041 | 2041 | ||
2042 | u32 dump_prefix_page; | 2042 | void s390_reset_system(void) |
2043 | |||
2044 | void s390_reset_system(void (*fn_pre)(void), | ||
2045 | void (*fn_post)(void *), void *data) | ||
2046 | { | 2043 | { |
2047 | struct _lowcore *lc; | 2044 | struct lowcore *lc; |
2048 | 2045 | ||
2049 | lc = (struct _lowcore *)(unsigned long) store_prefix(); | 2046 | lc = (struct lowcore *)(unsigned long) store_prefix(); |
2050 | 2047 | ||
2051 | /* Stack for interrupt/machine check handler */ | 2048 | /* Stack for interrupt/machine check handler */ |
2052 | lc->panic_stack = S390_lowcore.panic_stack; | 2049 | lc->panic_stack = S390_lowcore.panic_stack; |
2053 | 2050 | ||
2054 | /* Save prefix page address for dump case */ | ||
2055 | dump_prefix_page = (u32)(unsigned long) lc; | ||
2056 | |||
2057 | /* Disable prefixing */ | 2051 | /* Disable prefixing */ |
2058 | set_prefix(0); | 2052 | set_prefix(0); |
2059 | 2053 | ||
@@ -2077,14 +2071,5 @@ void s390_reset_system(void (*fn_pre)(void), | |||
2077 | S390_lowcore.subchannel_id = 0; | 2071 | S390_lowcore.subchannel_id = 0; |
2078 | S390_lowcore.subchannel_nr = 0; | 2072 | S390_lowcore.subchannel_nr = 0; |
2079 | 2073 | ||
2080 | /* Store status at absolute zero */ | ||
2081 | store_status(); | ||
2082 | |||
2083 | /* Call function before reset */ | ||
2084 | if (fn_pre) | ||
2085 | fn_pre(); | ||
2086 | do_reset_calls(); | 2074 | do_reset_calls(); |
2087 | /* Call function after reset */ | ||
2088 | if (fn_post) | ||
2089 | fn_post(data); | ||
2090 | } | 2075 | } |
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c index fb0901ec4306..2f1b7217c25c 100644 --- a/arch/s390/kernel/machine_kexec.c +++ b/arch/s390/kernel/machine_kexec.c | |||
@@ -35,46 +35,6 @@ extern const unsigned long long relocate_kernel_len; | |||
35 | #ifdef CONFIG_CRASH_DUMP | 35 | #ifdef CONFIG_CRASH_DUMP |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Create ELF notes for one CPU | ||
39 | */ | ||
40 | static void add_elf_notes(int cpu) | ||
41 | { | ||
42 | struct save_area *sa = (void *) 4608 + store_prefix(); | ||
43 | void *ptr; | ||
44 | |||
45 | memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa)); | ||
46 | ptr = (u64 *) per_cpu_ptr(crash_notes, cpu); | ||
47 | ptr = fill_cpu_elf_notes(ptr, sa, NULL); | ||
48 | memset(ptr, 0, sizeof(struct elf_note)); | ||
49 | } | ||
50 | |||
51 | /* | ||
52 | * Initialize CPU ELF notes | ||
53 | */ | ||
54 | static void setup_regs(void) | ||
55 | { | ||
56 | unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE; | ||
57 | struct _lowcore *lc; | ||
58 | int cpu, this_cpu; | ||
59 | |||
60 | /* Get lowcore pointer from store status of this CPU (absolute zero) */ | ||
61 | lc = (struct _lowcore *)(unsigned long)S390_lowcore.prefixreg_save_area; | ||
62 | this_cpu = smp_find_processor_id(stap()); | ||
63 | add_elf_notes(this_cpu); | ||
64 | for_each_online_cpu(cpu) { | ||
65 | if (cpu == this_cpu) | ||
66 | continue; | ||
67 | if (smp_store_status(cpu)) | ||
68 | continue; | ||
69 | add_elf_notes(cpu); | ||
70 | } | ||
71 | if (MACHINE_HAS_VX) | ||
72 | save_vx_regs_safe((void *) lc->vector_save_area_addr); | ||
73 | /* Copy dump CPU store status info to absolute zero */ | ||
74 | memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area)); | ||
75 | } | ||
76 | |||
77 | /* | ||
78 | * PM notifier callback for kdump | 38 | * PM notifier callback for kdump |
79 | */ | 39 | */ |
80 | static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, | 40 | static int machine_kdump_pm_cb(struct notifier_block *nb, unsigned long action, |
@@ -105,14 +65,66 @@ static int __init machine_kdump_pm_init(void) | |||
105 | arch_initcall(machine_kdump_pm_init); | 65 | arch_initcall(machine_kdump_pm_init); |
106 | 66 | ||
107 | /* | 67 | /* |
108 | * Start kdump: We expect here that a store status has been done on our CPU | 68 | * Reset the system, copy boot CPU registers to absolute zero, |
69 | * and jump to the kdump image | ||
109 | */ | 70 | */ |
110 | static void __do_machine_kdump(void *image) | 71 | static void __do_machine_kdump(void *image) |
111 | { | 72 | { |
112 | int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; | 73 | int (*start_kdump)(int); |
74 | unsigned long prefix; | ||
75 | |||
76 | /* store_status() saved the prefix register to lowcore */ | ||
77 | prefix = (unsigned long) S390_lowcore.prefixreg_save_area; | ||
78 | |||
79 | /* Now do the reset */ | ||
80 | s390_reset_system(); | ||
81 | |||
82 | /* | ||
83 | * Copy dump CPU store status info to absolute zero. | ||
84 | * This need to be done *after* s390_reset_system set the | ||
85 | * prefix register of this CPU to zero | ||
86 | */ | ||
87 | memcpy((void *) __LC_FPREGS_SAVE_AREA, | ||
88 | (void *)(prefix + __LC_FPREGS_SAVE_AREA), 512); | ||
113 | 89 | ||
114 | __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); | 90 | __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); |
91 | start_kdump = (void *)((struct kimage *) image)->start; | ||
115 | start_kdump(1); | 92 | start_kdump(1); |
93 | |||
94 | /* Die if start_kdump returns */ | ||
95 | disabled_wait((unsigned long) __builtin_return_address(0)); | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * Start kdump: create a LGR log entry, store status of all CPUs and | ||
100 | * branch to __do_machine_kdump. | ||
101 | */ | ||
102 | static noinline void __machine_kdump(void *image) | ||
103 | { | ||
104 | int this_cpu, cpu; | ||
105 | |||
106 | lgr_info_log(); | ||
107 | /* Get status of the other CPUs */ | ||
108 | this_cpu = smp_find_processor_id(stap()); | ||
109 | for_each_online_cpu(cpu) { | ||
110 | if (cpu == this_cpu) | ||
111 | continue; | ||
112 | if (smp_store_status(cpu)) | ||
113 | continue; | ||
114 | } | ||
115 | /* Store status of the boot CPU */ | ||
116 | if (MACHINE_HAS_VX) | ||
117 | save_vx_regs((void *) &S390_lowcore.vector_save_area); | ||
118 | /* | ||
119 | * To create a good backchain for this CPU in the dump store_status | ||
120 | * is passed the address of a function. The address is saved into | ||
121 | * the PSW save area of the boot CPU and the function is invoked as | ||
122 | * a tail call of store_status. The backchain in the dump will look | ||
123 | * like this: | ||
124 | * restart_int_handler -> __machine_kexec -> __do_machine_kdump | ||
125 | * The call to store_status() will not return. | ||
126 | */ | ||
127 | store_status(__do_machine_kdump, image); | ||
116 | } | 128 | } |
117 | #endif | 129 | #endif |
118 | 130 | ||
@@ -235,10 +247,14 @@ static void __do_machine_kexec(void *data) | |||
235 | relocate_kernel_t data_mover; | 247 | relocate_kernel_t data_mover; |
236 | struct kimage *image = data; | 248 | struct kimage *image = data; |
237 | 249 | ||
250 | s390_reset_system(); | ||
238 | data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); | 251 | data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); |
239 | 252 | ||
240 | /* Call the moving routine */ | 253 | /* Call the moving routine */ |
241 | (*data_mover)(&image->head, image->start); | 254 | (*data_mover)(&image->head, image->start); |
255 | |||
256 | /* Die if kexec returns */ | ||
257 | disabled_wait((unsigned long) __builtin_return_address(0)); | ||
242 | } | 258 | } |
243 | 259 | ||
244 | /* | 260 | /* |
@@ -251,14 +267,10 @@ static void __machine_kexec(void *data) | |||
251 | tracing_off(); | 267 | tracing_off(); |
252 | debug_locks_off(); | 268 | debug_locks_off(); |
253 | #ifdef CONFIG_CRASH_DUMP | 269 | #ifdef CONFIG_CRASH_DUMP |
254 | if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) { | 270 | if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) |
255 | 271 | __machine_kdump(data); | |
256 | lgr_info_log(); | ||
257 | s390_reset_system(setup_regs, __do_machine_kdump, data); | ||
258 | } else | ||
259 | #endif | 272 | #endif |
260 | s390_reset_system(NULL, __do_machine_kexec, data); | 273 | __do_machine_kexec(data); |
261 | disabled_wait((unsigned long) __builtin_return_address(0)); | ||
262 | } | 274 | } |
263 | 275 | ||
264 | /* | 276 | /* |
diff --git a/arch/s390/kernel/os_info.c b/arch/s390/kernel/os_info.c index d112fc66f993..87f05e475ae8 100644 --- a/arch/s390/kernel/os_info.c +++ b/arch/s390/kernel/os_info.c | |||
@@ -89,7 +89,7 @@ static void os_info_old_alloc(int nr, int align) | |||
89 | goto fail; | 89 | goto fail; |
90 | } | 90 | } |
91 | buf_align = PTR_ALIGN(buf, align); | 91 | buf_align = PTR_ALIGN(buf, align); |
92 | if (copy_from_oldmem(buf_align, (void *) addr, size)) { | 92 | if (copy_oldmem_kernel(buf_align, (void *) addr, size)) { |
93 | msg = "copy failed"; | 93 | msg = "copy failed"; |
94 | goto fail_free; | 94 | goto fail_free; |
95 | } | 95 | } |
@@ -122,14 +122,15 @@ static void os_info_old_init(void) | |||
122 | return; | 122 | return; |
123 | if (!OLDMEM_BASE) | 123 | if (!OLDMEM_BASE) |
124 | goto fail; | 124 | goto fail; |
125 | if (copy_from_oldmem(&addr, &S390_lowcore.os_info, sizeof(addr))) | 125 | if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr))) |
126 | goto fail; | 126 | goto fail; |
127 | if (addr == 0 || addr % PAGE_SIZE) | 127 | if (addr == 0 || addr % PAGE_SIZE) |
128 | goto fail; | 128 | goto fail; |
129 | os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL); | 129 | os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL); |
130 | if (!os_info_old) | 130 | if (!os_info_old) |
131 | goto fail; | 131 | goto fail; |
132 | if (copy_from_oldmem(os_info_old, (void *) addr, sizeof(*os_info_old))) | 132 | if (copy_oldmem_kernel(os_info_old, (void *) addr, |
133 | sizeof(*os_info_old))) | ||
133 | goto fail_free; | 134 | goto fail_free; |
134 | if (os_info_old->magic != OS_INFO_MAGIC) | 135 | if (os_info_old->magic != OS_INFO_MAGIC) |
135 | goto fail_free; | 136 | goto fail_free; |
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S index 52aab0bd84f8..89ea8c213d82 100644 --- a/arch/s390/kernel/reipl.S +++ b/arch/s390/kernel/reipl.S | |||
@@ -9,60 +9,66 @@ | |||
9 | #include <asm/sigp.h> | 9 | #include <asm/sigp.h> |
10 | 10 | ||
11 | # | 11 | # |
12 | # store_status | 12 | # Issue "store status" for the current CPU to its prefix page |
13 | # and call passed function afterwards | ||
13 | # | 14 | # |
14 | # Prerequisites to run this function: | 15 | # r2 = Function to be called after store status |
15 | # - Prefix register is set to zero | 16 | # r3 = Parameter for function |
16 | # - Original prefix register is stored in "dump_prefix_page" | ||
17 | # - Lowcore protection is off | ||
18 | # | 17 | # |
19 | ENTRY(store_status) | 18 | ENTRY(store_status) |
20 | /* Save register one and load save area base */ | 19 | /* Save register one and load save area base */ |
21 | stg %r1,__LC_SAVE_AREA_RESTART | 20 | stg %r1,__LC_SAVE_AREA_RESTART |
22 | lghi %r1,SAVE_AREA_BASE | ||
23 | /* General purpose registers */ | 21 | /* General purpose registers */ |
24 | stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 22 | lghi %r1,__LC_GPREGS_SAVE_AREA |
25 | lg %r2,__LC_SAVE_AREA_RESTART | 23 | stmg %r0,%r15,0(%r1) |
26 | stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) | 24 | mvc 8(8,%r1),__LC_SAVE_AREA_RESTART |
27 | /* Control registers */ | 25 | /* Control registers */ |
28 | stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 26 | lghi %r1,__LC_CREGS_SAVE_AREA |
27 | stctg %c0,%c15,0(%r1) | ||
29 | /* Access registers */ | 28 | /* Access registers */ |
30 | stam %a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 29 | lghi %r1,__LC_AREGS_SAVE_AREA |
30 | stam %a0,%a15,0(%r1) | ||
31 | /* Floating point registers */ | 31 | /* Floating point registers */ |
32 | std %f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 32 | lghi %r1,__LC_FPREGS_SAVE_AREA |
33 | std %f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 33 | std %f0, 0x00(%r1) |
34 | std %f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 34 | std %f1, 0x08(%r1) |
35 | std %f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 35 | std %f2, 0x10(%r1) |
36 | std %f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 36 | std %f3, 0x18(%r1) |
37 | std %f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 37 | std %f4, 0x20(%r1) |
38 | std %f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 38 | std %f5, 0x28(%r1) |
39 | std %f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 39 | std %f6, 0x30(%r1) |
40 | std %f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 40 | std %f7, 0x38(%r1) |
41 | std %f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 41 | std %f8, 0x40(%r1) |
42 | std %f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 42 | std %f9, 0x48(%r1) |
43 | std %f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 43 | std %f10,0x50(%r1) |
44 | std %f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 44 | std %f11,0x58(%r1) |
45 | std %f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 45 | std %f12,0x60(%r1) |
46 | std %f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 46 | std %f13,0x68(%r1) |
47 | std %f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) | 47 | std %f14,0x70(%r1) |
48 | std %f15,0x78(%r1) | ||
48 | /* Floating point control register */ | 49 | /* Floating point control register */ |
49 | stfpc __LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1) | 50 | lghi %r1,__LC_FP_CREG_SAVE_AREA |
51 | stfpc 0(%r1) | ||
50 | /* CPU timer */ | 52 | /* CPU timer */ |
51 | stpt __LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1) | 53 | lghi %r1,__LC_CPU_TIMER_SAVE_AREA |
52 | /* Saved prefix register */ | 54 | stpt 0(%r1) |
53 | larl %r2,dump_prefix_page | 55 | /* Store prefix register */ |
54 | mvc __LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2) | 56 | lghi %r1,__LC_PREFIX_SAVE_AREA |
57 | stpx 0(%r1) | ||
55 | /* Clock comparator - seven bytes */ | 58 | /* Clock comparator - seven bytes */ |
56 | larl %r2,.Lclkcmp | 59 | lghi %r1,__LC_CLOCK_COMP_SAVE_AREA |
57 | stckc 0(%r2) | 60 | larl %r4,.Lclkcmp |
58 | mvc __LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2) | 61 | stckc 0(%r4) |
62 | mvc 1(7,%r1),1(%r4) | ||
59 | /* Program status word */ | 63 | /* Program status word */ |
60 | epsw %r2,%r3 | 64 | lghi %r1,__LC_PSW_SAVE_AREA |
61 | st %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1) | 65 | epsw %r4,%r5 |
62 | st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1) | 66 | st %r4,0(%r1) |
63 | larl %r2,store_status | 67 | st %r5,4(%r1) |
64 | stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1) | 68 | stg %r2,8(%r1) |
65 | br %r14 | 69 | lgr %r1,%r2 |
70 | lgr %r2,%r3 | ||
71 | br %r1 | ||
66 | 72 | ||
67 | .section .bss | 73 | .section .bss |
68 | .align 8 | 74 | .align 8 |
@@ -77,9 +83,11 @@ ENTRY(store_status) | |||
77 | ENTRY(do_reipl_asm) | 83 | ENTRY(do_reipl_asm) |
78 | basr %r13,0 | 84 | basr %r13,0 |
79 | .Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) | 85 | .Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) |
80 | .Lpg1: brasl %r14,store_status | 86 | .Lpg1: lgr %r3,%r2 |
87 | larl %r2,.Lstatus | ||
88 | brasl %r14,store_status | ||
81 | 89 | ||
82 | lctlg %c6,%c6,.Lall-.Lpg0(%r13) | 90 | .Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13) |
83 | lgr %r1,%r2 | 91 | lgr %r1,%r2 |
84 | mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) | 92 | mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) |
85 | stsch .Lschib-.Lpg0(%r13) | 93 | stsch .Lschib-.Lpg0(%r13) |
diff --git a/arch/s390/kernel/sclp.c b/arch/s390/kernel/sclp.c index 9fe7781a45cd..d88db40bdf15 100644 --- a/arch/s390/kernel/sclp.c +++ b/arch/s390/kernel/sclp.c | |||
@@ -9,7 +9,11 @@ | |||
9 | #include <asm/processor.h> | 9 | #include <asm/processor.h> |
10 | #include <asm/sclp.h> | 10 | #include <asm/sclp.h> |
11 | 11 | ||
12 | #define EVTYP_VT220MSG_MASK 0x00000040 | ||
13 | #define EVTYP_MSG_MASK 0x40000000 | ||
14 | |||
12 | static char _sclp_work_area[4096] __aligned(PAGE_SIZE); | 15 | static char _sclp_work_area[4096] __aligned(PAGE_SIZE); |
16 | static bool have_vt220, have_linemode; | ||
13 | 17 | ||
14 | static void _sclp_wait_int(void) | 18 | static void _sclp_wait_int(void) |
15 | { | 19 | { |
@@ -68,7 +72,7 @@ static int _sclp_setup(int disable) | |||
68 | 0x00, 0x1c, | 72 | 0x00, 0x1c, |
69 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 73 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
70 | 0x00, 0x04, | 74 | 0x00, 0x04, |
71 | 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, | 75 | 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, |
72 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 | 76 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 |
73 | }; | 77 | }; |
74 | unsigned int *masks; | 78 | unsigned int *masks; |
@@ -82,13 +86,13 @@ static int _sclp_setup(int disable) | |||
82 | rc = _sclp_servc(0x00780005, _sclp_work_area); | 86 | rc = _sclp_servc(0x00780005, _sclp_work_area); |
83 | if (rc) | 87 | if (rc) |
84 | return rc; | 88 | return rc; |
85 | if ((masks[0] & masks[3]) != masks[0] || | 89 | have_vt220 = masks[2] & EVTYP_VT220MSG_MASK; |
86 | (masks[1] & masks[2]) != masks[1]) | 90 | have_linemode = masks[2] & EVTYP_MSG_MASK; |
87 | return -EIO; | ||
88 | return 0; | 91 | return 0; |
89 | } | 92 | } |
90 | 93 | ||
91 | static int _sclp_print(const char *str) | 94 | /* Output multi-line text using SCLP Message interface. */ |
95 | static void _sclp_print_lm(const char *str) | ||
92 | { | 96 | { |
93 | static unsigned char write_head[] = { | 97 | static unsigned char write_head[] = { |
94 | /* sccb header */ | 98 | /* sccb header */ |
@@ -143,18 +147,49 @@ static int _sclp_print(const char *str) | |||
143 | } while (ch != 0); | 147 | } while (ch != 0); |
144 | 148 | ||
145 | /* SCLP write data */ | 149 | /* SCLP write data */ |
146 | return _sclp_servc(0x00760005, _sclp_work_area); | 150 | _sclp_servc(0x00760005, _sclp_work_area); |
147 | } | 151 | } |
148 | 152 | ||
149 | int _sclp_print_early(const char *str) | 153 | /* Output multi-line text (plus a newline) using SCLP VT220 |
154 | * interface. | ||
155 | */ | ||
156 | static void _sclp_print_vt220(const char *str) | ||
150 | { | 157 | { |
151 | int rc; | 158 | static unsigned char const write_head[] = { |
159 | /* sccb header */ | ||
160 | 0x00, 0x0e, | ||
161 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
162 | /* evbuf header */ | ||
163 | 0x00, 0x06, | ||
164 | 0x1a, 0x00, 0x00, 0x00, | ||
165 | }; | ||
166 | size_t len = strlen(str); | ||
152 | 167 | ||
153 | rc = _sclp_setup(0); | 168 | if (sizeof(write_head) + len >= sizeof(_sclp_work_area)) |
154 | if (rc) | 169 | len = sizeof(_sclp_work_area) - sizeof(write_head) - 1; |
155 | return rc; | 170 | |
156 | rc = _sclp_print(str); | 171 | memcpy(_sclp_work_area, write_head, sizeof(write_head)); |
157 | if (rc) | 172 | memcpy(_sclp_work_area + sizeof(write_head), str, len); |
158 | return rc; | 173 | _sclp_work_area[sizeof(write_head) + len] = '\n'; |
159 | return _sclp_setup(1); | 174 | |
175 | /* Update length fields in evbuf and sccb headers */ | ||
176 | *(unsigned short *)(_sclp_work_area + 8) += len + 1; | ||
177 | *(unsigned short *)(_sclp_work_area + 0) += len + 1; | ||
178 | |||
179 | /* SCLP write data */ | ||
180 | (void)_sclp_servc(0x00760005, _sclp_work_area); | ||
181 | } | ||
182 | |||
183 | /* Output one or more lines of text on the SCLP console (VT220 and / | ||
184 | * or line-mode). All lines get terminated; no need for a trailing LF. | ||
185 | */ | ||
186 | void _sclp_print_early(const char *str) | ||
187 | { | ||
188 | if (_sclp_setup(0) != 0) | ||
189 | return; | ||
190 | if (have_linemode) | ||
191 | _sclp_print_lm(str); | ||
192 | if (have_vt220) | ||
193 | _sclp_print_vt220(str); | ||
194 | _sclp_setup(1); | ||
160 | } | 195 | } |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index dc83ae66a730..c6878fbbcf13 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -99,7 +99,7 @@ unsigned long MODULES_VADDR; | |||
99 | unsigned long MODULES_END; | 99 | unsigned long MODULES_END; |
100 | 100 | ||
101 | /* An array with a pointer to the lowcore of every CPU. */ | 101 | /* An array with a pointer to the lowcore of every CPU. */ |
102 | struct _lowcore *lowcore_ptr[NR_CPUS]; | 102 | struct lowcore *lowcore_ptr[NR_CPUS]; |
103 | EXPORT_SYMBOL(lowcore_ptr); | 103 | EXPORT_SYMBOL(lowcore_ptr); |
104 | 104 | ||
105 | /* | 105 | /* |
@@ -293,12 +293,12 @@ void *restart_stack __attribute__((__section__(".data"))); | |||
293 | 293 | ||
294 | static void __init setup_lowcore(void) | 294 | static void __init setup_lowcore(void) |
295 | { | 295 | { |
296 | struct _lowcore *lc; | 296 | struct lowcore *lc; |
297 | 297 | ||
298 | /* | 298 | /* |
299 | * Setup lowcore for boot cpu | 299 | * Setup lowcore for boot cpu |
300 | */ | 300 | */ |
301 | BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096); | 301 | BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096); |
302 | lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); | 302 | lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); |
303 | lc->restart_psw.mask = PSW_KERNEL_BITS; | 303 | lc->restart_psw.mask = PSW_KERNEL_BITS; |
304 | lc->restart_psw.addr = | 304 | lc->restart_psw.addr = |
@@ -663,15 +663,6 @@ static void __init reserve_kernel(void) | |||
663 | #endif | 663 | #endif |
664 | } | 664 | } |
665 | 665 | ||
666 | static void __init reserve_elfcorehdr(void) | ||
667 | { | ||
668 | #ifdef CONFIG_CRASH_DUMP | ||
669 | if (is_kdump_kernel()) | ||
670 | memblock_reserve(elfcorehdr_addr - OLDMEM_BASE, | ||
671 | PAGE_ALIGN(elfcorehdr_size)); | ||
672 | #endif | ||
673 | } | ||
674 | |||
675 | static void __init setup_memory(void) | 666 | static void __init setup_memory(void) |
676 | { | 667 | { |
677 | struct memblock_region *reg; | 668 | struct memblock_region *reg; |
@@ -850,6 +841,11 @@ void __init setup_arch(char **cmdline_p) | |||
850 | init_mm.brk = (unsigned long) &_end; | 841 | init_mm.brk = (unsigned long) &_end; |
851 | 842 | ||
852 | parse_early_param(); | 843 | parse_early_param(); |
844 | #ifdef CONFIG_CRASH_DUMP | ||
845 | /* Deactivate elfcorehdr= kernel parameter */ | ||
846 | elfcorehdr_addr = ELFCORE_ADDR_MAX; | ||
847 | #endif | ||
848 | |||
853 | os_info_init(); | 849 | os_info_init(); |
854 | setup_ipl(); | 850 | setup_ipl(); |
855 | 851 | ||
@@ -858,7 +854,6 @@ void __init setup_arch(char **cmdline_p) | |||
858 | reserve_oldmem(); | 854 | reserve_oldmem(); |
859 | reserve_kernel(); | 855 | reserve_kernel(); |
860 | reserve_initrd(); | 856 | reserve_initrd(); |
861 | reserve_elfcorehdr(); | ||
862 | memblock_allow_resize(); | 857 | memblock_allow_resize(); |
863 | 858 | ||
864 | /* Get information about *all* installed memory */ | 859 | /* Get information about *all* installed memory */ |
@@ -879,11 +874,13 @@ void __init setup_arch(char **cmdline_p) | |||
879 | 874 | ||
880 | check_initrd(); | 875 | check_initrd(); |
881 | reserve_crashkernel(); | 876 | reserve_crashkernel(); |
877 | #ifdef CONFIG_CRASH_DUMP | ||
882 | /* | 878 | /* |
883 | * Be aware that smp_save_dump_cpus() triggers a system reset. | 879 | * Be aware that smp_save_dump_cpus() triggers a system reset. |
884 | * Therefore CPU and device initialization should be done afterwards. | 880 | * Therefore CPU and device initialization should be done afterwards. |
885 | */ | 881 | */ |
886 | smp_save_dump_cpus(); | 882 | smp_save_dump_cpus(); |
883 | #endif | ||
887 | 884 | ||
888 | setup_resources(); | 885 | setup_resources(); |
889 | setup_vmcoreinfo(); | 886 | setup_vmcoreinfo(); |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 9062df575afe..a13468b9a913 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -64,8 +64,9 @@ enum { | |||
64 | static DEFINE_PER_CPU(struct cpu *, cpu_device); | 64 | static DEFINE_PER_CPU(struct cpu *, cpu_device); |
65 | 65 | ||
66 | struct pcpu { | 66 | struct pcpu { |
67 | struct _lowcore *lowcore; /* lowcore page(s) for the cpu */ | 67 | struct lowcore *lowcore; /* lowcore page(s) for the cpu */ |
68 | unsigned long ec_mask; /* bit mask for ec_xxx functions */ | 68 | unsigned long ec_mask; /* bit mask for ec_xxx functions */ |
69 | unsigned long ec_clk; /* sigp timestamp for ec_xxx */ | ||
69 | signed char state; /* physical cpu state */ | 70 | signed char state; /* physical cpu state */ |
70 | signed char polarization; /* physical polarization */ | 71 | signed char polarization; /* physical polarization */ |
71 | u16 address; /* physical cpu address */ | 72 | u16 address; /* physical cpu address */ |
@@ -80,6 +81,10 @@ EXPORT_SYMBOL(smp_cpu_mt_shift); | |||
80 | unsigned int smp_cpu_mtid; | 81 | unsigned int smp_cpu_mtid; |
81 | EXPORT_SYMBOL(smp_cpu_mtid); | 82 | EXPORT_SYMBOL(smp_cpu_mtid); |
82 | 83 | ||
84 | #ifdef CONFIG_CRASH_DUMP | ||
85 | __vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS]; | ||
86 | #endif | ||
87 | |||
83 | static unsigned int smp_max_threads __initdata = -1U; | 88 | static unsigned int smp_max_threads __initdata = -1U; |
84 | 89 | ||
85 | static int __init early_nosmt(char *s) | 90 | static int __init early_nosmt(char *s) |
@@ -105,8 +110,7 @@ DEFINE_MUTEX(smp_cpu_state_mutex); | |||
105 | /* | 110 | /* |
106 | * Signal processor helper functions. | 111 | * Signal processor helper functions. |
107 | */ | 112 | */ |
108 | static inline int __pcpu_sigp_relax(u16 addr, u8 order, unsigned long parm, | 113 | static inline int __pcpu_sigp_relax(u16 addr, u8 order, unsigned long parm) |
109 | u32 *status) | ||
110 | { | 114 | { |
111 | int cc; | 115 | int cc; |
112 | 116 | ||
@@ -171,6 +175,7 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit) | |||
171 | if (test_and_set_bit(ec_bit, &pcpu->ec_mask)) | 175 | if (test_and_set_bit(ec_bit, &pcpu->ec_mask)) |
172 | return; | 176 | return; |
173 | order = pcpu_running(pcpu) ? SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL; | 177 | order = pcpu_running(pcpu) ? SIGP_EXTERNAL_CALL : SIGP_EMERGENCY_SIGNAL; |
178 | pcpu->ec_clk = get_tod_clock_fast(); | ||
174 | pcpu_sigp_retry(pcpu, order, 0); | 179 | pcpu_sigp_retry(pcpu, order, 0); |
175 | } | 180 | } |
176 | 181 | ||
@@ -180,10 +185,10 @@ static void pcpu_ec_call(struct pcpu *pcpu, int ec_bit) | |||
180 | static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) | 185 | static int pcpu_alloc_lowcore(struct pcpu *pcpu, int cpu) |
181 | { | 186 | { |
182 | unsigned long async_stack, panic_stack; | 187 | unsigned long async_stack, panic_stack; |
183 | struct _lowcore *lc; | 188 | struct lowcore *lc; |
184 | 189 | ||
185 | if (pcpu != &pcpu_devices[0]) { | 190 | if (pcpu != &pcpu_devices[0]) { |
186 | pcpu->lowcore = (struct _lowcore *) | 191 | pcpu->lowcore = (struct lowcore *) |
187 | __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER); | 192 | __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER); |
188 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); | 193 | async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); |
189 | panic_stack = __get_free_page(GFP_KERNEL); | 194 | panic_stack = __get_free_page(GFP_KERNEL); |
@@ -235,7 +240,7 @@ static void pcpu_free_lowcore(struct pcpu *pcpu) | |||
235 | 240 | ||
236 | static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) | 241 | static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) |
237 | { | 242 | { |
238 | struct _lowcore *lc = pcpu->lowcore; | 243 | struct lowcore *lc = pcpu->lowcore; |
239 | 244 | ||
240 | if (MACHINE_HAS_TLB_LC) | 245 | if (MACHINE_HAS_TLB_LC) |
241 | cpumask_set_cpu(cpu, &init_mm.context.cpu_attach_mask); | 246 | cpumask_set_cpu(cpu, &init_mm.context.cpu_attach_mask); |
@@ -255,7 +260,7 @@ static void pcpu_prepare_secondary(struct pcpu *pcpu, int cpu) | |||
255 | 260 | ||
256 | static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) | 261 | static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) |
257 | { | 262 | { |
258 | struct _lowcore *lc = pcpu->lowcore; | 263 | struct lowcore *lc = pcpu->lowcore; |
259 | struct thread_info *ti = task_thread_info(tsk); | 264 | struct thread_info *ti = task_thread_info(tsk); |
260 | 265 | ||
261 | lc->kernel_stack = (unsigned long) task_stack_page(tsk) | 266 | lc->kernel_stack = (unsigned long) task_stack_page(tsk) |
@@ -271,7 +276,7 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk) | |||
271 | 276 | ||
272 | static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) | 277 | static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) |
273 | { | 278 | { |
274 | struct _lowcore *lc = pcpu->lowcore; | 279 | struct lowcore *lc = pcpu->lowcore; |
275 | 280 | ||
276 | lc->restart_stack = lc->kernel_stack; | 281 | lc->restart_stack = lc->kernel_stack; |
277 | lc->restart_fn = (unsigned long) func; | 282 | lc->restart_fn = (unsigned long) func; |
@@ -286,7 +291,7 @@ static void pcpu_start_fn(struct pcpu *pcpu, void (*func)(void *), void *data) | |||
286 | static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), | 291 | static void pcpu_delegate(struct pcpu *pcpu, void (*func)(void *), |
287 | void *data, unsigned long stack) | 292 | void *data, unsigned long stack) |
288 | { | 293 | { |
289 | struct _lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; | 294 | struct lowcore *lc = lowcore_ptr[pcpu - pcpu_devices]; |
290 | unsigned long source_cpu = stap(); | 295 | unsigned long source_cpu = stap(); |
291 | 296 | ||
292 | __load_psw_mask(PSW_KERNEL_BITS); | 297 | __load_psw_mask(PSW_KERNEL_BITS); |
@@ -538,53 +543,24 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); | |||
538 | 543 | ||
539 | #ifdef CONFIG_CRASH_DUMP | 544 | #ifdef CONFIG_CRASH_DUMP |
540 | 545 | ||
541 | static void __init __smp_store_cpu_state(struct save_area_ext *sa_ext, | ||
542 | u16 address, int is_boot_cpu) | ||
543 | { | ||
544 | void *lc = (void *)(unsigned long) store_prefix(); | ||
545 | unsigned long vx_sa; | ||
546 | |||
547 | if (is_boot_cpu) { | ||
548 | /* Copy the registers of the boot CPU. */ | ||
549 | copy_oldmem_page(1, (void *) &sa_ext->sa, sizeof(sa_ext->sa), | ||
550 | SAVE_AREA_BASE - PAGE_SIZE, 0); | ||
551 | if (MACHINE_HAS_VX) | ||
552 | save_vx_regs_safe(sa_ext->vx_regs); | ||
553 | return; | ||
554 | } | ||
555 | /* Get the registers of a non-boot cpu. */ | ||
556 | __pcpu_sigp_relax(address, SIGP_STOP_AND_STORE_STATUS, 0, NULL); | ||
557 | memcpy_real(&sa_ext->sa, lc + SAVE_AREA_BASE, sizeof(sa_ext->sa)); | ||
558 | if (!MACHINE_HAS_VX) | ||
559 | return; | ||
560 | /* Get the VX registers */ | ||
561 | vx_sa = memblock_alloc(PAGE_SIZE, PAGE_SIZE); | ||
562 | if (!vx_sa) | ||
563 | panic("could not allocate memory for VX save area\n"); | ||
564 | __pcpu_sigp_relax(address, SIGP_STORE_ADDITIONAL_STATUS, vx_sa, NULL); | ||
565 | memcpy(sa_ext->vx_regs, (void *) vx_sa, sizeof(sa_ext->vx_regs)); | ||
566 | memblock_free(vx_sa, PAGE_SIZE); | ||
567 | } | ||
568 | |||
569 | int smp_store_status(int cpu) | 546 | int smp_store_status(int cpu) |
570 | { | 547 | { |
571 | unsigned long vx_sa; | 548 | struct pcpu *pcpu = pcpu_devices + cpu; |
572 | struct pcpu *pcpu; | 549 | unsigned long pa; |
573 | 550 | ||
574 | pcpu = pcpu_devices + cpu; | 551 | pa = __pa(&pcpu->lowcore->floating_pt_save_area); |
575 | if (__pcpu_sigp_relax(pcpu->address, SIGP_STOP_AND_STORE_STATUS, | 552 | if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_STATUS_AT_ADDRESS, |
576 | 0, NULL) != SIGP_CC_ORDER_CODE_ACCEPTED) | 553 | pa) != SIGP_CC_ORDER_CODE_ACCEPTED) |
577 | return -EIO; | 554 | return -EIO; |
578 | if (!MACHINE_HAS_VX) | 555 | if (!MACHINE_HAS_VX) |
579 | return 0; | 556 | return 0; |
580 | vx_sa = __pa(pcpu->lowcore->vector_save_area_addr); | 557 | pa = __pa(pcpu->lowcore->vector_save_area_addr); |
581 | __pcpu_sigp_relax(pcpu->address, SIGP_STORE_ADDITIONAL_STATUS, | 558 | if (__pcpu_sigp_relax(pcpu->address, SIGP_STORE_ADDITIONAL_STATUS, |
582 | vx_sa, NULL); | 559 | pa) != SIGP_CC_ORDER_CODE_ACCEPTED) |
560 | return -EIO; | ||
583 | return 0; | 561 | return 0; |
584 | } | 562 | } |
585 | 563 | ||
586 | #endif /* CONFIG_CRASH_DUMP */ | ||
587 | |||
588 | /* | 564 | /* |
589 | * Collect CPU state of the previous, crashed system. | 565 | * Collect CPU state of the previous, crashed system. |
590 | * There are four cases: | 566 | * There are four cases: |
@@ -593,7 +569,7 @@ int smp_store_status(int cpu) | |||
593 | * The state for all CPUs except the boot CPU needs to be collected | 569 | * The state for all CPUs except the boot CPU needs to be collected |
594 | * with sigp stop-and-store-status. The boot CPU state is located in | 570 | * with sigp stop-and-store-status. The boot CPU state is located in |
595 | * the absolute lowcore of the memory stored in the HSA. The zcore code | 571 | * the absolute lowcore of the memory stored in the HSA. The zcore code |
596 | * will allocate the save area and copy the boot CPU state from the HSA. | 572 | * will copy the boot CPU state from the HSA. |
597 | * 2) stand-alone kdump for SCSI (zfcp dump with swapped memory) | 573 | * 2) stand-alone kdump for SCSI (zfcp dump with swapped memory) |
598 | * condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP | 574 | * condition: OLDMEM_BASE != NULL && ipl_info.type == IPL_TYPE_FCP_DUMP |
599 | * The state for all CPUs except the boot CPU needs to be collected | 575 | * The state for all CPUs except the boot CPU needs to be collected |
@@ -608,55 +584,78 @@ int smp_store_status(int cpu) | |||
608 | * stored the registers of the boot CPU in the memory of the old system. | 584 | * stored the registers of the boot CPU in the memory of the old system. |
609 | * 4) kdump and the old kernel stored the CPU state | 585 | * 4) kdump and the old kernel stored the CPU state |
610 | * condition: OLDMEM_BASE != NULL && is_kdump_kernel() | 586 | * condition: OLDMEM_BASE != NULL && is_kdump_kernel() |
611 | * The state of all CPUs is stored in ELF sections in the memory of the | 587 | * This case does not exist for s390 anymore, setup_arch explicitly |
612 | * old system. The ELF sections are picked up by the crash_dump code | 588 | * deactivates the elfcorehdr= kernel parameter |
613 | * via elfcorehdr_addr. | ||
614 | */ | 589 | */ |
590 | static __init void smp_save_cpu_vxrs(struct save_area *sa, u16 addr, | ||
591 | bool is_boot_cpu, unsigned long page) | ||
592 | { | ||
593 | __vector128 *vxrs = (__vector128 *) page; | ||
594 | |||
595 | if (is_boot_cpu) | ||
596 | vxrs = boot_cpu_vector_save_area; | ||
597 | else | ||
598 | __pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, page); | ||
599 | save_area_add_vxrs(sa, vxrs); | ||
600 | } | ||
601 | |||
602 | static __init void smp_save_cpu_regs(struct save_area *sa, u16 addr, | ||
603 | bool is_boot_cpu, unsigned long page) | ||
604 | { | ||
605 | void *regs = (void *) page; | ||
606 | |||
607 | if (is_boot_cpu) | ||
608 | copy_oldmem_kernel(regs, (void *) __LC_FPREGS_SAVE_AREA, 512); | ||
609 | else | ||
610 | __pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, page); | ||
611 | save_area_add_regs(sa, regs); | ||
612 | } | ||
613 | |||
615 | void __init smp_save_dump_cpus(void) | 614 | void __init smp_save_dump_cpus(void) |
616 | { | 615 | { |
617 | #ifdef CONFIG_CRASH_DUMP | 616 | int addr, boot_cpu_addr, max_cpu_addr; |
618 | int addr, cpu, boot_cpu_addr, max_cpu_addr; | 617 | struct save_area *sa; |
619 | struct save_area_ext *sa_ext; | 618 | unsigned long page; |
620 | bool is_boot_cpu; | 619 | bool is_boot_cpu; |
621 | 620 | ||
622 | if (is_kdump_kernel()) | ||
623 | /* Previous system stored the CPU states. Nothing to do. */ | ||
624 | return; | ||
625 | if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP)) | 621 | if (!(OLDMEM_BASE || ipl_info.type == IPL_TYPE_FCP_DUMP)) |
626 | /* No previous system present, normal boot. */ | 622 | /* No previous system present, normal boot. */ |
627 | return; | 623 | return; |
624 | /* Allocate a page as dumping area for the store status sigps */ | ||
625 | page = memblock_alloc_base(PAGE_SIZE, PAGE_SIZE, 1UL << 31); | ||
626 | if (!page) | ||
627 | panic("could not allocate memory for save area\n"); | ||
628 | /* Set multi-threading state to the previous system. */ | 628 | /* Set multi-threading state to the previous system. */ |
629 | pcpu_set_smt(sclp.mtid_prev); | 629 | pcpu_set_smt(sclp.mtid_prev); |
630 | max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev; | ||
631 | for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) { | ||
632 | if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0, NULL) == | ||
633 | SIGP_CC_NOT_OPERATIONAL) | ||
634 | continue; | ||
635 | cpu += 1; | ||
636 | } | ||
637 | dump_save_areas.areas = (void *)memblock_alloc(sizeof(void *) * cpu, 8); | ||
638 | dump_save_areas.count = cpu; | ||
639 | boot_cpu_addr = stap(); | 630 | boot_cpu_addr = stap(); |
640 | for (cpu = 0, addr = 0; addr <= max_cpu_addr; addr++) { | 631 | max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev; |
641 | if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0, NULL) == | 632 | for (addr = 0; addr <= max_cpu_addr; addr++) { |
633 | if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0) == | ||
642 | SIGP_CC_NOT_OPERATIONAL) | 634 | SIGP_CC_NOT_OPERATIONAL) |
643 | continue; | 635 | continue; |
644 | sa_ext = (void *) memblock_alloc(sizeof(*sa_ext), 8); | ||
645 | dump_save_areas.areas[cpu] = sa_ext; | ||
646 | if (!sa_ext) | ||
647 | panic("could not allocate memory for save area\n"); | ||
648 | is_boot_cpu = (addr == boot_cpu_addr); | 636 | is_boot_cpu = (addr == boot_cpu_addr); |
649 | cpu += 1; | 637 | /* Allocate save area */ |
650 | if (is_boot_cpu && !OLDMEM_BASE) | 638 | sa = save_area_alloc(is_boot_cpu); |
651 | /* Skip boot CPU for standard zfcp dump. */ | 639 | if (!sa) |
652 | continue; | 640 | panic("could not allocate memory for save area\n"); |
653 | /* Get state for this CPU. */ | 641 | if (MACHINE_HAS_VX) |
654 | __smp_store_cpu_state(sa_ext, addr, is_boot_cpu); | 642 | /* Get the vector registers */ |
643 | smp_save_cpu_vxrs(sa, addr, is_boot_cpu, page); | ||
644 | /* | ||
645 | * For a zfcp dump OLDMEM_BASE == NULL and the registers | ||
646 | * of the boot CPU are stored in the HSA. To retrieve | ||
647 | * these registers an SCLP request is required which is | ||
648 | * done by drivers/s390/char/zcore.c:init_cpu_info() | ||
649 | */ | ||
650 | if (!is_boot_cpu || OLDMEM_BASE) | ||
651 | /* Get the CPU registers */ | ||
652 | smp_save_cpu_regs(sa, addr, is_boot_cpu, page); | ||
655 | } | 653 | } |
654 | memblock_free(page, PAGE_SIZE); | ||
656 | diag308_reset(); | 655 | diag308_reset(); |
657 | pcpu_set_smt(0); | 656 | pcpu_set_smt(0); |
658 | #endif /* CONFIG_CRASH_DUMP */ | ||
659 | } | 657 | } |
658 | #endif /* CONFIG_CRASH_DUMP */ | ||
660 | 659 | ||
661 | void smp_cpu_set_polarization(int cpu, int val) | 660 | void smp_cpu_set_polarization(int cpu, int val) |
662 | { | 661 | { |
@@ -680,7 +679,7 @@ static struct sclp_core_info *smp_get_core_info(void) | |||
680 | for (address = 0; | 679 | for (address = 0; |
681 | address < (SCLP_MAX_CORES << smp_cpu_mt_shift); | 680 | address < (SCLP_MAX_CORES << smp_cpu_mt_shift); |
682 | address += (1U << smp_cpu_mt_shift)) { | 681 | address += (1U << smp_cpu_mt_shift)) { |
683 | if (__pcpu_sigp_relax(address, SIGP_SENSE, 0, NULL) == | 682 | if (__pcpu_sigp_relax(address, SIGP_SENSE, 0) == |
684 | SIGP_CC_NOT_OPERATIONAL) | 683 | SIGP_CC_NOT_OPERATIONAL) |
685 | continue; | 684 | continue; |
686 | info->core[info->configured].core_id = | 685 | info->core[info->configured].core_id = |
@@ -924,7 +923,7 @@ void __init smp_prepare_boot_cpu(void) | |||
924 | 923 | ||
925 | pcpu->state = CPU_STATE_CONFIGURED; | 924 | pcpu->state = CPU_STATE_CONFIGURED; |
926 | pcpu->address = stap(); | 925 | pcpu->address = stap(); |
927 | pcpu->lowcore = (struct _lowcore *)(unsigned long) store_prefix(); | 926 | pcpu->lowcore = (struct lowcore *)(unsigned long) store_prefix(); |
928 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; | 927 | S390_lowcore.percpu_offset = __per_cpu_offset[0]; |
929 | smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); | 928 | smp_cpu_set_polarization(0, POLARIZATION_UNKNOWN); |
930 | set_cpu_present(0, true); | 929 | set_cpu_present(0, true); |
diff --git a/arch/s390/kernel/sysinfo.c b/arch/s390/kernel/sysinfo.c index 99babea026ca..f7dba3887a54 100644 --- a/arch/s390/kernel/sysinfo.c +++ b/arch/s390/kernel/sysinfo.c | |||
@@ -111,8 +111,7 @@ static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info) | |||
111 | 111 | ||
112 | static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info) | 112 | static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info) |
113 | { | 113 | { |
114 | static int max_mnest; | 114 | int i; |
115 | int i, rc; | ||
116 | 115 | ||
117 | seq_putc(m, '\n'); | 116 | seq_putc(m, '\n'); |
118 | if (!MACHINE_HAS_TOPOLOGY) | 117 | if (!MACHINE_HAS_TOPOLOGY) |
@@ -123,7 +122,7 @@ static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info) | |||
123 | for (i = 0; i < TOPOLOGY_NR_MAG; i++) | 122 | for (i = 0; i < TOPOLOGY_NR_MAG; i++) |
124 | seq_printf(m, " %d", info->mag[i]); | 123 | seq_printf(m, " %d", info->mag[i]); |
125 | seq_putc(m, '\n'); | 124 | seq_putc(m, '\n'); |
126 | #ifdef CONFIG_SCHED_MC | 125 | #ifdef CONFIG_SCHED_TOPOLOGY |
127 | store_topology(info); | 126 | store_topology(info); |
128 | seq_printf(m, "CPU Topology SW: "); | 127 | seq_printf(m, "CPU Topology SW: "); |
129 | for (i = 0; i < TOPOLOGY_NR_MAG; i++) | 128 | for (i = 0; i < TOPOLOGY_NR_MAG; i++) |
@@ -145,6 +144,10 @@ static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info) | |||
145 | seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured); | 144 | seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured); |
146 | seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby); | 145 | seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby); |
147 | seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved); | 146 | seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved); |
147 | if (info->mt_installed) { | ||
148 | seq_printf(m, "CPUs G-MTID: %d\n", info->mt_gtid); | ||
149 | seq_printf(m, "CPUs S-MTID: %d\n", info->mt_stid); | ||
150 | } | ||
148 | /* | 151 | /* |
149 | * Sigh 2. According to the specification the alternate | 152 | * Sigh 2. According to the specification the alternate |
150 | * capability field is a 32 bit floating point number | 153 | * capability field is a 32 bit floating point number |
@@ -194,13 +197,10 @@ static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info) | |||
194 | seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved); | 197 | seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved); |
195 | seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated); | 198 | seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated); |
196 | seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); | 199 | seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); |
197 | if (info->mt_installed & 0x80) { | 200 | if (info->mt_installed) { |
198 | seq_printf(m, "LPAR CPUs G-MTID: %d\n", | 201 | seq_printf(m, "LPAR CPUs G-MTID: %d\n", info->mt_gtid); |
199 | info->mt_general & 0x1f); | 202 | seq_printf(m, "LPAR CPUs S-MTID: %d\n", info->mt_stid); |
200 | seq_printf(m, "LPAR CPUs S-MTID: %d\n", | 203 | seq_printf(m, "LPAR CPUs PS-MTID: %d\n", info->mt_psmtid); |
201 | info->mt_installed & 0x1f); | ||
202 | seq_printf(m, "LPAR CPUs PS-MTID: %d\n", | ||
203 | info->mt_psmtid & 0x1f); | ||
204 | } | 204 | } |
205 | } | 205 | } |
206 | 206 | ||
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c index 1b18118bbc06..d69d648759c9 100644 --- a/arch/s390/kernel/traps.c +++ b/arch/s390/kernel/traps.c | |||
@@ -260,11 +260,8 @@ void vector_exception(struct pt_regs *regs) | |||
260 | 260 | ||
261 | void data_exception(struct pt_regs *regs) | 261 | void data_exception(struct pt_regs *regs) |
262 | { | 262 | { |
263 | __u16 __user *location; | ||
264 | int signal = 0; | 263 | int signal = 0; |
265 | 264 | ||
266 | location = get_trap_ip(regs); | ||
267 | |||
268 | save_fpu_regs(); | 265 | save_fpu_regs(); |
269 | if (current->thread.fpu.fpc & FPC_DXC_MASK) | 266 | if (current->thread.fpu.fpc & FPC_DXC_MASK) |
270 | signal = SIGFPE; | 267 | signal = SIGFPE; |
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c index 59eddb0e1a3e..94495cac8be3 100644 --- a/arch/s390/kernel/vdso.c +++ b/arch/s390/kernel/vdso.c | |||
@@ -80,7 +80,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data; | |||
80 | /* | 80 | /* |
81 | * Setup vdso data page. | 81 | * Setup vdso data page. |
82 | */ | 82 | */ |
83 | static void vdso_init_data(struct vdso_data *vd) | 83 | static void __init vdso_init_data(struct vdso_data *vd) |
84 | { | 84 | { |
85 | vd->ectg_available = test_facility(31); | 85 | vd->ectg_available = test_facility(31); |
86 | } | 86 | } |
@@ -90,9 +90,10 @@ static void vdso_init_data(struct vdso_data *vd) | |||
90 | */ | 90 | */ |
91 | #define SEGMENT_ORDER 2 | 91 | #define SEGMENT_ORDER 2 |
92 | 92 | ||
93 | int vdso_alloc_per_cpu(struct _lowcore *lowcore) | 93 | int vdso_alloc_per_cpu(struct lowcore *lowcore) |
94 | { | 94 | { |
95 | unsigned long segment_table, page_table, page_frame; | 95 | unsigned long segment_table, page_table, page_frame; |
96 | struct vdso_per_cpu_data *vd; | ||
96 | u32 *psal, *aste; | 97 | u32 *psal, *aste; |
97 | int i; | 98 | int i; |
98 | 99 | ||
@@ -107,6 +108,12 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore) | |||
107 | if (!segment_table || !page_table || !page_frame) | 108 | if (!segment_table || !page_table || !page_frame) |
108 | goto out; | 109 | goto out; |
109 | 110 | ||
111 | /* Initialize per-cpu vdso data page */ | ||
112 | vd = (struct vdso_per_cpu_data *) page_frame; | ||
113 | vd->cpu_nr = lowcore->cpu_nr; | ||
114 | vd->node_id = cpu_to_node(vd->cpu_nr); | ||
115 | |||
116 | /* Set up access register mode page table */ | ||
110 | clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, | 117 | clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, |
111 | PAGE_SIZE << SEGMENT_ORDER); | 118 | PAGE_SIZE << SEGMENT_ORDER); |
112 | clear_table((unsigned long *) page_table, _PAGE_INVALID, | 119 | clear_table((unsigned long *) page_table, _PAGE_INVALID, |
@@ -138,7 +145,7 @@ out: | |||
138 | return -ENOMEM; | 145 | return -ENOMEM; |
139 | } | 146 | } |
140 | 147 | ||
141 | void vdso_free_per_cpu(struct _lowcore *lowcore) | 148 | void vdso_free_per_cpu(struct lowcore *lowcore) |
142 | { | 149 | { |
143 | unsigned long segment_table, page_table, page_frame; | 150 | unsigned long segment_table, page_table, page_frame; |
144 | u32 *psal, *aste; | 151 | u32 *psal, *aste; |
@@ -163,7 +170,7 @@ static void vdso_init_cr5(void) | |||
163 | 170 | ||
164 | if (!vdso_enabled) | 171 | if (!vdso_enabled) |
165 | return; | 172 | return; |
166 | cr5 = offsetof(struct _lowcore, paste); | 173 | cr5 = offsetof(struct lowcore, paste); |
167 | __ctl_load(cr5, 5, 5); | 174 | __ctl_load(cr5, 5, 5); |
168 | } | 175 | } |
169 | 176 | ||
@@ -299,8 +306,6 @@ static int __init vdso_init(void) | |||
299 | 306 | ||
300 | get_page(virt_to_page(vdso_data)); | 307 | get_page(virt_to_page(vdso_data)); |
301 | 308 | ||
302 | smp_mb(); | ||
303 | |||
304 | return 0; | 309 | return 0; |
305 | } | 310 | } |
306 | early_initcall(vdso_init); | 311 | early_initcall(vdso_init); |
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile index ee8a18e50a25..f9c459586649 100644 --- a/arch/s390/kernel/vdso32/Makefile +++ b/arch/s390/kernel/vdso32/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # List of files in the vdso, has to be asm only for now | 1 | # List of files in the vdso, has to be asm only for now |
2 | 2 | ||
3 | obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o | 3 | obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o |
4 | 4 | ||
5 | # Build rules | 5 | # Build rules |
6 | 6 | ||
diff --git a/arch/s390/kernel/vdso32/getcpu.S b/arch/s390/kernel/vdso32/getcpu.S new file mode 100644 index 000000000000..c1ed0b72030f --- /dev/null +++ b/arch/s390/kernel/vdso32/getcpu.S | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Userland implementation of getcpu() for 32 bits processes in a | ||
3 | * s390 kernel for use in the vDSO | ||
4 | * | ||
5 | * Copyright IBM Corp. 2016 | ||
6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
7 | */ | ||
8 | #include <asm/vdso.h> | ||
9 | #include <asm/asm-offsets.h> | ||
10 | |||
11 | .text | ||
12 | .align 4 | ||
13 | .globl __kernel_getcpu | ||
14 | .type __kernel_getcpu,@function | ||
15 | __kernel_getcpu: | ||
16 | .cfi_startproc | ||
17 | ear %r1,%a4 | ||
18 | lhi %r4,1 | ||
19 | sll %r4,24 | ||
20 | sar %a4,%r4 | ||
21 | la %r4,0 | ||
22 | epsw %r0,0 | ||
23 | sacf 512 | ||
24 | l %r5,__VDSO_CPU_NR(%r4) | ||
25 | l %r4,__VDSO_NODE_ID(%r4) | ||
26 | tml %r0,0x4000 | ||
27 | jo 1f | ||
28 | tml %r0,0x8000 | ||
29 | jno 0f | ||
30 | sacf 256 | ||
31 | j 1f | ||
32 | 0: sacf 0 | ||
33 | 1: sar %a4,%r1 | ||
34 | ltr %r2,%r2 | ||
35 | jz 2f | ||
36 | st %r5,0(%r2) | ||
37 | 2: ltr %r3,%r3 | ||
38 | jz 3f | ||
39 | st %r4,0(%r3) | ||
40 | 3: lhi %r2,0 | ||
41 | br %r14 | ||
42 | .cfi_endproc | ||
43 | .size __kernel_getcpu,.-__kernel_getcpu | ||
diff --git a/arch/s390/kernel/vdso32/vdso32.lds.S b/arch/s390/kernel/vdso32/vdso32.lds.S index a8c379fa1247..8f048c2d6d13 100644 --- a/arch/s390/kernel/vdso32/vdso32.lds.S +++ b/arch/s390/kernel/vdso32/vdso32.lds.S | |||
@@ -132,6 +132,7 @@ VERSION | |||
132 | __kernel_gettimeofday; | 132 | __kernel_gettimeofday; |
133 | __kernel_clock_gettime; | 133 | __kernel_clock_gettime; |
134 | __kernel_clock_getres; | 134 | __kernel_clock_getres; |
135 | __kernel_getcpu; | ||
135 | 136 | ||
136 | local: *; | 137 | local: *; |
137 | }; | 138 | }; |
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile index c4b03f9ed228..058659c1b8cf 100644 --- a/arch/s390/kernel/vdso64/Makefile +++ b/arch/s390/kernel/vdso64/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # List of files in the vdso, has to be asm only for now | 1 | # List of files in the vdso, has to be asm only for now |
2 | 2 | ||
3 | obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o | 3 | obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o |
4 | 4 | ||
5 | # Build rules | 5 | # Build rules |
6 | 6 | ||
diff --git a/arch/s390/kernel/vdso64/getcpu.S b/arch/s390/kernel/vdso64/getcpu.S new file mode 100644 index 000000000000..4cbe98291931 --- /dev/null +++ b/arch/s390/kernel/vdso64/getcpu.S | |||
@@ -0,0 +1,42 @@ | |||
1 | /* | ||
2 | * Userland implementation of getcpu() for 64 bits processes in a | ||
3 | * s390 kernel for use in the vDSO | ||
4 | * | ||
5 | * Copyright IBM Corp. 2016 | ||
6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
7 | */ | ||
8 | #include <asm/vdso.h> | ||
9 | #include <asm/asm-offsets.h> | ||
10 | |||
11 | .text | ||
12 | .align 4 | ||
13 | .globl __kernel_getcpu | ||
14 | .type __kernel_getcpu,@function | ||
15 | __kernel_getcpu: | ||
16 | .cfi_startproc | ||
17 | ear %r1,%a4 | ||
18 | llilh %r4,0x0100 | ||
19 | sar %a4,%r4 | ||
20 | la %r4,0 | ||
21 | epsw %r0,0 | ||
22 | sacf 512 | ||
23 | l %r5,__VDSO_CPU_NR(%r4) | ||
24 | l %r4,__VDSO_NODE_ID(%r4) | ||
25 | tml %r0,0x4000 | ||
26 | jo 1f | ||
27 | tml %r0,0x8000 | ||
28 | jno 0f | ||
29 | sacf 256 | ||
30 | j 1f | ||
31 | 0: sacf 0 | ||
32 | 1: sar %a4,%r1 | ||
33 | ltgr %r2,%r2 | ||
34 | jz 2f | ||
35 | st %r5,0(%r2) | ||
36 | 2: ltgr %r3,%r3 | ||
37 | jz 3f | ||
38 | st %r4,0(%r3) | ||
39 | 3: lghi %r2,0 | ||
40 | br %r14 | ||
41 | .cfi_endproc | ||
42 | .size __kernel_getcpu,.-__kernel_getcpu | ||
diff --git a/arch/s390/kernel/vdso64/vdso64.lds.S b/arch/s390/kernel/vdso64/vdso64.lds.S index 9f5979d102a9..f35455d497fe 100644 --- a/arch/s390/kernel/vdso64/vdso64.lds.S +++ b/arch/s390/kernel/vdso64/vdso64.lds.S | |||
@@ -132,6 +132,7 @@ VERSION | |||
132 | __kernel_gettimeofday; | 132 | __kernel_gettimeofday; |
133 | __kernel_clock_gettime; | 133 | __kernel_clock_gettime; |
134 | __kernel_clock_getres; | 134 | __kernel_clock_getres; |
135 | __kernel_getcpu; | ||
135 | 136 | ||
136 | local: *; | 137 | local: *; |
137 | }; | 138 | }; |
diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 62ec925aa196..f88ca72c3a77 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c | |||
@@ -499,9 +499,9 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu) | |||
499 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); | 499 | trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); |
500 | 500 | ||
501 | rc = write_guest_lc(vcpu, | 501 | rc = write_guest_lc(vcpu, |
502 | offsetof(struct _lowcore, restart_old_psw), | 502 | offsetof(struct lowcore, restart_old_psw), |
503 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 503 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); |
504 | rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw), | 504 | rc |= read_guest_lc(vcpu, offsetof(struct lowcore, restart_psw), |
505 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); | 505 | &vcpu->arch.sie_block->gpsw, sizeof(psw_t)); |
506 | clear_bit(IRQ_PEND_RESTART, &li->pending_irqs); | 506 | clear_bit(IRQ_PEND_RESTART, &li->pending_irqs); |
507 | return rc ? -EFAULT : 0; | 507 | return rc ? -EFAULT : 0; |
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 5927c61d322a..835d60bedb54 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c | |||
@@ -2400,37 +2400,37 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) | |||
2400 | u64 clkcomp; | 2400 | u64 clkcomp; |
2401 | int rc; | 2401 | int rc; |
2402 | 2402 | ||
2403 | px = kvm_s390_get_prefix(vcpu); | ||
2403 | if (gpa == KVM_S390_STORE_STATUS_NOADDR) { | 2404 | if (gpa == KVM_S390_STORE_STATUS_NOADDR) { |
2404 | if (write_guest_abs(vcpu, 163, &archmode, 1)) | 2405 | if (write_guest_abs(vcpu, 163, &archmode, 1)) |
2405 | return -EFAULT; | 2406 | return -EFAULT; |
2406 | gpa = SAVE_AREA_BASE; | 2407 | gpa = 0; |
2407 | } else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) { | 2408 | } else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) { |
2408 | if (write_guest_real(vcpu, 163, &archmode, 1)) | 2409 | if (write_guest_real(vcpu, 163, &archmode, 1)) |
2409 | return -EFAULT; | 2410 | return -EFAULT; |
2410 | gpa = kvm_s390_real_to_abs(vcpu, SAVE_AREA_BASE); | 2411 | gpa = px; |
2411 | } | 2412 | } else |
2412 | rc = write_guest_abs(vcpu, gpa + offsetof(struct save_area, fp_regs), | 2413 | gpa -= __LC_FPREGS_SAVE_AREA; |
2414 | rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA, | ||
2413 | vcpu->arch.guest_fpregs.fprs, 128); | 2415 | vcpu->arch.guest_fpregs.fprs, 128); |
2414 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, gp_regs), | 2416 | rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA, |
2415 | vcpu->run->s.regs.gprs, 128); | 2417 | vcpu->run->s.regs.gprs, 128); |
2416 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, psw), | 2418 | rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA, |
2417 | &vcpu->arch.sie_block->gpsw, 16); | 2419 | &vcpu->arch.sie_block->gpsw, 16); |
2418 | px = kvm_s390_get_prefix(vcpu); | 2420 | rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA, |
2419 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, pref_reg), | ||
2420 | &px, 4); | 2421 | &px, 4); |
2421 | rc |= write_guest_abs(vcpu, | 2422 | rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA, |
2422 | gpa + offsetof(struct save_area, fp_ctrl_reg), | ||
2423 | &vcpu->arch.guest_fpregs.fpc, 4); | 2423 | &vcpu->arch.guest_fpregs.fpc, 4); |
2424 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, tod_reg), | 2424 | rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA, |
2425 | &vcpu->arch.sie_block->todpr, 4); | 2425 | &vcpu->arch.sie_block->todpr, 4); |
2426 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, timer), | 2426 | rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA, |
2427 | &vcpu->arch.sie_block->cputm, 8); | 2427 | &vcpu->arch.sie_block->cputm, 8); |
2428 | clkcomp = vcpu->arch.sie_block->ckc >> 8; | 2428 | clkcomp = vcpu->arch.sie_block->ckc >> 8; |
2429 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, clk_cmp), | 2429 | rc |= write_guest_abs(vcpu, gpa + __LC_CLOCK_COMP_SAVE_AREA, |
2430 | &clkcomp, 8); | 2430 | &clkcomp, 8); |
2431 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, acc_regs), | 2431 | rc |= write_guest_abs(vcpu, gpa + __LC_AREGS_SAVE_AREA, |
2432 | &vcpu->run->s.regs.acrs, 64); | 2432 | &vcpu->run->s.regs.acrs, 64); |
2433 | rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, ctrl_regs), | 2433 | rc |= write_guest_abs(vcpu, gpa + __LC_CREGS_SAVE_AREA, |
2434 | &vcpu->arch.sie_block->gcr, 128); | 2434 | &vcpu->arch.sie_block->gcr, 128); |
2435 | return rc ? -EFAULT : 0; | 2435 | return rc ? -EFAULT : 0; |
2436 | } | 2436 | } |
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c index d76b51cb4b62..ed74e86d9b9e 100644 --- a/arch/s390/kvm/priv.c +++ b/arch/s390/kvm/priv.c | |||
@@ -355,7 +355,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) | |||
355 | * into a u32 memory representation. They will remain bits 0-31. | 355 | * into a u32 memory representation. They will remain bits 0-31. |
356 | */ | 356 | */ |
357 | fac = *vcpu->kvm->arch.model.fac->list >> 32; | 357 | fac = *vcpu->kvm->arch.model.fac->list >> 32; |
358 | rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), | 358 | rc = write_guest_lc(vcpu, offsetof(struct lowcore, stfl_fac_list), |
359 | &fac, sizeof(fac)); | 359 | &fac, sizeof(fac)); |
360 | if (rc) | 360 | if (rc) |
361 | return rc; | 361 | return rc; |
diff --git a/arch/s390/lib/spinlock.c b/arch/s390/lib/spinlock.c index 427aa44b3505..d4549c964589 100644 --- a/arch/s390/lib/spinlock.c +++ b/arch/s390/lib/spinlock.c | |||
@@ -37,12 +37,22 @@ static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old) | |||
37 | asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock)); | 37 | asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock)); |
38 | } | 38 | } |
39 | 39 | ||
40 | static inline int cpu_is_preempted(int cpu) | ||
41 | { | ||
42 | if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu)) | ||
43 | return 0; | ||
44 | if (smp_vcpu_scheduled(cpu)) | ||
45 | return 0; | ||
46 | return 1; | ||
47 | } | ||
48 | |||
40 | void arch_spin_lock_wait(arch_spinlock_t *lp) | 49 | void arch_spin_lock_wait(arch_spinlock_t *lp) |
41 | { | 50 | { |
42 | unsigned int cpu = SPINLOCK_LOCKVAL; | 51 | unsigned int cpu = SPINLOCK_LOCKVAL; |
43 | unsigned int owner; | 52 | unsigned int owner; |
44 | int count; | 53 | int count, first_diag; |
45 | 54 | ||
55 | first_diag = 1; | ||
46 | while (1) { | 56 | while (1) { |
47 | owner = ACCESS_ONCE(lp->lock); | 57 | owner = ACCESS_ONCE(lp->lock); |
48 | /* Try to get the lock if it is free. */ | 58 | /* Try to get the lock if it is free. */ |
@@ -51,9 +61,10 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) | |||
51 | return; | 61 | return; |
52 | continue; | 62 | continue; |
53 | } | 63 | } |
54 | /* Check if the lock owner is running. */ | 64 | /* First iteration: check if the lock owner is running. */ |
55 | if (!smp_vcpu_scheduled(~owner)) { | 65 | if (first_diag && cpu_is_preempted(~owner)) { |
56 | smp_yield_cpu(~owner); | 66 | smp_yield_cpu(~owner); |
67 | first_diag = 0; | ||
57 | continue; | 68 | continue; |
58 | } | 69 | } |
59 | /* Loop for a while on the lock value. */ | 70 | /* Loop for a while on the lock value. */ |
@@ -67,10 +78,13 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) | |||
67 | continue; | 78 | continue; |
68 | /* | 79 | /* |
69 | * For multiple layers of hypervisors, e.g. z/VM + LPAR | 80 | * For multiple layers of hypervisors, e.g. z/VM + LPAR |
70 | * yield the CPU if the lock is still unavailable. | 81 | * yield the CPU unconditionally. For LPAR rely on the |
82 | * sense running status. | ||
71 | */ | 83 | */ |
72 | if (!MACHINE_IS_LPAR) | 84 | if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) { |
73 | smp_yield_cpu(~owner); | 85 | smp_yield_cpu(~owner); |
86 | first_diag = 0; | ||
87 | } | ||
74 | } | 88 | } |
75 | } | 89 | } |
76 | EXPORT_SYMBOL(arch_spin_lock_wait); | 90 | EXPORT_SYMBOL(arch_spin_lock_wait); |
@@ -79,9 +93,10 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) | |||
79 | { | 93 | { |
80 | unsigned int cpu = SPINLOCK_LOCKVAL; | 94 | unsigned int cpu = SPINLOCK_LOCKVAL; |
81 | unsigned int owner; | 95 | unsigned int owner; |
82 | int count; | 96 | int count, first_diag; |
83 | 97 | ||
84 | local_irq_restore(flags); | 98 | local_irq_restore(flags); |
99 | first_diag = 1; | ||
85 | while (1) { | 100 | while (1) { |
86 | owner = ACCESS_ONCE(lp->lock); | 101 | owner = ACCESS_ONCE(lp->lock); |
87 | /* Try to get the lock if it is free. */ | 102 | /* Try to get the lock if it is free. */ |
@@ -92,8 +107,9 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) | |||
92 | local_irq_restore(flags); | 107 | local_irq_restore(flags); |
93 | } | 108 | } |
94 | /* Check if the lock owner is running. */ | 109 | /* Check if the lock owner is running. */ |
95 | if (!smp_vcpu_scheduled(~owner)) { | 110 | if (first_diag && cpu_is_preempted(~owner)) { |
96 | smp_yield_cpu(~owner); | 111 | smp_yield_cpu(~owner); |
112 | first_diag = 0; | ||
97 | continue; | 113 | continue; |
98 | } | 114 | } |
99 | /* Loop for a while on the lock value. */ | 115 | /* Loop for a while on the lock value. */ |
@@ -107,10 +123,13 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) | |||
107 | continue; | 123 | continue; |
108 | /* | 124 | /* |
109 | * For multiple layers of hypervisors, e.g. z/VM + LPAR | 125 | * For multiple layers of hypervisors, e.g. z/VM + LPAR |
110 | * yield the CPU if the lock is still unavailable. | 126 | * yield the CPU unconditionally. For LPAR rely on the |
127 | * sense running status. | ||
111 | */ | 128 | */ |
112 | if (!MACHINE_IS_LPAR) | 129 | if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) { |
113 | smp_yield_cpu(~owner); | 130 | smp_yield_cpu(~owner); |
131 | first_diag = 0; | ||
132 | } | ||
114 | } | 133 | } |
115 | } | 134 | } |
116 | EXPORT_SYMBOL(arch_spin_lock_wait_flags); | 135 | EXPORT_SYMBOL(arch_spin_lock_wait_flags); |
@@ -145,7 +164,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) | |||
145 | owner = 0; | 164 | owner = 0; |
146 | while (1) { | 165 | while (1) { |
147 | if (count-- <= 0) { | 166 | if (count-- <= 0) { |
148 | if (owner && !smp_vcpu_scheduled(~owner)) | 167 | if (owner && cpu_is_preempted(~owner)) |
149 | smp_yield_cpu(~owner); | 168 | smp_yield_cpu(~owner); |
150 | count = spin_retry; | 169 | count = spin_retry; |
151 | } | 170 | } |
@@ -191,7 +210,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev) | |||
191 | owner = 0; | 210 | owner = 0; |
192 | while (1) { | 211 | while (1) { |
193 | if (count-- <= 0) { | 212 | if (count-- <= 0) { |
194 | if (owner && !smp_vcpu_scheduled(~owner)) | 213 | if (owner && cpu_is_preempted(~owner)) |
195 | smp_yield_cpu(~owner); | 214 | smp_yield_cpu(~owner); |
196 | count = spin_retry; | 215 | count = spin_retry; |
197 | } | 216 | } |
@@ -221,7 +240,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) | |||
221 | owner = 0; | 240 | owner = 0; |
222 | while (1) { | 241 | while (1) { |
223 | if (count-- <= 0) { | 242 | if (count-- <= 0) { |
224 | if (owner && !smp_vcpu_scheduled(~owner)) | 243 | if (owner && cpu_is_preempted(~owner)) |
225 | smp_yield_cpu(~owner); | 244 | smp_yield_cpu(~owner); |
226 | count = spin_retry; | 245 | count = spin_retry; |
227 | } | 246 | } |
@@ -265,7 +284,7 @@ void arch_lock_relax(unsigned int cpu) | |||
265 | { | 284 | { |
266 | if (!cpu) | 285 | if (!cpu) |
267 | return; | 286 | return; |
268 | if (MACHINE_IS_LPAR && smp_vcpu_scheduled(~cpu)) | 287 | if (MACHINE_IS_LPAR && !cpu_is_preempted(~cpu)) |
269 | return; | 288 | return; |
270 | smp_yield_cpu(~cpu); | 289 | smp_yield_cpu(~cpu); |
271 | } | 290 | } |
diff --git a/arch/s390/mm/extable.c b/arch/s390/mm/extable.c index 4d1ee88864e8..18c8b819b0aa 100644 --- a/arch/s390/mm/extable.c +++ b/arch/s390/mm/extable.c | |||
@@ -52,12 +52,16 @@ void sort_extable(struct exception_table_entry *start, | |||
52 | int i; | 52 | int i; |
53 | 53 | ||
54 | /* Normalize entries to being relative to the start of the section */ | 54 | /* Normalize entries to being relative to the start of the section */ |
55 | for (p = start, i = 0; p < finish; p++, i += 8) | 55 | for (p = start, i = 0; p < finish; p++, i += 8) { |
56 | p->insn += i; | 56 | p->insn += i; |
57 | p->fixup += i + 4; | ||
58 | } | ||
57 | sort(start, finish - start, sizeof(*start), cmp_ex, NULL); | 59 | sort(start, finish - start, sizeof(*start), cmp_ex, NULL); |
58 | /* Denormalize all entries */ | 60 | /* Denormalize all entries */ |
59 | for (p = start, i = 0; p < finish; p++, i += 8) | 61 | for (p = start, i = 0; p < finish; p++, i += 8) { |
60 | p->insn -= i; | 62 | p->insn -= i; |
63 | p->fixup -= i + 4; | ||
64 | } | ||
61 | } | 65 | } |
62 | 66 | ||
63 | #ifdef CONFIG_MODULES | 67 | #ifdef CONFIG_MODULES |
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index 18fccc303db7..a1bf4ad8925d 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c | |||
@@ -94,7 +94,7 @@ static DEFINE_MUTEX(dcss_lock); | |||
94 | static LIST_HEAD(dcss_list); | 94 | static LIST_HEAD(dcss_list); |
95 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", | 95 | static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", |
96 | "EW/EN-MIXED" }; | 96 | "EW/EN-MIXED" }; |
97 | static int loadshr_scode, loadnsr_scode, findseg_scode; | 97 | static int loadshr_scode, loadnsr_scode; |
98 | static int segext_scode, purgeseg_scode; | 98 | static int segext_scode, purgeseg_scode; |
99 | static int scode_set; | 99 | static int scode_set; |
100 | 100 | ||
@@ -130,7 +130,6 @@ dcss_set_subcodes(void) | |||
130 | loadshr_scode = DCSS_LOADSHRX; | 130 | loadshr_scode = DCSS_LOADSHRX; |
131 | loadnsr_scode = DCSS_LOADNSRX; | 131 | loadnsr_scode = DCSS_LOADNSRX; |
132 | purgeseg_scode = DCSS_PURGESEG; | 132 | purgeseg_scode = DCSS_PURGESEG; |
133 | findseg_scode = DCSS_FINDSEGX; | ||
134 | segext_scode = DCSS_SEGEXTX; | 133 | segext_scode = DCSS_SEGEXTX; |
135 | return 0; | 134 | return 0; |
136 | } | 135 | } |
@@ -138,7 +137,6 @@ dcss_set_subcodes(void) | |||
138 | loadshr_scode = DCSS_LOADNOLY; | 137 | loadshr_scode = DCSS_LOADNOLY; |
139 | loadnsr_scode = DCSS_LOADNSR; | 138 | loadnsr_scode = DCSS_LOADNSR; |
140 | purgeseg_scode = DCSS_PURGESEG; | 139 | purgeseg_scode = DCSS_PURGESEG; |
141 | findseg_scode = DCSS_FINDSEG; | ||
142 | segext_scode = DCSS_SEGEXT; | 140 | segext_scode = DCSS_SEGEXT; |
143 | return 0; | 141 | return 0; |
144 | } | 142 | } |
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index ec1a30d0d11a..1b903f6ad54a 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c | |||
@@ -254,7 +254,6 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code) | |||
254 | static noinline void do_no_context(struct pt_regs *regs) | 254 | static noinline void do_no_context(struct pt_regs *regs) |
255 | { | 255 | { |
256 | const struct exception_table_entry *fixup; | 256 | const struct exception_table_entry *fixup; |
257 | unsigned long address; | ||
258 | 257 | ||
259 | /* Are we prepared to handle this kernel fault? */ | 258 | /* Are we prepared to handle this kernel fault? */ |
260 | fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); | 259 | fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); |
@@ -267,7 +266,6 @@ static noinline void do_no_context(struct pt_regs *regs) | |||
267 | * Oops. The kernel tried to access some bad page. We'll have to | 266 | * Oops. The kernel tried to access some bad page. We'll have to |
268 | * terminate things with extreme prejudice. | 267 | * terminate things with extreme prejudice. |
269 | */ | 268 | */ |
270 | address = regs->int_parm_long & __FAIL_ADDR_MASK; | ||
271 | if (!user_space_fault(regs)) | 269 | if (!user_space_fault(regs)) |
272 | printk(KERN_ALERT "Unable to handle kernel pointer dereference" | 270 | printk(KERN_ALERT "Unable to handle kernel pointer dereference" |
273 | " in virtual kernel address space\n"); | 271 | " in virtual kernel address space\n"); |
diff --git a/arch/s390/mm/gup.c b/arch/s390/mm/gup.c index 12bbf0e8478f..21c74a71e2ab 100644 --- a/arch/s390/mm/gup.c +++ b/arch/s390/mm/gup.c | |||
@@ -233,6 +233,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, | |||
233 | struct mm_struct *mm = current->mm; | 233 | struct mm_struct *mm = current->mm; |
234 | int nr, ret; | 234 | int nr, ret; |
235 | 235 | ||
236 | might_sleep(); | ||
236 | start &= PAGE_MASK; | 237 | start &= PAGE_MASK; |
237 | nr = __get_user_pages_fast(start, nr_pages, write, pages); | 238 | nr = __get_user_pages_fast(start, nr_pages, write, pages); |
238 | if (nr == nr_pages) | 239 | if (nr == nr_pages) |
diff --git a/arch/s390/mm/maccess.c b/arch/s390/mm/maccess.c index 8a993a53fcd6..fec59c067d0d 100644 --- a/arch/s390/mm/maccess.c +++ b/arch/s390/mm/maccess.c | |||
@@ -163,11 +163,11 @@ static int is_swapped(unsigned long addr) | |||
163 | unsigned long lc; | 163 | unsigned long lc; |
164 | int cpu; | 164 | int cpu; |
165 | 165 | ||
166 | if (addr < sizeof(struct _lowcore)) | 166 | if (addr < sizeof(struct lowcore)) |
167 | return 1; | 167 | return 1; |
168 | for_each_online_cpu(cpu) { | 168 | for_each_online_cpu(cpu) { |
169 | lc = (unsigned long) lowcore_ptr[cpu]; | 169 | lc = (unsigned long) lowcore_ptr[cpu]; |
170 | if (addr > lc + sizeof(struct _lowcore) - 1 || addr < lc) | 170 | if (addr > lc + sizeof(struct lowcore) - 1 || addr < lc) |
171 | continue; | 171 | continue; |
172 | return 1; | 172 | return 1; |
173 | } | 173 | } |
diff --git a/arch/s390/mm/mem_detect.c b/arch/s390/mm/mem_detect.c index e00f0d5d296d..d612cc3eec6a 100644 --- a/arch/s390/mm/mem_detect.c +++ b/arch/s390/mm/mem_detect.c | |||
@@ -14,8 +14,6 @@ | |||
14 | #include <asm/sclp.h> | 14 | #include <asm/sclp.h> |
15 | #include <asm/setup.h> | 15 | #include <asm/setup.h> |
16 | 16 | ||
17 | #define ADDR2G (1ULL << 31) | ||
18 | |||
19 | #define CHUNK_READ_WRITE 0 | 17 | #define CHUNK_READ_WRITE 0 |
20 | #define CHUNK_READ_ONLY 1 | 18 | #define CHUNK_READ_ONLY 1 |
21 | 19 | ||
@@ -27,15 +25,14 @@ static inline void memblock_physmem_add(phys_addr_t start, phys_addr_t size) | |||
27 | 25 | ||
28 | void __init detect_memory_memblock(void) | 26 | void __init detect_memory_memblock(void) |
29 | { | 27 | { |
30 | unsigned long long memsize, rnmax, rzm; | 28 | unsigned long memsize, rnmax, rzm, addr, size; |
31 | unsigned long addr, size; | ||
32 | int type; | 29 | int type; |
33 | 30 | ||
34 | rzm = sclp.rzm; | 31 | rzm = sclp.rzm; |
35 | rnmax = sclp.rnmax; | 32 | rnmax = sclp.rnmax; |
36 | memsize = rzm * rnmax; | 33 | memsize = rzm * rnmax; |
37 | if (!rzm) | 34 | if (!rzm) |
38 | rzm = 1ULL << 17; | 35 | rzm = 1UL << 17; |
39 | max_physmem_end = memsize; | 36 | max_physmem_end = memsize; |
40 | addr = 0; | 37 | addr = 0; |
41 | /* keep memblock lists close to the kernel */ | 38 | /* keep memblock lists close to the kernel */ |
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c index 7ef12a3ace3a..11d4f277e9f6 100644 --- a/arch/s390/pci/pci.c +++ b/arch/s390/pci/pci.c | |||
@@ -701,8 +701,7 @@ static int zpci_restore(struct device *dev) | |||
701 | goto out; | 701 | goto out; |
702 | 702 | ||
703 | zpci_map_resources(pdev); | 703 | zpci_map_resources(pdev); |
704 | zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, | 704 | zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, |
705 | zdev->start_dma + zdev->iommu_size - 1, | ||
706 | (u64) zdev->dma_table); | 705 | (u64) zdev->dma_table); |
707 | 706 | ||
708 | out: | 707 | out: |
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index 32da0a6ecec2..4638b93c7632 100644 --- a/arch/s390/pci/pci_dma.c +++ b/arch/s390/pci/pci_dma.c | |||
@@ -457,7 +457,19 @@ int zpci_dma_init_device(struct zpci_dev *zdev) | |||
457 | goto out_clean; | 457 | goto out_clean; |
458 | } | 458 | } |
459 | 459 | ||
460 | zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET; | 460 | /* |
461 | * Restrict the iommu bitmap size to the minimum of the following: | ||
462 | * - main memory size | ||
463 | * - 3-level pagetable address limit minus start_dma offset | ||
464 | * - DMA address range allowed by the hardware (clp query pci fn) | ||
465 | * | ||
466 | * Also set zdev->end_dma to the actual end address of the usable | ||
467 | * range, instead of the theoretical maximum as reported by hardware. | ||
468 | */ | ||
469 | zdev->iommu_size = min3((u64) high_memory, | ||
470 | ZPCI_TABLE_SIZE_RT - zdev->start_dma, | ||
471 | zdev->end_dma - zdev->start_dma + 1); | ||
472 | zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1; | ||
461 | zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; | 473 | zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; |
462 | zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); | 474 | zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); |
463 | if (!zdev->iommu_bitmap) { | 475 | if (!zdev->iommu_bitmap) { |
@@ -465,10 +477,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) | |||
465 | goto out_reg; | 477 | goto out_reg; |
466 | } | 478 | } |
467 | 479 | ||
468 | rc = zpci_register_ioat(zdev, | 480 | rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma, |
469 | 0, | ||
470 | zdev->start_dma + PAGE_OFFSET, | ||
471 | zdev->start_dma + zdev->iommu_size - 1, | ||
472 | (u64) zdev->dma_table); | 481 | (u64) zdev->dma_table); |
473 | if (rc) | 482 | if (rc) |
474 | goto out_reg; | 483 | goto out_reg; |
diff --git a/arch/s390/tools/.gitignore b/arch/s390/tools/.gitignore new file mode 100644 index 000000000000..72a4b2cf1365 --- /dev/null +++ b/arch/s390/tools/.gitignore | |||
@@ -0,0 +1 @@ | |||
gen_facilities | |||
diff --git a/arch/s390/tools/Makefile b/arch/s390/tools/Makefile new file mode 100644 index 000000000000..6d9814c9df2b --- /dev/null +++ b/arch/s390/tools/Makefile | |||
@@ -0,0 +1,15 @@ | |||
1 | # | ||
2 | # Makefile for s390 specific build tools | ||
3 | # | ||
4 | |||
5 | hostprogs-y += gen_facilities | ||
6 | HOSTCFLAGS_gen_facilities.o += -Wall $(LINUXINCLUDE) | ||
7 | |||
8 | define filechk_facilities.h | ||
9 | $(obj)/gen_facilities | ||
10 | endef | ||
11 | |||
12 | $(obj)/gen_facilities.o: $(srctree)/arch/s390/tools/gen_facilities.c | ||
13 | |||
14 | include/generated/facilities.h: $(obj)/gen_facilities FORCE | ||
15 | $(call filechk,facilities.h) | ||
diff --git a/arch/s390/tools/gen_facilities.c b/arch/s390/tools/gen_facilities.c new file mode 100644 index 000000000000..e2660d27889b --- /dev/null +++ b/arch/s390/tools/gen_facilities.c | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * Simple program to generate defines out of facility lists that use the bit | ||
3 | * numbering scheme from the Princples of Operations: most significant bit | ||
4 | * has bit number 0. | ||
5 | * | ||
6 | * Copyright IBM Corp. 2015 | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #define S390_GEN_FACILITIES_C | ||
11 | |||
12 | #include <strings.h> | ||
13 | #include <string.h> | ||
14 | #include <stdlib.h> | ||
15 | #include <stdio.h> | ||
16 | #include <asm/facilities_src.h> | ||
17 | |||
18 | static void print_facility_list(struct facility_def *def) | ||
19 | { | ||
20 | unsigned int high, bit, dword, i; | ||
21 | unsigned long long *array; | ||
22 | |||
23 | array = calloc(1, 8); | ||
24 | if (!array) | ||
25 | exit(EXIT_FAILURE); | ||
26 | high = 0; | ||
27 | for (i = 0; def->bits[i] != -1; i++) { | ||
28 | bit = 63 - (def->bits[i] & 63); | ||
29 | dword = def->bits[i] / 64; | ||
30 | if (dword > high) { | ||
31 | array = realloc(array, (dword + 1) * 8); | ||
32 | if (!array) | ||
33 | exit(EXIT_FAILURE); | ||
34 | memset(array + high + 1, 0, (dword - high) * 8); | ||
35 | high = dword; | ||
36 | } | ||
37 | array[dword] |= 1ULL << bit; | ||
38 | } | ||
39 | printf("#define %s ", def->name); | ||
40 | for (i = 0; i <= high; i++) | ||
41 | printf("_AC(0x%016llx,UL)%c", array[i], i < high ? ',' : '\n'); | ||
42 | printf("#define %s_DWORDS %d\n", def->name, high + 1); | ||
43 | free(array); | ||
44 | } | ||
45 | |||
46 | static void print_facility_lists(void) | ||
47 | { | ||
48 | unsigned int i; | ||
49 | |||
50 | for (i = 0; i < sizeof(facility_defs) / sizeof(facility_defs[0]); i++) | ||
51 | print_facility_list(&facility_defs[i]); | ||
52 | } | ||
53 | |||
54 | int main(int argc, char **argv) | ||
55 | { | ||
56 | printf("#ifndef __ASM_S390_FACILITIES__\n"); | ||
57 | printf("#define __ASM_S390_FACILITIES__\n"); | ||
58 | printf("/*\n"); | ||
59 | printf(" * DO NOT MODIFY.\n"); | ||
60 | printf(" *\n"); | ||
61 | printf(" * This file was generated by %s\n", __FILE__); | ||
62 | printf(" */\n\n"); | ||
63 | printf("#include <linux/const.h>\n\n"); | ||
64 | print_facility_lists(); | ||
65 | printf("\n#endif\n"); | ||
66 | return 0; | ||
67 | } | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index a263c10359e1..41605dac8309 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -2556,8 +2556,12 @@ static void __dasd_process_request_queue(struct dasd_block *block) | |||
2556 | return; | 2556 | return; |
2557 | } | 2557 | } |
2558 | 2558 | ||
2559 | /* if device ist stopped do not fetch new requests */ | 2559 | /* |
2560 | if (basedev->stopped) | 2560 | * if device is stopped do not fetch new requests |
2561 | * except failfast is active which will let requests fail | ||
2562 | * immediately in __dasd_block_start_head() | ||
2563 | */ | ||
2564 | if (basedev->stopped && !(basedev->features & DASD_FEATURE_FAILFAST)) | ||
2561 | return; | 2565 | return; |
2562 | 2566 | ||
2563 | /* Now we try to fetch requests from the request queue */ | 2567 | /* Now we try to fetch requests from the request queue */ |
diff --git a/drivers/s390/char/Kconfig b/drivers/s390/char/Kconfig index eaca3e006301..b3f1c458905f 100644 --- a/drivers/s390/char/Kconfig +++ b/drivers/s390/char/Kconfig | |||
@@ -78,19 +78,6 @@ config SCLP_VT220_CONSOLE | |||
78 | Include support for using an IBM SCLP VT220-compatible terminal as a | 78 | Include support for using an IBM SCLP VT220-compatible terminal as a |
79 | Linux system console. | 79 | Linux system console. |
80 | 80 | ||
81 | config SCLP_CPI | ||
82 | def_tristate m | ||
83 | prompt "Control-Program Identification" | ||
84 | depends on S390 | ||
85 | help | ||
86 | This option enables the hardware console interface for system | ||
87 | identification. This is commonly used for workload management and | ||
88 | gives you a nice name for the system on the service element. | ||
89 | Please select this option as a module since built-in operation is | ||
90 | completely untested. | ||
91 | You should only select this option if you know what you are doing, | ||
92 | need this feature and intend to run your kernel in LPAR. | ||
93 | |||
94 | config SCLP_ASYNC | 81 | config SCLP_ASYNC |
95 | def_tristate m | 82 | def_tristate m |
96 | prompt "Support for Call Home via Asynchronous SCLP Records" | 83 | prompt "Support for Call Home via Asynchronous SCLP Records" |
@@ -125,6 +112,14 @@ config HMC_DRV | |||
125 | transfer cache size from it's default value 0.5MB to N bytes. If N | 112 | transfer cache size from it's default value 0.5MB to N bytes. If N |
126 | is zero, then no caching is performed. | 113 | is zero, then no caching is performed. |
127 | 114 | ||
115 | config SCLP_OFB | ||
116 | def_bool n | ||
117 | prompt "Support for Open-for-Business SCLP Event" | ||
118 | depends on S390 | ||
119 | help | ||
120 | This option enables the Open-for-Business interface to the s390 | ||
121 | Service Element. | ||
122 | |||
128 | config S390_TAPE | 123 | config S390_TAPE |
129 | def_tristate m | 124 | def_tristate m |
130 | prompt "S/390 tape device support" | 125 | prompt "S/390 tape device support" |
diff --git a/drivers/s390/char/Makefile b/drivers/s390/char/Makefile index 6fa9364d1c07..dd2f7c832e5e 100644 --- a/drivers/s390/char/Makefile +++ b/drivers/s390/char/Makefile | |||
@@ -16,7 +16,6 @@ obj-$(CONFIG_TN3215) += con3215.o | |||
16 | obj-$(CONFIG_SCLP_TTY) += sclp_tty.o | 16 | obj-$(CONFIG_SCLP_TTY) += sclp_tty.o |
17 | obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o | 17 | obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o |
18 | obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o | 18 | obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o |
19 | obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o | ||
20 | obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o | 19 | obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o |
21 | 20 | ||
22 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o | 21 | obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o |
@@ -30,9 +29,7 @@ obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o | |||
30 | obj-$(CONFIG_MONREADER) += monreader.o | 29 | obj-$(CONFIG_MONREADER) += monreader.o |
31 | obj-$(CONFIG_MONWRITER) += monwriter.o | 30 | obj-$(CONFIG_MONWRITER) += monwriter.o |
32 | obj-$(CONFIG_S390_VMUR) += vmur.o | 31 | obj-$(CONFIG_S390_VMUR) += vmur.o |
33 | 32 | obj-$(CONFIG_CRASH_DUMP) += sclp_sdias.o zcore.o | |
34 | zcore_mod-objs := sclp_sdias.o zcore.o | ||
35 | obj-$(CONFIG_CRASH_DUMP) += zcore_mod.o | ||
36 | 33 | ||
37 | hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o | 34 | hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o |
38 | obj-$(CONFIG_HMC_DRV) += hmcdrv.o | 35 | obj-$(CONFIG_HMC_DRV) += hmcdrv.o |
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c index 0fc3fe5fd5b8..7d82bbcb12df 100644 --- a/drivers/s390/char/con3215.c +++ b/drivers/s390/char/con3215.c | |||
@@ -922,6 +922,8 @@ static int __init con3215_init(void) | |||
922 | spin_lock_init(&raw3215_freelist_lock); | 922 | spin_lock_init(&raw3215_freelist_lock); |
923 | for (i = 0; i < NR_3215_REQ; i++) { | 923 | for (i = 0; i < NR_3215_REQ; i++) { |
924 | req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); | 924 | req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); |
925 | if (!req) | ||
926 | return -ENOMEM; | ||
925 | req->next = raw3215_freelist; | 927 | req->next = raw3215_freelist; |
926 | raw3215_freelist = req; | 928 | raw3215_freelist = req; |
927 | } | 929 | } |
diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c index 7c511add5aa7..4d7a9badfede 100644 --- a/drivers/s390/char/con3270.c +++ b/drivers/s390/char/con3270.c | |||
@@ -606,6 +606,8 @@ con3270_init(void) | |||
606 | return PTR_ERR(rp); | 606 | return PTR_ERR(rp); |
607 | 607 | ||
608 | condev = kzalloc(sizeof(struct con3270), GFP_KERNEL | GFP_DMA); | 608 | condev = kzalloc(sizeof(struct con3270), GFP_KERNEL | GFP_DMA); |
609 | if (!condev) | ||
610 | return -ENOMEM; | ||
609 | condev->view.dev = rp; | 611 | condev->view.dev = rp; |
610 | 612 | ||
611 | condev->read = raw3270_request_alloc(0); | 613 | condev->read = raw3270_request_alloc(0); |
diff --git a/drivers/s390/char/hmcdrv_ftp.c b/drivers/s390/char/hmcdrv_ftp.c index d4b61d9088fb..8cb7d8fbadd6 100644 --- a/drivers/s390/char/hmcdrv_ftp.c +++ b/drivers/s390/char/hmcdrv_ftp.c | |||
@@ -37,7 +37,7 @@ struct hmcdrv_ftp_ops { | |||
37 | static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len); | 37 | static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len); |
38 | static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp); | 38 | static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp); |
39 | 39 | ||
40 | static struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ | 40 | static const struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ |
41 | static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */ | 41 | static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */ |
42 | static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */ | 42 | static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */ |
43 | 43 | ||
@@ -290,13 +290,13 @@ ssize_t hmcdrv_ftp_cmd(char __kernel *cmd, loff_t offset, | |||
290 | */ | 290 | */ |
291 | int hmcdrv_ftp_startup(void) | 291 | int hmcdrv_ftp_startup(void) |
292 | { | 292 | { |
293 | static struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = { | 293 | static const struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = { |
294 | .startup = diag_ftp_startup, | 294 | .startup = diag_ftp_startup, |
295 | .shutdown = diag_ftp_shutdown, | 295 | .shutdown = diag_ftp_shutdown, |
296 | .transfer = diag_ftp_cmd | 296 | .transfer = diag_ftp_cmd |
297 | }; | 297 | }; |
298 | 298 | ||
299 | static struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = { | 299 | static const struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = { |
300 | .startup = sclp_ftp_startup, | 300 | .startup = sclp_ftp_startup, |
301 | .shutdown = sclp_ftp_shutdown, | 301 | .shutdown = sclp_ftp_shutdown, |
302 | .transfer = sclp_ftp_cmd | 302 | .transfer = sclp_ftp_cmd |
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c index f58bf4c6c3ee..272898225dbb 100644 --- a/drivers/s390/char/sclp.c +++ b/drivers/s390/char/sclp.c | |||
@@ -579,9 +579,8 @@ sclp_sync_wait(void) | |||
579 | old_tick = local_tick_disable(); | 579 | old_tick = local_tick_disable(); |
580 | trace_hardirqs_on(); | 580 | trace_hardirqs_on(); |
581 | __ctl_store(cr0, 0, 0); | 581 | __ctl_store(cr0, 0, 0); |
582 | cr0_sync = cr0; | 582 | cr0_sync = cr0 & ~CR0_IRQ_SUBCLASS_MASK; |
583 | cr0_sync &= 0xffff00a0; | 583 | cr0_sync |= 1UL << (63 - 54); |
584 | cr0_sync |= 0x00000200; | ||
585 | __ctl_load(cr0_sync, 0, 0); | 584 | __ctl_load(cr0_sync, 0, 0); |
586 | __arch_local_irq_stosm(0x01); | 585 | __arch_local_irq_stosm(0x01); |
587 | /* Loop until driver state indicates finished request */ | 586 | /* Loop until driver state indicates finished request */ |
diff --git a/drivers/s390/char/sclp_config.c b/drivers/s390/char/sclp_config.c index 944156207477..2ced50ccca63 100644 --- a/drivers/s390/char/sclp_config.c +++ b/drivers/s390/char/sclp_config.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/cpu.h> | 11 | #include <linux/cpu.h> |
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/workqueue.h> | 13 | #include <linux/workqueue.h> |
14 | #include <linux/slab.h> | ||
15 | #include <linux/sysfs.h> | ||
14 | #include <asm/smp.h> | 16 | #include <asm/smp.h> |
15 | 17 | ||
16 | #include "sclp.h" | 18 | #include "sclp.h" |
@@ -20,8 +22,22 @@ struct conf_mgm_data { | |||
20 | u8 ev_qualifier; | 22 | u8 ev_qualifier; |
21 | } __attribute__((packed)); | 23 | } __attribute__((packed)); |
22 | 24 | ||
25 | #define OFB_DATA_MAX 64 | ||
26 | |||
27 | struct sclp_ofb_evbuf { | ||
28 | struct evbuf_header header; | ||
29 | struct conf_mgm_data cm_data; | ||
30 | char ev_data[OFB_DATA_MAX]; | ||
31 | } __packed; | ||
32 | |||
33 | struct sclp_ofb_sccb { | ||
34 | struct sccb_header header; | ||
35 | struct sclp_ofb_evbuf ofb_evbuf; | ||
36 | } __packed; | ||
37 | |||
23 | #define EV_QUAL_CPU_CHANGE 1 | 38 | #define EV_QUAL_CPU_CHANGE 1 |
24 | #define EV_QUAL_CAP_CHANGE 3 | 39 | #define EV_QUAL_CAP_CHANGE 3 |
40 | #define EV_QUAL_OPEN4BUSINESS 5 | ||
25 | 41 | ||
26 | static struct work_struct sclp_cpu_capability_work; | 42 | static struct work_struct sclp_cpu_capability_work; |
27 | static struct work_struct sclp_cpu_change_work; | 43 | static struct work_struct sclp_cpu_change_work; |
@@ -63,15 +79,99 @@ static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) | |||
63 | 79 | ||
64 | static struct sclp_register sclp_conf_register = | 80 | static struct sclp_register sclp_conf_register = |
65 | { | 81 | { |
82 | #ifdef CONFIG_SCLP_OFB | ||
83 | .send_mask = EVTYP_CONFMGMDATA_MASK, | ||
84 | #endif | ||
66 | .receive_mask = EVTYP_CONFMGMDATA_MASK, | 85 | .receive_mask = EVTYP_CONFMGMDATA_MASK, |
67 | .receiver_fn = sclp_conf_receiver_fn, | 86 | .receiver_fn = sclp_conf_receiver_fn, |
68 | }; | 87 | }; |
69 | 88 | ||
89 | #ifdef CONFIG_SCLP_OFB | ||
90 | static int sclp_ofb_send_req(char *ev_data, size_t len) | ||
91 | { | ||
92 | static DEFINE_MUTEX(send_mutex); | ||
93 | struct sclp_ofb_sccb *sccb; | ||
94 | int rc, response; | ||
95 | |||
96 | if (len > OFB_DATA_MAX) | ||
97 | return -EINVAL; | ||
98 | sccb = (struct sclp_ofb_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA); | ||
99 | if (!sccb) | ||
100 | return -ENOMEM; | ||
101 | /* Setup SCCB for Control-Program Identification */ | ||
102 | sccb->header.length = sizeof(struct sclp_ofb_sccb); | ||
103 | sccb->ofb_evbuf.header.length = sizeof(struct sclp_ofb_evbuf); | ||
104 | sccb->ofb_evbuf.header.type = EVTYP_CONFMGMDATA; | ||
105 | sccb->ofb_evbuf.cm_data.ev_qualifier = EV_QUAL_OPEN4BUSINESS; | ||
106 | memcpy(sccb->ofb_evbuf.ev_data, ev_data, len); | ||
107 | |||
108 | if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK)) | ||
109 | pr_warn("SCLP receiver did not register to receive " | ||
110 | "Configuration Management Data Events.\n"); | ||
111 | |||
112 | mutex_lock(&send_mutex); | ||
113 | rc = sclp_sync_request(SCLP_CMDW_WRITE_EVENT_DATA, sccb); | ||
114 | mutex_unlock(&send_mutex); | ||
115 | if (rc) | ||
116 | goto out; | ||
117 | response = sccb->header.response_code; | ||
118 | if (response != 0x0020) { | ||
119 | pr_err("Open for Business request failed with response code " | ||
120 | "0x%04x\n", response); | ||
121 | rc = -EIO; | ||
122 | } | ||
123 | out: | ||
124 | free_page((unsigned long)sccb); | ||
125 | return rc; | ||
126 | } | ||
127 | |||
128 | static ssize_t sysfs_ofb_data_write(struct file *filp, struct kobject *kobj, | ||
129 | struct bin_attribute *bin_attr, | ||
130 | char *buf, loff_t off, size_t count) | ||
131 | { | ||
132 | int rc; | ||
133 | |||
134 | rc = sclp_ofb_send_req(buf, count); | ||
135 | return rc ?: count; | ||
136 | } | ||
137 | |||
138 | static struct bin_attribute ofb_bin_attr = { | ||
139 | .attr = { | ||
140 | .name = "event_data", | ||
141 | .mode = S_IWUSR, | ||
142 | }, | ||
143 | .write = sysfs_ofb_data_write, | ||
144 | }; | ||
145 | #endif | ||
146 | |||
147 | static int __init sclp_ofb_setup(void) | ||
148 | { | ||
149 | #ifdef CONFIG_SCLP_OFB | ||
150 | struct kset *ofb_kset; | ||
151 | int rc; | ||
152 | |||
153 | ofb_kset = kset_create_and_add("ofb", NULL, firmware_kobj); | ||
154 | if (!ofb_kset) | ||
155 | return -ENOMEM; | ||
156 | rc = sysfs_create_bin_file(&ofb_kset->kobj, &ofb_bin_attr); | ||
157 | if (rc) { | ||
158 | kset_unregister(ofb_kset); | ||
159 | return rc; | ||
160 | } | ||
161 | #endif | ||
162 | return 0; | ||
163 | } | ||
164 | |||
70 | static int __init sclp_conf_init(void) | 165 | static int __init sclp_conf_init(void) |
71 | { | 166 | { |
167 | int rc; | ||
168 | |||
72 | INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); | 169 | INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); |
73 | INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); | 170 | INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); |
74 | return sclp_register(&sclp_conf_register); | 171 | rc = sclp_register(&sclp_conf_register); |
172 | if (rc) | ||
173 | return rc; | ||
174 | return sclp_ofb_setup(); | ||
75 | } | 175 | } |
76 | 176 | ||
77 | __initcall(sclp_conf_init); | 177 | __initcall(sclp_conf_init); |
diff --git a/drivers/s390/char/sclp_cpi.c b/drivers/s390/char/sclp_cpi.c deleted file mode 100644 index d70d8c20229c..000000000000 --- a/drivers/s390/char/sclp_cpi.c +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | * SCLP control programm identification | ||
3 | * | ||
4 | * Copyright IBM Corp. 2001, 2007 | ||
5 | * Author(s): Martin Peschke <mpeschke@de.ibm.com> | ||
6 | * Michael Ernst <mernst@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/kmod.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/moduleparam.h> | ||
12 | #include <linux/version.h> | ||
13 | #include "sclp_cpi_sys.h" | ||
14 | |||
15 | MODULE_LICENSE("GPL"); | ||
16 | MODULE_DESCRIPTION("Identify this operating system instance " | ||
17 | "to the System z hardware"); | ||
18 | MODULE_AUTHOR("Martin Peschke <mpeschke@de.ibm.com>, " | ||
19 | "Michael Ernst <mernst@de.ibm.com>"); | ||
20 | |||
21 | static char *system_name = ""; | ||
22 | static char *sysplex_name = ""; | ||
23 | |||
24 | module_param(system_name, charp, 0); | ||
25 | MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters"); | ||
26 | module_param(sysplex_name, charp, 0); | ||
27 | MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters"); | ||
28 | |||
29 | static int __init cpi_module_init(void) | ||
30 | { | ||
31 | return sclp_cpi_set_data(system_name, sysplex_name, "LINUX", | ||
32 | LINUX_VERSION_CODE); | ||
33 | } | ||
34 | |||
35 | static void __exit cpi_module_exit(void) | ||
36 | { | ||
37 | } | ||
38 | |||
39 | module_init(cpi_module_init); | ||
40 | module_exit(cpi_module_exit); | ||
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 3339b862ec17..5043ecfa1fbc 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c | |||
@@ -28,13 +28,12 @@ | |||
28 | #include <asm/processor.h> | 28 | #include <asm/processor.h> |
29 | #include <asm/irqflags.h> | 29 | #include <asm/irqflags.h> |
30 | #include <asm/checksum.h> | 30 | #include <asm/checksum.h> |
31 | #include <asm/os_info.h> | ||
31 | #include <asm/switch_to.h> | 32 | #include <asm/switch_to.h> |
32 | #include "sclp.h" | 33 | #include "sclp.h" |
33 | 34 | ||
34 | #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x) | 35 | #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x) |
35 | 36 | ||
36 | #define TO_USER 1 | ||
37 | #define TO_KERNEL 0 | ||
38 | #define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */ | 37 | #define CHUNK_INFO_SIZE 34 /* 2 16-byte char, each followed by blank */ |
39 | 38 | ||
40 | enum arch_id { | 39 | enum arch_id { |
@@ -42,241 +41,93 @@ enum arch_id { | |||
42 | ARCH_S390X = 1, | 41 | ARCH_S390X = 1, |
43 | }; | 42 | }; |
44 | 43 | ||
45 | /* dump system info */ | ||
46 | |||
47 | struct sys_info { | ||
48 | enum arch_id arch; | ||
49 | unsigned long sa_base; | ||
50 | u32 sa_size; | ||
51 | int cpu_map[NR_CPUS]; | ||
52 | unsigned long mem_size; | ||
53 | struct save_area lc_mask; | ||
54 | }; | ||
55 | |||
56 | struct ipib_info { | 44 | struct ipib_info { |
57 | unsigned long ipib; | 45 | unsigned long ipib; |
58 | u32 checksum; | 46 | u32 checksum; |
59 | } __attribute__((packed)); | 47 | } __attribute__((packed)); |
60 | 48 | ||
61 | static struct sys_info sys_info; | ||
62 | static struct debug_info *zcore_dbf; | 49 | static struct debug_info *zcore_dbf; |
63 | static int hsa_available; | 50 | static int hsa_available; |
64 | static struct dentry *zcore_dir; | 51 | static struct dentry *zcore_dir; |
65 | static struct dentry *zcore_file; | ||
66 | static struct dentry *zcore_memmap_file; | 52 | static struct dentry *zcore_memmap_file; |
67 | static struct dentry *zcore_reipl_file; | 53 | static struct dentry *zcore_reipl_file; |
68 | static struct dentry *zcore_hsa_file; | 54 | static struct dentry *zcore_hsa_file; |
69 | static struct ipl_parameter_block *ipl_block; | 55 | static struct ipl_parameter_block *ipl_block; |
70 | 56 | ||
57 | static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE); | ||
58 | |||
71 | /* | 59 | /* |
72 | * Copy memory from HSA to kernel or user memory (not reentrant): | 60 | * Copy memory from HSA to user memory (not reentrant): |
73 | * | 61 | * |
74 | * @dest: Kernel or user buffer where memory should be copied to | 62 | * @dest: User buffer where memory should be copied to |
75 | * @src: Start address within HSA where data should be copied | 63 | * @src: Start address within HSA where data should be copied |
76 | * @count: Size of buffer, which should be copied | 64 | * @count: Size of buffer, which should be copied |
77 | * @mode: Either TO_KERNEL or TO_USER | ||
78 | */ | 65 | */ |
79 | int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode) | 66 | int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) |
80 | { | 67 | { |
81 | int offs, blk_num; | 68 | unsigned long offset, bytes; |
82 | static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); | ||
83 | 69 | ||
84 | if (!hsa_available) | 70 | if (!hsa_available) |
85 | return -ENODATA; | 71 | return -ENODATA; |
86 | if (count == 0) | ||
87 | return 0; | ||
88 | 72 | ||
89 | /* copy first block */ | 73 | while (count) { |
90 | offs = 0; | 74 | if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { |
91 | if ((src % PAGE_SIZE) != 0) { | ||
92 | blk_num = src / PAGE_SIZE + 2; | ||
93 | if (sclp_sdias_copy(buf, blk_num, 1)) { | ||
94 | TRACE("sclp_sdias_copy() failed\n"); | 75 | TRACE("sclp_sdias_copy() failed\n"); |
95 | return -EIO; | 76 | return -EIO; |
96 | } | 77 | } |
97 | offs = min((PAGE_SIZE - (src % PAGE_SIZE)), count); | 78 | offset = src % PAGE_SIZE; |
98 | if (mode == TO_USER) { | 79 | bytes = min(PAGE_SIZE - offset, count); |
99 | if (copy_to_user((__force __user void*) dest, | 80 | if (copy_to_user(dest, hsa_buf + offset, bytes)) |
100 | buf + (src % PAGE_SIZE), offs)) | ||
101 | return -EFAULT; | ||
102 | } else | ||
103 | memcpy(dest, buf + (src % PAGE_SIZE), offs); | ||
104 | } | ||
105 | if (offs == count) | ||
106 | goto out; | ||
107 | |||
108 | /* copy middle */ | ||
109 | for (; (offs + PAGE_SIZE) <= count; offs += PAGE_SIZE) { | ||
110 | blk_num = (src + offs) / PAGE_SIZE + 2; | ||
111 | if (sclp_sdias_copy(buf, blk_num, 1)) { | ||
112 | TRACE("sclp_sdias_copy() failed\n"); | ||
113 | return -EIO; | ||
114 | } | ||
115 | if (mode == TO_USER) { | ||
116 | if (copy_to_user((__force __user void*) dest + offs, | ||
117 | buf, PAGE_SIZE)) | ||
118 | return -EFAULT; | ||
119 | } else | ||
120 | memcpy(dest + offs, buf, PAGE_SIZE); | ||
121 | } | ||
122 | if (offs == count) | ||
123 | goto out; | ||
124 | |||
125 | /* copy last block */ | ||
126 | blk_num = (src + offs) / PAGE_SIZE + 2; | ||
127 | if (sclp_sdias_copy(buf, blk_num, 1)) { | ||
128 | TRACE("sclp_sdias_copy() failed\n"); | ||
129 | return -EIO; | ||
130 | } | ||
131 | if (mode == TO_USER) { | ||
132 | if (copy_to_user((__force __user void*) dest + offs, buf, | ||
133 | count - offs)) | ||
134 | return -EFAULT; | 81 | return -EFAULT; |
135 | } else | 82 | src += bytes; |
136 | memcpy(dest + offs, buf, count - offs); | 83 | dest += bytes; |
137 | out: | 84 | count -= bytes; |
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count) | ||
142 | { | ||
143 | return memcpy_hsa((void __force *) dest, src, count, TO_USER); | ||
144 | } | ||
145 | |||
146 | static int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) | ||
147 | { | ||
148 | return memcpy_hsa(dest, src, count, TO_KERNEL); | ||
149 | } | ||
150 | |||
151 | static int __init init_cpu_info(enum arch_id arch) | ||
152 | { | ||
153 | struct save_area_ext *sa_ext; | ||
154 | |||
155 | /* get info for boot cpu from lowcore, stored in the HSA */ | ||
156 | |||
157 | sa_ext = dump_save_areas.areas[0]; | ||
158 | if (!sa_ext) | ||
159 | return -ENOMEM; | ||
160 | if (memcpy_hsa_kernel(&sa_ext->sa, sys_info.sa_base, | ||
161 | sys_info.sa_size) < 0) { | ||
162 | TRACE("could not copy from HSA\n"); | ||
163 | kfree(sa_ext); | ||
164 | return -EIO; | ||
165 | } | 85 | } |
166 | if (MACHINE_HAS_VX) | ||
167 | save_vx_regs_safe(sa_ext->vx_regs); | ||
168 | return 0; | 86 | return 0; |
169 | } | 87 | } |
170 | 88 | ||
171 | static DEFINE_MUTEX(zcore_mutex); | ||
172 | |||
173 | #define DUMP_VERSION 0x5 | ||
174 | #define DUMP_MAGIC 0xa8190173618f23fdULL | ||
175 | #define DUMP_ARCH_S390X 2 | ||
176 | #define DUMP_ARCH_S390 1 | ||
177 | #define HEADER_SIZE 4096 | ||
178 | |||
179 | /* dump header dumped according to s390 crash dump format */ | ||
180 | |||
181 | struct zcore_header { | ||
182 | u64 magic; | ||
183 | u32 version; | ||
184 | u32 header_size; | ||
185 | u32 dump_level; | ||
186 | u32 page_size; | ||
187 | u64 mem_size; | ||
188 | u64 mem_start; | ||
189 | u64 mem_end; | ||
190 | u32 num_pages; | ||
191 | u32 pad1; | ||
192 | u64 tod; | ||
193 | struct cpuid cpu_id; | ||
194 | u32 arch_id; | ||
195 | u32 volnr; | ||
196 | u32 build_arch; | ||
197 | u64 rmem_size; | ||
198 | u8 mvdump; | ||
199 | u16 cpu_cnt; | ||
200 | u16 real_cpu_cnt; | ||
201 | u8 end_pad1[0x200-0x061]; | ||
202 | u64 mvdump_sign; | ||
203 | u64 mvdump_zipl_time; | ||
204 | u8 end_pad2[0x800-0x210]; | ||
205 | u32 lc_vec[512]; | ||
206 | } __attribute__((packed,__aligned__(16))); | ||
207 | |||
208 | static struct zcore_header zcore_header = { | ||
209 | .magic = DUMP_MAGIC, | ||
210 | .version = DUMP_VERSION, | ||
211 | .header_size = 4096, | ||
212 | .dump_level = 0, | ||
213 | .page_size = PAGE_SIZE, | ||
214 | .mem_start = 0, | ||
215 | .build_arch = DUMP_ARCH_S390X, | ||
216 | }; | ||
217 | |||
218 | /* | 89 | /* |
219 | * Copy lowcore info to buffer. Use map in order to copy only register parts. | 90 | * Copy memory from HSA to kernel memory (not reentrant): |
220 | * | 91 | * |
221 | * @buf: User buffer | 92 | * @dest: Kernel or user buffer where memory should be copied to |
222 | * @sa: Pointer to save area | 93 | * @src: Start address within HSA where data should be copied |
223 | * @sa_off: Offset in save area to copy | 94 | * @count: Size of buffer, which should be copied |
224 | * @len: Number of bytes to copy | ||
225 | */ | 95 | */ |
226 | static int copy_lc(void __user *buf, void *sa, int sa_off, int len) | 96 | int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count) |
227 | { | 97 | { |
228 | int i; | 98 | unsigned long offset, bytes; |
229 | char *lc_mask = (char*)&sys_info.lc_mask; | ||
230 | 99 | ||
231 | for (i = 0; i < len; i++) { | 100 | if (!hsa_available) |
232 | if (!lc_mask[i + sa_off]) | 101 | return -ENODATA; |
233 | continue; | 102 | |
234 | if (copy_to_user(buf + i, sa + sa_off + i, 1)) | 103 | while (count) { |
235 | return -EFAULT; | 104 | if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) { |
105 | TRACE("sclp_sdias_copy() failed\n"); | ||
106 | return -EIO; | ||
107 | } | ||
108 | offset = src % PAGE_SIZE; | ||
109 | bytes = min(PAGE_SIZE - offset, count); | ||
110 | memcpy(dest, hsa_buf + offset, bytes); | ||
111 | src += bytes; | ||
112 | dest += bytes; | ||
113 | count -= bytes; | ||
236 | } | 114 | } |
237 | return 0; | 115 | return 0; |
238 | } | 116 | } |
239 | 117 | ||
240 | /* | 118 | static int __init init_cpu_info(void) |
241 | * Copy lowcores info to memory, if necessary | ||
242 | * | ||
243 | * @buf: User buffer | ||
244 | * @addr: Start address of buffer in dump memory | ||
245 | * @count: Size of buffer | ||
246 | */ | ||
247 | static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) | ||
248 | { | 119 | { |
249 | unsigned long end; | 120 | struct save_area *sa; |
250 | int i; | ||
251 | |||
252 | if (count == 0) | ||
253 | return 0; | ||
254 | 121 | ||
255 | end = start + count; | 122 | /* get info for boot cpu from lowcore, stored in the HSA */ |
256 | for (i = 0; i < dump_save_areas.count; i++) { | 123 | sa = save_area_boot_cpu(); |
257 | unsigned long cp_start, cp_end; /* copy range */ | 124 | if (!sa) |
258 | unsigned long sa_start, sa_end; /* save area range */ | 125 | return -ENOMEM; |
259 | unsigned long prefix; | 126 | if (memcpy_hsa_kernel(hsa_buf, __LC_FPREGS_SAVE_AREA, 512) < 0) { |
260 | unsigned long sa_off, len, buf_off; | 127 | TRACE("could not copy from HSA\n"); |
261 | struct save_area *save_area = &dump_save_areas.areas[i]->sa; | 128 | return -EIO; |
262 | |||
263 | prefix = save_area->pref_reg; | ||
264 | sa_start = prefix + sys_info.sa_base; | ||
265 | sa_end = prefix + sys_info.sa_base + sys_info.sa_size; | ||
266 | |||
267 | if ((end < sa_start) || (start > sa_end)) | ||
268 | continue; | ||
269 | cp_start = max(start, sa_start); | ||
270 | cp_end = min(end, sa_end); | ||
271 | |||
272 | buf_off = cp_start - start; | ||
273 | sa_off = cp_start - sa_start; | ||
274 | len = cp_end - cp_start; | ||
275 | |||
276 | TRACE("copy_lc for: %lx\n", start); | ||
277 | if (copy_lc(buf + buf_off, save_area, sa_off, len)) | ||
278 | return -EFAULT; | ||
279 | } | 129 | } |
130 | save_area_add_regs(sa, hsa_buf); /* vx registers are saved in smp.c */ | ||
280 | return 0; | 131 | return 0; |
281 | } | 132 | } |
282 | 133 | ||
@@ -289,115 +140,6 @@ static void release_hsa(void) | |||
289 | hsa_available = 0; | 140 | hsa_available = 0; |
290 | } | 141 | } |
291 | 142 | ||
292 | /* | ||
293 | * Read routine for zcore character device | ||
294 | * First 4K are dump header | ||
295 | * Next 32MB are HSA Memory | ||
296 | * Rest is read from absolute Memory | ||
297 | */ | ||
298 | static ssize_t zcore_read(struct file *file, char __user *buf, size_t count, | ||
299 | loff_t *ppos) | ||
300 | { | ||
301 | unsigned long mem_start; /* Start address in memory */ | ||
302 | size_t mem_offs; /* Offset in dump memory */ | ||
303 | size_t hdr_count; /* Size of header part of output buffer */ | ||
304 | size_t size; | ||
305 | int rc; | ||
306 | |||
307 | mutex_lock(&zcore_mutex); | ||
308 | |||
309 | if (*ppos > (sys_info.mem_size + HEADER_SIZE)) { | ||
310 | rc = -EINVAL; | ||
311 | goto fail; | ||
312 | } | ||
313 | |||
314 | count = min(count, (size_t) (sys_info.mem_size + HEADER_SIZE - *ppos)); | ||
315 | |||
316 | /* Copy dump header */ | ||
317 | if (*ppos < HEADER_SIZE) { | ||
318 | size = min(count, (size_t) (HEADER_SIZE - *ppos)); | ||
319 | if (copy_to_user(buf, &zcore_header + *ppos, size)) { | ||
320 | rc = -EFAULT; | ||
321 | goto fail; | ||
322 | } | ||
323 | hdr_count = size; | ||
324 | mem_start = 0; | ||
325 | } else { | ||
326 | hdr_count = 0; | ||
327 | mem_start = *ppos - HEADER_SIZE; | ||
328 | } | ||
329 | |||
330 | mem_offs = 0; | ||
331 | |||
332 | /* Copy from HSA data */ | ||
333 | if (*ppos < sclp.hsa_size + HEADER_SIZE) { | ||
334 | size = min((count - hdr_count), | ||
335 | (size_t) (sclp.hsa_size - mem_start)); | ||
336 | rc = memcpy_hsa_user(buf + hdr_count, mem_start, size); | ||
337 | if (rc) | ||
338 | goto fail; | ||
339 | |||
340 | mem_offs += size; | ||
341 | } | ||
342 | |||
343 | /* Copy from real mem */ | ||
344 | size = count - mem_offs - hdr_count; | ||
345 | rc = copy_to_user_real(buf + hdr_count + mem_offs, | ||
346 | (void *) mem_start + mem_offs, size); | ||
347 | if (rc) | ||
348 | goto fail; | ||
349 | |||
350 | /* | ||
351 | * Since s390 dump analysis tools like lcrash or crash | ||
352 | * expect register sets in the prefix pages of the cpus, | ||
353 | * we copy them into the read buffer, if necessary. | ||
354 | * buf + hdr_count: Start of memory part of output buffer | ||
355 | * mem_start: Start memory address to copy from | ||
356 | * count - hdr_count: Size of memory area to copy | ||
357 | */ | ||
358 | if (zcore_add_lc(buf + hdr_count, mem_start, count - hdr_count)) { | ||
359 | rc = -EFAULT; | ||
360 | goto fail; | ||
361 | } | ||
362 | *ppos += count; | ||
363 | fail: | ||
364 | mutex_unlock(&zcore_mutex); | ||
365 | return (rc < 0) ? rc : count; | ||
366 | } | ||
367 | |||
368 | static int zcore_open(struct inode *inode, struct file *filp) | ||
369 | { | ||
370 | if (!hsa_available) | ||
371 | return -ENODATA; | ||
372 | else | ||
373 | return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; | ||
374 | } | ||
375 | |||
376 | static int zcore_release(struct inode *inode, struct file *filep) | ||
377 | { | ||
378 | if (hsa_available) | ||
379 | release_hsa(); | ||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static loff_t zcore_lseek(struct file *file, loff_t offset, int orig) | ||
384 | { | ||
385 | loff_t rc; | ||
386 | |||
387 | mutex_lock(&zcore_mutex); | ||
388 | rc = no_seek_end_llseek(file, offset, orig); | ||
389 | mutex_unlock(&zcore_mutex); | ||
390 | return rc; | ||
391 | } | ||
392 | |||
393 | static const struct file_operations zcore_fops = { | ||
394 | .owner = THIS_MODULE, | ||
395 | .llseek = zcore_lseek, | ||
396 | .read = zcore_read, | ||
397 | .open = zcore_open, | ||
398 | .release = zcore_release, | ||
399 | }; | ||
400 | |||
401 | static ssize_t zcore_memmap_read(struct file *filp, char __user *buf, | 143 | static ssize_t zcore_memmap_read(struct file *filp, char __user *buf, |
402 | size_t count, loff_t *ppos) | 144 | size_t count, loff_t *ppos) |
403 | { | 145 | { |
@@ -501,50 +243,6 @@ static const struct file_operations zcore_hsa_fops = { | |||
501 | .llseek = no_llseek, | 243 | .llseek = no_llseek, |
502 | }; | 244 | }; |
503 | 245 | ||
504 | static void __init set_lc_mask(struct save_area *map) | ||
505 | { | ||
506 | memset(&map->fp_regs, 0xff, sizeof(map->fp_regs)); | ||
507 | memset(&map->gp_regs, 0xff, sizeof(map->gp_regs)); | ||
508 | memset(&map->psw, 0xff, sizeof(map->psw)); | ||
509 | memset(&map->pref_reg, 0xff, sizeof(map->pref_reg)); | ||
510 | memset(&map->fp_ctrl_reg, 0xff, sizeof(map->fp_ctrl_reg)); | ||
511 | memset(&map->tod_reg, 0xff, sizeof(map->tod_reg)); | ||
512 | memset(&map->timer, 0xff, sizeof(map->timer)); | ||
513 | memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp)); | ||
514 | memset(&map->acc_regs, 0xff, sizeof(map->acc_regs)); | ||
515 | memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs)); | ||
516 | } | ||
517 | |||
518 | /* | ||
519 | * Initialize dump globals for a given architecture | ||
520 | */ | ||
521 | static int __init sys_info_init(enum arch_id arch, unsigned long mem_end) | ||
522 | { | ||
523 | int rc; | ||
524 | |||
525 | switch (arch) { | ||
526 | case ARCH_S390X: | ||
527 | pr_alert("DETECTED 'S390X (64 bit) OS'\n"); | ||
528 | break; | ||
529 | case ARCH_S390: | ||
530 | pr_alert("DETECTED 'S390 (32 bit) OS'\n"); | ||
531 | break; | ||
532 | default: | ||
533 | pr_alert("0x%x is an unknown architecture.\n",arch); | ||
534 | return -EINVAL; | ||
535 | } | ||
536 | sys_info.sa_base = SAVE_AREA_BASE; | ||
537 | sys_info.sa_size = sizeof(struct save_area); | ||
538 | sys_info.arch = arch; | ||
539 | set_lc_mask(&sys_info.lc_mask); | ||
540 | rc = init_cpu_info(arch); | ||
541 | if (rc) | ||
542 | return rc; | ||
543 | sys_info.mem_size = mem_end; | ||
544 | |||
545 | return 0; | ||
546 | } | ||
547 | |||
548 | static int __init check_sdias(void) | 246 | static int __init check_sdias(void) |
549 | { | 247 | { |
550 | if (!sclp.hsa_size) { | 248 | if (!sclp.hsa_size) { |
@@ -554,43 +252,6 @@ static int __init check_sdias(void) | |||
554 | return 0; | 252 | return 0; |
555 | } | 253 | } |
556 | 254 | ||
557 | static int __init get_mem_info(unsigned long *mem, unsigned long *end) | ||
558 | { | ||
559 | struct memblock_region *reg; | ||
560 | |||
561 | for_each_memblock(memory, reg) { | ||
562 | *mem += reg->size; | ||
563 | *end = max_t(unsigned long, *end, reg->base + reg->size); | ||
564 | } | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | static void __init zcore_header_init(int arch, struct zcore_header *hdr, | ||
569 | unsigned long mem_size) | ||
570 | { | ||
571 | u32 prefix; | ||
572 | int i; | ||
573 | |||
574 | if (arch == ARCH_S390X) | ||
575 | hdr->arch_id = DUMP_ARCH_S390X; | ||
576 | else | ||
577 | hdr->arch_id = DUMP_ARCH_S390; | ||
578 | hdr->mem_size = mem_size; | ||
579 | hdr->rmem_size = mem_size; | ||
580 | hdr->mem_end = sys_info.mem_size; | ||
581 | hdr->num_pages = mem_size / PAGE_SIZE; | ||
582 | hdr->tod = get_tod_clock(); | ||
583 | get_cpu_id(&hdr->cpu_id); | ||
584 | for (i = 0; i < dump_save_areas.count; i++) { | ||
585 | prefix = dump_save_areas.areas[i]->sa.pref_reg; | ||
586 | hdr->real_cpu_cnt++; | ||
587 | if (!prefix) | ||
588 | continue; | ||
589 | hdr->lc_vec[hdr->cpu_cnt] = prefix; | ||
590 | hdr->cpu_cnt++; | ||
591 | } | ||
592 | } | ||
593 | |||
594 | /* | 255 | /* |
595 | * Provide IPL parameter information block from either HSA or memory | 256 | * Provide IPL parameter information block from either HSA or memory |
596 | * for future reipl | 257 | * for future reipl |
@@ -623,11 +284,9 @@ static int __init zcore_reipl_init(void) | |||
623 | 284 | ||
624 | static int __init zcore_init(void) | 285 | static int __init zcore_init(void) |
625 | { | 286 | { |
626 | unsigned long mem_size, mem_end; | ||
627 | unsigned char arch; | 287 | unsigned char arch; |
628 | int rc; | 288 | int rc; |
629 | 289 | ||
630 | mem_size = mem_end = 0; | ||
631 | if (ipl_info.type != IPL_TYPE_FCP_DUMP) | 290 | if (ipl_info.type != IPL_TYPE_FCP_DUMP) |
632 | return -ENODATA; | 291 | return -ENODATA; |
633 | if (OLDMEM_BASE) | 292 | if (OLDMEM_BASE) |
@@ -661,14 +320,10 @@ static int __init zcore_init(void) | |||
661 | goto fail; | 320 | goto fail; |
662 | } | 321 | } |
663 | 322 | ||
664 | rc = get_mem_info(&mem_size, &mem_end); | 323 | pr_alert("DETECTED 'S390X (64 bit) OS'\n"); |
665 | if (rc) | 324 | rc = init_cpu_info(); |
666 | goto fail; | ||
667 | |||
668 | rc = sys_info_init(arch, mem_end); | ||
669 | if (rc) | 325 | if (rc) |
670 | goto fail; | 326 | goto fail; |
671 | zcore_header_init(arch, &zcore_header, mem_size); | ||
672 | 327 | ||
673 | rc = zcore_reipl_init(); | 328 | rc = zcore_reipl_init(); |
674 | if (rc) | 329 | if (rc) |
@@ -679,17 +334,11 @@ static int __init zcore_init(void) | |||
679 | rc = -ENOMEM; | 334 | rc = -ENOMEM; |
680 | goto fail; | 335 | goto fail; |
681 | } | 336 | } |
682 | zcore_file = debugfs_create_file("mem", S_IRUSR, zcore_dir, NULL, | ||
683 | &zcore_fops); | ||
684 | if (!zcore_file) { | ||
685 | rc = -ENOMEM; | ||
686 | goto fail_dir; | ||
687 | } | ||
688 | zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir, | 337 | zcore_memmap_file = debugfs_create_file("memmap", S_IRUSR, zcore_dir, |
689 | NULL, &zcore_memmap_fops); | 338 | NULL, &zcore_memmap_fops); |
690 | if (!zcore_memmap_file) { | 339 | if (!zcore_memmap_file) { |
691 | rc = -ENOMEM; | 340 | rc = -ENOMEM; |
692 | goto fail_file; | 341 | goto fail_dir; |
693 | } | 342 | } |
694 | zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir, | 343 | zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir, |
695 | NULL, &zcore_reipl_fops); | 344 | NULL, &zcore_reipl_fops); |
@@ -709,8 +358,6 @@ fail_reipl_file: | |||
709 | debugfs_remove(zcore_reipl_file); | 358 | debugfs_remove(zcore_reipl_file); |
710 | fail_memmap_file: | 359 | fail_memmap_file: |
711 | debugfs_remove(zcore_memmap_file); | 360 | debugfs_remove(zcore_memmap_file); |
712 | fail_file: | ||
713 | debugfs_remove(zcore_file); | ||
714 | fail_dir: | 361 | fail_dir: |
715 | debugfs_remove(zcore_dir); | 362 | debugfs_remove(zcore_dir); |
716 | fail: | 363 | fail: |
@@ -726,7 +373,6 @@ static void __exit zcore_exit(void) | |||
726 | debugfs_remove(zcore_hsa_file); | 373 | debugfs_remove(zcore_hsa_file); |
727 | debugfs_remove(zcore_reipl_file); | 374 | debugfs_remove(zcore_reipl_file); |
728 | debugfs_remove(zcore_memmap_file); | 375 | debugfs_remove(zcore_memmap_file); |
729 | debugfs_remove(zcore_file); | ||
730 | debugfs_remove(zcore_dir); | 376 | debugfs_remove(zcore_dir); |
731 | diag308(DIAG308_REL_HSA, NULL); | 377 | diag308(DIAG308_REL_HSA, NULL); |
732 | } | 378 | } |
diff --git a/drivers/s390/cio/Makefile b/drivers/s390/cio/Makefile index 8c4a386e97f6..3ab9aedeb84a 100644 --- a/drivers/s390/cio/Makefile +++ b/drivers/s390/cio/Makefile | |||
@@ -2,8 +2,11 @@ | |||
2 | # Makefile for the S/390 common i/o drivers | 2 | # Makefile for the S/390 common i/o drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | # The following is required for define_trace.h to find ./trace.h | ||
6 | CFLAGS_trace.o := -I$(src) | ||
7 | |||
5 | obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ | 8 | obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ |
6 | fcx.o itcw.o crw.o ccwreq.o | 9 | fcx.o itcw.o crw.o ccwreq.o trace.o ioasm.o |
7 | ccw_device-objs += device.o device_fsm.o device_ops.o | 10 | ccw_device-objs += device.o device_fsm.o device_ops.o |
8 | ccw_device-objs += device_id.o device_pgid.o device_status.o | 11 | ccw_device-objs += device_id.o device_pgid.o device_status.o |
9 | obj-y += ccw_device.o cmf.o | 12 | obj-y += ccw_device.o cmf.o |
diff --git a/drivers/s390/cio/airq.c b/drivers/s390/cio/airq.c index 56eb4ee4deba..99b5db469097 100644 --- a/drivers/s390/cio/airq.c +++ b/drivers/s390/cio/airq.c | |||
@@ -89,6 +89,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy) | |||
89 | 89 | ||
90 | set_cpu_flag(CIF_NOHZ_DELAY); | 90 | set_cpu_flag(CIF_NOHZ_DELAY); |
91 | tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; | 91 | tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; |
92 | trace_s390_cio_adapter_int(tpi_info); | ||
92 | head = &airq_lists[tpi_info->isc]; | 93 | head = &airq_lists[tpi_info->isc]; |
93 | rcu_read_lock(); | 94 | rcu_read_lock(); |
94 | hlist_for_each_entry_rcu(airq, head, list) | 95 | hlist_for_each_entry_rcu(airq, head, list) |
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c index 213159dec89e..b6f12c2bb114 100644 --- a/drivers/s390/cio/chsc_sch.c +++ b/drivers/s390/cio/chsc_sch.c | |||
@@ -133,7 +133,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch) | |||
133 | * since we don't have a way to clear the subchannel and | 133 | * since we don't have a way to clear the subchannel and |
134 | * cannot disable it with a request running. | 134 | * cannot disable it with a request running. |
135 | */ | 135 | */ |
136 | cc = stsch_err(sch->schid, &schib); | 136 | cc = stsch(sch->schid, &schib); |
137 | if (!cc && scsw_stctl(&schib.scsw)) | 137 | if (!cc && scsw_stctl(&schib.scsw)) |
138 | return -EAGAIN; | 138 | return -EAGAIN; |
139 | return 0; | 139 | return 0; |
@@ -185,8 +185,7 @@ static int __init chsc_init_dbfs(void) | |||
185 | debug_set_level(chsc_debug_log_id, 2); | 185 | debug_set_level(chsc_debug_log_id, 2); |
186 | return 0; | 186 | return 0; |
187 | out: | 187 | out: |
188 | if (chsc_debug_msg_id) | 188 | debug_unregister(chsc_debug_msg_id); |
189 | debug_unregister(chsc_debug_msg_id); | ||
190 | return -ENOMEM; | 189 | return -ENOMEM; |
191 | } | 190 | } |
192 | 191 | ||
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 690b8547e828..39a8ae54e9c1 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include "blacklist.h" | 41 | #include "blacklist.h" |
42 | #include "cio_debug.h" | 42 | #include "cio_debug.h" |
43 | #include "chp.h" | 43 | #include "chp.h" |
44 | #include "trace.h" | ||
44 | 45 | ||
45 | debug_info_t *cio_debug_msg_id; | 46 | debug_info_t *cio_debug_msg_id; |
46 | debug_info_t *cio_debug_trace_id; | 47 | debug_info_t *cio_debug_trace_id; |
@@ -76,12 +77,9 @@ static int __init cio_debug_init(void) | |||
76 | return 0; | 77 | return 0; |
77 | 78 | ||
78 | out_unregister: | 79 | out_unregister: |
79 | if (cio_debug_msg_id) | 80 | debug_unregister(cio_debug_msg_id); |
80 | debug_unregister(cio_debug_msg_id); | 81 | debug_unregister(cio_debug_trace_id); |
81 | if (cio_debug_trace_id) | 82 | debug_unregister(cio_debug_crw_id); |
82 | debug_unregister(cio_debug_trace_id); | ||
83 | if (cio_debug_crw_id) | ||
84 | debug_unregister(cio_debug_crw_id); | ||
85 | return -1; | 83 | return -1; |
86 | } | 84 | } |
87 | 85 | ||
@@ -348,18 +346,18 @@ int cio_commit_config(struct subchannel *sch) | |||
348 | struct schib schib; | 346 | struct schib schib; |
349 | struct irb irb; | 347 | struct irb irb; |
350 | 348 | ||
351 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 349 | if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
352 | return -ENODEV; | 350 | return -ENODEV; |
353 | 351 | ||
354 | for (retry = 0; retry < 5; retry++) { | 352 | for (retry = 0; retry < 5; retry++) { |
355 | /* copy desired changes to local schib */ | 353 | /* copy desired changes to local schib */ |
356 | cio_apply_config(sch, &schib); | 354 | cio_apply_config(sch, &schib); |
357 | ccode = msch_err(sch->schid, &schib); | 355 | ccode = msch(sch->schid, &schib); |
358 | if (ccode < 0) /* -EIO if msch gets a program check. */ | 356 | if (ccode < 0) /* -EIO if msch gets a program check. */ |
359 | return ccode; | 357 | return ccode; |
360 | switch (ccode) { | 358 | switch (ccode) { |
361 | case 0: /* successful */ | 359 | case 0: /* successful */ |
362 | if (stsch_err(sch->schid, &schib) || | 360 | if (stsch(sch->schid, &schib) || |
363 | !css_sch_is_valid(&schib)) | 361 | !css_sch_is_valid(&schib)) |
364 | return -ENODEV; | 362 | return -ENODEV; |
365 | if (cio_check_config(sch, &schib)) { | 363 | if (cio_check_config(sch, &schib)) { |
@@ -394,7 +392,7 @@ int cio_update_schib(struct subchannel *sch) | |||
394 | { | 392 | { |
395 | struct schib schib; | 393 | struct schib schib; |
396 | 394 | ||
397 | if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) | 395 | if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib)) |
398 | return -ENODEV; | 396 | return -ENODEV; |
399 | 397 | ||
400 | memcpy(&sch->schib, &schib, sizeof(schib)); | 398 | memcpy(&sch->schib, &schib, sizeof(schib)); |
@@ -503,7 +501,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) | |||
503 | * If stsch gets an exception, it means the current subchannel set | 501 | * If stsch gets an exception, it means the current subchannel set |
504 | * is not valid. | 502 | * is not valid. |
505 | */ | 503 | */ |
506 | ccode = stsch_err(schid, &sch->schib); | 504 | ccode = stsch(schid, &sch->schib); |
507 | if (ccode) { | 505 | if (ccode) { |
508 | err = (ccode == 3) ? -ENXIO : ccode; | 506 | err = (ccode == 3) ? -ENXIO : ccode; |
509 | goto out; | 507 | goto out; |
@@ -542,6 +540,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) | |||
542 | 540 | ||
543 | set_cpu_flag(CIF_NOHZ_DELAY); | 541 | set_cpu_flag(CIF_NOHZ_DELAY); |
544 | tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; | 542 | tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; |
543 | trace_s390_cio_interrupt(tpi_info); | ||
545 | irb = this_cpu_ptr(&cio_irb); | 544 | irb = this_cpu_ptr(&cio_irb); |
546 | sch = (struct subchannel *)(unsigned long) tpi_info->intparm; | 545 | sch = (struct subchannel *)(unsigned long) tpi_info->intparm; |
547 | if (!sch) { | 546 | if (!sch) { |
@@ -619,7 +618,7 @@ static int cio_test_for_console(struct subchannel_id schid, void *data) | |||
619 | { | 618 | { |
620 | struct schib schib; | 619 | struct schib schib; |
621 | 620 | ||
622 | if (stsch_err(schid, &schib) != 0) | 621 | if (stsch(schid, &schib) != 0) |
623 | return -ENXIO; | 622 | return -ENXIO; |
624 | if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && | 623 | if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && |
625 | (schib.pmcw.dev == console_devno)) { | 624 | (schib.pmcw.dev == console_devno)) { |
@@ -638,7 +637,7 @@ static int cio_get_console_sch_no(void) | |||
638 | if (console_irq != -1) { | 637 | if (console_irq != -1) { |
639 | /* VM provided us with the irq number of the console. */ | 638 | /* VM provided us with the irq number of the console. */ |
640 | schid.sch_no = console_irq; | 639 | schid.sch_no = console_irq; |
641 | if (stsch_err(schid, &schib) != 0 || | 640 | if (stsch(schid, &schib) != 0 || |
642 | (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv) | 641 | (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv) |
643 | return -1; | 642 | return -1; |
644 | console_devno = schib.pmcw.dev; | 643 | console_devno = schib.pmcw.dev; |
@@ -708,10 +707,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) | |||
708 | cc = 0; | 707 | cc = 0; |
709 | for (retry=0;retry<3;retry++) { | 708 | for (retry=0;retry<3;retry++) { |
710 | schib->pmcw.ena = 0; | 709 | schib->pmcw.ena = 0; |
711 | cc = msch_err(schid, schib); | 710 | cc = msch(schid, schib); |
712 | if (cc) | 711 | if (cc) |
713 | return (cc==3?-ENODEV:-EBUSY); | 712 | return (cc==3?-ENODEV:-EBUSY); |
714 | if (stsch_err(schid, schib) || !css_sch_is_valid(schib)) | 713 | if (stsch(schid, schib) || !css_sch_is_valid(schib)) |
715 | return -ENODEV; | 714 | return -ENODEV; |
716 | if (!schib->pmcw.ena) | 715 | if (!schib->pmcw.ena) |
717 | return 0; | 716 | return 0; |
@@ -758,7 +757,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr) | |||
758 | 757 | ||
759 | pgm_check_occured = 0; | 758 | pgm_check_occured = 0; |
760 | s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; | 759 | s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; |
761 | rc = stsch_err(schid, addr); | 760 | rc = stsch(schid, addr); |
762 | s390_base_pgm_handler_fn = NULL; | 761 | s390_base_pgm_handler_fn = NULL; |
763 | 762 | ||
764 | /* The program check handler could have changed pgm_check_occured. */ | 763 | /* The program check handler could have changed pgm_check_occured. */ |
@@ -795,7 +794,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data) | |||
795 | /* No default clear strategy */ | 794 | /* No default clear strategy */ |
796 | break; | 795 | break; |
797 | } | 796 | } |
798 | stsch_err(schid, &schib); | 797 | stsch(schid, &schib); |
799 | __disable_subchannel_easy(schid, &schib); | 798 | __disable_subchannel_easy(schid, &schib); |
800 | } | 799 | } |
801 | out: | 800 | out: |
@@ -917,7 +916,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) | |||
917 | { | 916 | { |
918 | struct subchannel_id uninitialized_var(schid); | 917 | struct subchannel_id uninitialized_var(schid); |
919 | 918 | ||
920 | s390_reset_system(NULL, NULL, NULL); | 919 | s390_reset_system(); |
921 | if (reipl_find_schid(devid, &schid) != 0) | 920 | if (reipl_find_schid(devid, &schid) != 0) |
922 | panic("IPL Device not found\n"); | 921 | panic("IPL Device not found\n"); |
923 | do_reipl_asm(*((__u32*)&schid)); | 922 | do_reipl_asm(*((__u32*)&schid)); |
@@ -943,7 +942,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) | |||
943 | if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS)) | 942 | if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS)) |
944 | return -ENODEV; | 943 | return -ENODEV; |
945 | } | 944 | } |
946 | if (stsch_err(schid, &schib)) | 945 | if (stsch(schid, &schib)) |
947 | return -ENODEV; | 946 | return -ENODEV; |
948 | if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) | 947 | if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) |
949 | return -ENODEV; | 948 | return -ENODEV; |
diff --git a/drivers/s390/cio/cio.h b/drivers/s390/cio/cio.h index a01376ae1749..93de0b46b489 100644 --- a/drivers/s390/cio/cio.h +++ b/drivers/s390/cio/cio.h | |||
@@ -45,6 +45,18 @@ struct pmcw { | |||
45 | /* ... in an operand exception. */ | 45 | /* ... in an operand exception. */ |
46 | } __attribute__ ((packed)); | 46 | } __attribute__ ((packed)); |
47 | 47 | ||
48 | /* I/O-Interruption Code as stored by TEST PENDING INTERRUPTION (TPI). */ | ||
49 | struct tpi_info { | ||
50 | struct subchannel_id schid; | ||
51 | u32 intparm; | ||
52 | u32 adapter_IO:1; | ||
53 | u32 :1; | ||
54 | u32 isc:3; | ||
55 | u32 :27; | ||
56 | u32 type:3; | ||
57 | u32 :12; | ||
58 | } __packed __aligned(4); | ||
59 | |||
48 | /* Target SCHIB configuration. */ | 60 | /* Target SCHIB configuration. */ |
49 | struct schib_config { | 61 | struct schib_config { |
50 | u64 mba; | 62 | u64 mba; |
diff --git a/drivers/s390/cio/crw.c b/drivers/s390/cio/crw.c index 0f8a25f98b10..3d3cd402b376 100644 --- a/drivers/s390/cio/crw.c +++ b/drivers/s390/cio/crw.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/wait.h> | 14 | #include <linux/wait.h> |
15 | #include <asm/crw.h> | 15 | #include <asm/crw.h> |
16 | #include <asm/ctl_reg.h> | 16 | #include <asm/ctl_reg.h> |
17 | #include "ioasm.h" | ||
17 | 18 | ||
18 | static DEFINE_MUTEX(crw_handler_mutex); | 19 | static DEFINE_MUTEX(crw_handler_mutex); |
19 | static crw_handler_t crw_handlers[NR_RSCS]; | 20 | static crw_handler_t crw_handlers[NR_RSCS]; |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 489e703dc82d..3d2b20ee613f 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -390,7 +390,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) | |||
390 | /* Will be done on the slow path. */ | 390 | /* Will be done on the slow path. */ |
391 | return -EAGAIN; | 391 | return -EAGAIN; |
392 | } | 392 | } |
393 | if (stsch_err(schid, &schib)) { | 393 | if (stsch(schid, &schib)) { |
394 | /* Subchannel is not provided. */ | 394 | /* Subchannel is not provided. */ |
395 | return -ENXIO; | 395 | return -ENXIO; |
396 | } | 396 | } |
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 92e03b42e661..8327d47e08b6 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c | |||
@@ -44,7 +44,7 @@ static void ccw_timeout_log(struct ccw_device *cdev) | |||
44 | sch = to_subchannel(cdev->dev.parent); | 44 | sch = to_subchannel(cdev->dev.parent); |
45 | private = to_io_private(sch); | 45 | private = to_io_private(sch); |
46 | orb = &private->orb; | 46 | orb = &private->orb; |
47 | cc = stsch_err(sch->schid, &schib); | 47 | cc = stsch(sch->schid, &schib); |
48 | 48 | ||
49 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " | 49 | printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " |
50 | "device information:\n", get_tod_clock()); | 50 | "device information:\n", get_tod_clock()); |
diff --git a/drivers/s390/cio/io_sch.h b/drivers/s390/cio/io_sch.h index b108f4a5c7dd..8975060af96c 100644 --- a/drivers/s390/cio/io_sch.h +++ b/drivers/s390/cio/io_sch.h | |||
@@ -169,49 +169,4 @@ struct ccw_device_private { | |||
169 | enum interruption_class int_class; | 169 | enum interruption_class int_class; |
170 | }; | 170 | }; |
171 | 171 | ||
172 | static inline int rsch(struct subchannel_id schid) | ||
173 | { | ||
174 | register struct subchannel_id reg1 asm("1") = schid; | ||
175 | int ccode; | ||
176 | |||
177 | asm volatile( | ||
178 | " rsch\n" | ||
179 | " ipm %0\n" | ||
180 | " srl %0,28" | ||
181 | : "=d" (ccode) | ||
182 | : "d" (reg1) | ||
183 | : "cc", "memory"); | ||
184 | return ccode; | ||
185 | } | ||
186 | |||
187 | static inline int hsch(struct subchannel_id schid) | ||
188 | { | ||
189 | register struct subchannel_id reg1 asm("1") = schid; | ||
190 | int ccode; | ||
191 | |||
192 | asm volatile( | ||
193 | " hsch\n" | ||
194 | " ipm %0\n" | ||
195 | " srl %0,28" | ||
196 | : "=d" (ccode) | ||
197 | : "d" (reg1) | ||
198 | : "cc"); | ||
199 | return ccode; | ||
200 | } | ||
201 | |||
202 | static inline int xsch(struct subchannel_id schid) | ||
203 | { | ||
204 | register struct subchannel_id reg1 asm("1") = schid; | ||
205 | int ccode; | ||
206 | |||
207 | asm volatile( | ||
208 | " .insn rre,0xb2760000,%1,0\n" | ||
209 | " ipm %0\n" | ||
210 | " srl %0,28" | ||
211 | : "=d" (ccode) | ||
212 | : "d" (reg1) | ||
213 | : "cc"); | ||
214 | return ccode; | ||
215 | } | ||
216 | |||
217 | #endif | 172 | #endif |
diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c new file mode 100644 index 000000000000..98984818618f --- /dev/null +++ b/drivers/s390/cio/ioasm.c | |||
@@ -0,0 +1,224 @@ | |||
1 | /* | ||
2 | * Channel subsystem I/O instructions. | ||
3 | */ | ||
4 | |||
5 | #include <linux/export.h> | ||
6 | |||
7 | #include <asm/chpid.h> | ||
8 | #include <asm/schid.h> | ||
9 | #include <asm/crw.h> | ||
10 | |||
11 | #include "ioasm.h" | ||
12 | #include "orb.h" | ||
13 | #include "cio.h" | ||
14 | |||
15 | int stsch(struct subchannel_id schid, struct schib *addr) | ||
16 | { | ||
17 | register struct subchannel_id reg1 asm ("1") = schid; | ||
18 | int ccode = -EIO; | ||
19 | |||
20 | asm volatile( | ||
21 | " stsch 0(%3)\n" | ||
22 | "0: ipm %0\n" | ||
23 | " srl %0,28\n" | ||
24 | "1:\n" | ||
25 | EX_TABLE(0b, 1b) | ||
26 | : "+d" (ccode), "=m" (*addr) | ||
27 | : "d" (reg1), "a" (addr) | ||
28 | : "cc"); | ||
29 | trace_s390_cio_stsch(schid, addr, ccode); | ||
30 | |||
31 | return ccode; | ||
32 | } | ||
33 | EXPORT_SYMBOL(stsch); | ||
34 | |||
35 | int msch(struct subchannel_id schid, struct schib *addr) | ||
36 | { | ||
37 | register struct subchannel_id reg1 asm ("1") = schid; | ||
38 | int ccode = -EIO; | ||
39 | |||
40 | asm volatile( | ||
41 | " msch 0(%2)\n" | ||
42 | "0: ipm %0\n" | ||
43 | " srl %0,28\n" | ||
44 | "1:\n" | ||
45 | EX_TABLE(0b, 1b) | ||
46 | : "+d" (ccode) | ||
47 | : "d" (reg1), "a" (addr), "m" (*addr) | ||
48 | : "cc"); | ||
49 | trace_s390_cio_msch(schid, addr, ccode); | ||
50 | |||
51 | return ccode; | ||
52 | } | ||
53 | |||
54 | int tsch(struct subchannel_id schid, struct irb *addr) | ||
55 | { | ||
56 | register struct subchannel_id reg1 asm ("1") = schid; | ||
57 | int ccode; | ||
58 | |||
59 | asm volatile( | ||
60 | " tsch 0(%3)\n" | ||
61 | " ipm %0\n" | ||
62 | " srl %0,28" | ||
63 | : "=d" (ccode), "=m" (*addr) | ||
64 | : "d" (reg1), "a" (addr) | ||
65 | : "cc"); | ||
66 | trace_s390_cio_tsch(schid, addr, ccode); | ||
67 | |||
68 | return ccode; | ||
69 | } | ||
70 | |||
71 | int ssch(struct subchannel_id schid, union orb *addr) | ||
72 | { | ||
73 | register struct subchannel_id reg1 asm("1") = schid; | ||
74 | int ccode = -EIO; | ||
75 | |||
76 | asm volatile( | ||
77 | " ssch 0(%2)\n" | ||
78 | "0: ipm %0\n" | ||
79 | " srl %0,28\n" | ||
80 | "1:\n" | ||
81 | EX_TABLE(0b, 1b) | ||
82 | : "+d" (ccode) | ||
83 | : "d" (reg1), "a" (addr), "m" (*addr) | ||
84 | : "cc", "memory"); | ||
85 | trace_s390_cio_ssch(schid, addr, ccode); | ||
86 | |||
87 | return ccode; | ||
88 | } | ||
89 | EXPORT_SYMBOL(ssch); | ||
90 | |||
91 | int csch(struct subchannel_id schid) | ||
92 | { | ||
93 | register struct subchannel_id reg1 asm("1") = schid; | ||
94 | int ccode; | ||
95 | |||
96 | asm volatile( | ||
97 | " csch\n" | ||
98 | " ipm %0\n" | ||
99 | " srl %0,28" | ||
100 | : "=d" (ccode) | ||
101 | : "d" (reg1) | ||
102 | : "cc"); | ||
103 | trace_s390_cio_csch(schid, ccode); | ||
104 | |||
105 | return ccode; | ||
106 | } | ||
107 | EXPORT_SYMBOL(csch); | ||
108 | |||
109 | int tpi(struct tpi_info *addr) | ||
110 | { | ||
111 | int ccode; | ||
112 | |||
113 | asm volatile( | ||
114 | " tpi 0(%2)\n" | ||
115 | " ipm %0\n" | ||
116 | " srl %0,28" | ||
117 | : "=d" (ccode), "=m" (*addr) | ||
118 | : "a" (addr) | ||
119 | : "cc"); | ||
120 | trace_s390_cio_tpi(addr, ccode); | ||
121 | |||
122 | return ccode; | ||
123 | } | ||
124 | |||
125 | int chsc(void *chsc_area) | ||
126 | { | ||
127 | typedef struct { char _[4096]; } addr_type; | ||
128 | int cc; | ||
129 | |||
130 | asm volatile( | ||
131 | " .insn rre,0xb25f0000,%2,0\n" | ||
132 | " ipm %0\n" | ||
133 | " srl %0,28\n" | ||
134 | : "=d" (cc), "=m" (*(addr_type *) chsc_area) | ||
135 | : "d" (chsc_area), "m" (*(addr_type *) chsc_area) | ||
136 | : "cc"); | ||
137 | trace_s390_cio_chsc(chsc_area, cc); | ||
138 | |||
139 | return cc; | ||
140 | } | ||
141 | EXPORT_SYMBOL(chsc); | ||
142 | |||
143 | int rchp(struct chp_id chpid) | ||
144 | { | ||
145 | register struct chp_id reg1 asm ("1") = chpid; | ||
146 | int ccode; | ||
147 | |||
148 | asm volatile( | ||
149 | " lr 1,%1\n" | ||
150 | " rchp\n" | ||
151 | " ipm %0\n" | ||
152 | " srl %0,28" | ||
153 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
154 | trace_s390_cio_rchp(chpid, ccode); | ||
155 | |||
156 | return ccode; | ||
157 | } | ||
158 | |||
159 | int rsch(struct subchannel_id schid) | ||
160 | { | ||
161 | register struct subchannel_id reg1 asm("1") = schid; | ||
162 | int ccode; | ||
163 | |||
164 | asm volatile( | ||
165 | " rsch\n" | ||
166 | " ipm %0\n" | ||
167 | " srl %0,28" | ||
168 | : "=d" (ccode) | ||
169 | : "d" (reg1) | ||
170 | : "cc", "memory"); | ||
171 | trace_s390_cio_rsch(schid, ccode); | ||
172 | |||
173 | return ccode; | ||
174 | } | ||
175 | |||
176 | int hsch(struct subchannel_id schid) | ||
177 | { | ||
178 | register struct subchannel_id reg1 asm("1") = schid; | ||
179 | int ccode; | ||
180 | |||
181 | asm volatile( | ||
182 | " hsch\n" | ||
183 | " ipm %0\n" | ||
184 | " srl %0,28" | ||
185 | : "=d" (ccode) | ||
186 | : "d" (reg1) | ||
187 | : "cc"); | ||
188 | trace_s390_cio_hsch(schid, ccode); | ||
189 | |||
190 | return ccode; | ||
191 | } | ||
192 | |||
193 | int xsch(struct subchannel_id schid) | ||
194 | { | ||
195 | register struct subchannel_id reg1 asm("1") = schid; | ||
196 | int ccode; | ||
197 | |||
198 | asm volatile( | ||
199 | " xsch\n" | ||
200 | " ipm %0\n" | ||
201 | " srl %0,28" | ||
202 | : "=d" (ccode) | ||
203 | : "d" (reg1) | ||
204 | : "cc"); | ||
205 | trace_s390_cio_xsch(schid, ccode); | ||
206 | |||
207 | return ccode; | ||
208 | } | ||
209 | |||
210 | int stcrw(struct crw *crw) | ||
211 | { | ||
212 | int ccode; | ||
213 | |||
214 | asm volatile( | ||
215 | " stcrw 0(%2)\n" | ||
216 | " ipm %0\n" | ||
217 | " srl %0,28\n" | ||
218 | : "=d" (ccode), "=m" (*crw) | ||
219 | : "a" (crw) | ||
220 | : "cc"); | ||
221 | trace_s390_cio_stcrw(crw, ccode); | ||
222 | |||
223 | return ccode; | ||
224 | } | ||
diff --git a/drivers/s390/cio/ioasm.h b/drivers/s390/cio/ioasm.h index 4d80fc67a06b..b31ee6bff1e4 100644 --- a/drivers/s390/cio/ioasm.h +++ b/drivers/s390/cio/ioasm.h | |||
@@ -3,165 +3,26 @@ | |||
3 | 3 | ||
4 | #include <asm/chpid.h> | 4 | #include <asm/chpid.h> |
5 | #include <asm/schid.h> | 5 | #include <asm/schid.h> |
6 | #include <asm/crw.h> | ||
6 | #include "orb.h" | 7 | #include "orb.h" |
7 | #include "cio.h" | 8 | #include "cio.h" |
9 | #include "trace.h" | ||
8 | 10 | ||
9 | /* | 11 | /* |
10 | * TPI info structure | 12 | * Some S390 specific IO instructions |
11 | */ | 13 | */ |
12 | struct tpi_info { | ||
13 | struct subchannel_id schid; | ||
14 | __u32 intparm; /* interruption parameter */ | ||
15 | __u32 adapter_IO : 1; | ||
16 | __u32 reserved2 : 1; | ||
17 | __u32 isc : 3; | ||
18 | __u32 reserved3 : 12; | ||
19 | __u32 int_type : 3; | ||
20 | __u32 reserved4 : 12; | ||
21 | } __attribute__ ((packed)); | ||
22 | 14 | ||
23 | 15 | int stsch(struct subchannel_id schid, struct schib *addr); | |
24 | /* | 16 | int msch(struct subchannel_id schid, struct schib *addr); |
25 | * Some S390 specific IO instructions as inline | 17 | int tsch(struct subchannel_id schid, struct irb *addr); |
26 | */ | 18 | int ssch(struct subchannel_id schid, union orb *addr); |
27 | 19 | int csch(struct subchannel_id schid); | |
28 | static inline int stsch_err(struct subchannel_id schid, struct schib *addr) | 20 | int tpi(struct tpi_info *addr); |
29 | { | 21 | int chsc(void *chsc_area); |
30 | register struct subchannel_id reg1 asm ("1") = schid; | 22 | int rchp(struct chp_id chpid); |
31 | int ccode = -EIO; | 23 | int rsch(struct subchannel_id schid); |
32 | 24 | int hsch(struct subchannel_id schid); | |
33 | asm volatile( | 25 | int xsch(struct subchannel_id schid); |
34 | " stsch 0(%3)\n" | 26 | int stcrw(struct crw *crw); |
35 | "0: ipm %0\n" | ||
36 | " srl %0,28\n" | ||
37 | "1:\n" | ||
38 | EX_TABLE(0b,1b) | ||
39 | : "+d" (ccode), "=m" (*addr) | ||
40 | : "d" (reg1), "a" (addr) | ||
41 | : "cc"); | ||
42 | return ccode; | ||
43 | } | ||
44 | |||
45 | static inline int msch(struct subchannel_id schid, struct schib *addr) | ||
46 | { | ||
47 | register struct subchannel_id reg1 asm ("1") = schid; | ||
48 | int ccode; | ||
49 | |||
50 | asm volatile( | ||
51 | " msch 0(%2)\n" | ||
52 | " ipm %0\n" | ||
53 | " srl %0,28" | ||
54 | : "=d" (ccode) | ||
55 | : "d" (reg1), "a" (addr), "m" (*addr) | ||
56 | : "cc"); | ||
57 | return ccode; | ||
58 | } | ||
59 | |||
60 | static inline int msch_err(struct subchannel_id schid, struct schib *addr) | ||
61 | { | ||
62 | register struct subchannel_id reg1 asm ("1") = schid; | ||
63 | int ccode = -EIO; | ||
64 | |||
65 | asm volatile( | ||
66 | " msch 0(%2)\n" | ||
67 | "0: ipm %0\n" | ||
68 | " srl %0,28\n" | ||
69 | "1:\n" | ||
70 | EX_TABLE(0b,1b) | ||
71 | : "+d" (ccode) | ||
72 | : "d" (reg1), "a" (addr), "m" (*addr) | ||
73 | : "cc"); | ||
74 | return ccode; | ||
75 | } | ||
76 | |||
77 | static inline int tsch(struct subchannel_id schid, struct irb *addr) | ||
78 | { | ||
79 | register struct subchannel_id reg1 asm ("1") = schid; | ||
80 | int ccode; | ||
81 | |||
82 | asm volatile( | ||
83 | " tsch 0(%3)\n" | ||
84 | " ipm %0\n" | ||
85 | " srl %0,28" | ||
86 | : "=d" (ccode), "=m" (*addr) | ||
87 | : "d" (reg1), "a" (addr) | ||
88 | : "cc"); | ||
89 | return ccode; | ||
90 | } | ||
91 | |||
92 | static inline int ssch(struct subchannel_id schid, union orb *addr) | ||
93 | { | ||
94 | register struct subchannel_id reg1 asm("1") = schid; | ||
95 | int ccode = -EIO; | ||
96 | |||
97 | asm volatile( | ||
98 | " ssch 0(%2)\n" | ||
99 | "0: ipm %0\n" | ||
100 | " srl %0,28\n" | ||
101 | "1:\n" | ||
102 | EX_TABLE(0b, 1b) | ||
103 | : "+d" (ccode) | ||
104 | : "d" (reg1), "a" (addr), "m" (*addr) | ||
105 | : "cc", "memory"); | ||
106 | return ccode; | ||
107 | } | ||
108 | |||
109 | static inline int csch(struct subchannel_id schid) | ||
110 | { | ||
111 | register struct subchannel_id reg1 asm("1") = schid; | ||
112 | int ccode; | ||
113 | |||
114 | asm volatile( | ||
115 | " csch\n" | ||
116 | " ipm %0\n" | ||
117 | " srl %0,28" | ||
118 | : "=d" (ccode) | ||
119 | : "d" (reg1) | ||
120 | : "cc"); | ||
121 | return ccode; | ||
122 | } | ||
123 | |||
124 | static inline int tpi(struct tpi_info *addr) | ||
125 | { | ||
126 | int ccode; | ||
127 | |||
128 | asm volatile( | ||
129 | " tpi 0(%2)\n" | ||
130 | " ipm %0\n" | ||
131 | " srl %0,28" | ||
132 | : "=d" (ccode), "=m" (*addr) | ||
133 | : "a" (addr) | ||
134 | : "cc"); | ||
135 | return ccode; | ||
136 | } | ||
137 | |||
138 | static inline int chsc(void *chsc_area) | ||
139 | { | ||
140 | typedef struct { char _[4096]; } addr_type; | ||
141 | int cc; | ||
142 | |||
143 | asm volatile( | ||
144 | " .insn rre,0xb25f0000,%2,0\n" | ||
145 | " ipm %0\n" | ||
146 | " srl %0,28\n" | ||
147 | : "=d" (cc), "=m" (*(addr_type *) chsc_area) | ||
148 | : "d" (chsc_area), "m" (*(addr_type *) chsc_area) | ||
149 | : "cc"); | ||
150 | return cc; | ||
151 | } | ||
152 | |||
153 | static inline int rchp(struct chp_id chpid) | ||
154 | { | ||
155 | register struct chp_id reg1 asm ("1") = chpid; | ||
156 | int ccode; | ||
157 | |||
158 | asm volatile( | ||
159 | " lr 1,%1\n" | ||
160 | " rchp\n" | ||
161 | " ipm %0\n" | ||
162 | " srl %0,28" | ||
163 | : "=d" (ccode) : "d" (reg1) : "cc"); | ||
164 | return ccode; | ||
165 | } | ||
166 | 27 | ||
167 | #endif | 28 | #endif |
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c index f1f3baa8e6e4..b6fc147f83d8 100644 --- a/drivers/s390/cio/qdio_debug.c +++ b/drivers/s390/cio/qdio_debug.c | |||
@@ -366,8 +366,6 @@ void qdio_debug_exit(void) | |||
366 | { | 366 | { |
367 | qdio_clear_dbf_list(); | 367 | qdio_clear_dbf_list(); |
368 | debugfs_remove(debugfs_root); | 368 | debugfs_remove(debugfs_root); |
369 | if (qdio_dbf_setup) | 369 | debug_unregister(qdio_dbf_setup); |
370 | debug_unregister(qdio_dbf_setup); | 370 | debug_unregister(qdio_dbf_error); |
371 | if (qdio_dbf_error) | ||
372 | debug_unregister(qdio_dbf_error); | ||
373 | } | 371 | } |
diff --git a/drivers/s390/cio/trace.c b/drivers/s390/cio/trace.c new file mode 100644 index 000000000000..8e706669ac8b --- /dev/null +++ b/drivers/s390/cio/trace.c | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Tracepoint definitions for s390_cio | ||
3 | * | ||
4 | * Copyright IBM Corp. 2015 | ||
5 | * Author(s): Peter Oberparleiter <oberpar@linux.vnet.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <asm/crw.h> | ||
9 | #include "cio.h" | ||
10 | |||
11 | #define CREATE_TRACE_POINTS | ||
12 | #include "trace.h" | ||
13 | |||
14 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_stsch); | ||
15 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_msch); | ||
16 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_tsch); | ||
17 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_tpi); | ||
18 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_ssch); | ||
19 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_csch); | ||
20 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_hsch); | ||
21 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_xsch); | ||
22 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_rsch); | ||
23 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_rchp); | ||
24 | EXPORT_TRACEPOINT_SYMBOL(s390_cio_chsc); | ||
diff --git a/drivers/s390/cio/trace.h b/drivers/s390/cio/trace.h new file mode 100644 index 000000000000..5b807a09f21b --- /dev/null +++ b/drivers/s390/cio/trace.h | |||
@@ -0,0 +1,363 @@ | |||
1 | /* | ||
2 | * Tracepoint header for the s390 Common I/O layer (CIO) | ||
3 | * | ||
4 | * Copyright IBM Corp. 2015 | ||
5 | * Author(s): Peter Oberparleiter <oberpar@linux.vnet.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #include <linux/kernel.h> | ||
9 | #include <asm/crw.h> | ||
10 | #include <uapi/asm/chpid.h> | ||
11 | #include <uapi/asm/schid.h> | ||
12 | #include "cio.h" | ||
13 | #include "orb.h" | ||
14 | |||
15 | #undef TRACE_SYSTEM | ||
16 | #define TRACE_SYSTEM s390 | ||
17 | |||
18 | #if !defined(_TRACE_S390_CIO_H) || defined(TRACE_HEADER_MULTI_READ) | ||
19 | #define _TRACE_S390_CIO_H | ||
20 | |||
21 | #include <linux/tracepoint.h> | ||
22 | |||
23 | DECLARE_EVENT_CLASS(s390_class_schib, | ||
24 | TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc), | ||
25 | TP_ARGS(schid, schib, cc), | ||
26 | TP_STRUCT__entry( | ||
27 | __field(u8, cssid) | ||
28 | __field(u8, ssid) | ||
29 | __field(u16, schno) | ||
30 | __field(u16, devno) | ||
31 | __field_struct(struct schib, schib) | ||
32 | __field(int, cc) | ||
33 | ), | ||
34 | TP_fast_assign( | ||
35 | __entry->cssid = schid.cssid; | ||
36 | __entry->ssid = schid.ssid; | ||
37 | __entry->schno = schid.sch_no; | ||
38 | __entry->devno = schib->pmcw.dev; | ||
39 | __entry->schib = *schib; | ||
40 | __entry->cc = cc; | ||
41 | ), | ||
42 | TP_printk("schid=%x.%x.%04x cc=%d ena=%d st=%d dnv=%d dev=%04x " | ||
43 | "lpm=0x%02x pnom=0x%02x lpum=0x%02x pim=0x%02x pam=0x%02x " | ||
44 | "pom=0x%02x chpids=%016llx", | ||
45 | __entry->cssid, __entry->ssid, __entry->schno, __entry->cc, | ||
46 | __entry->schib.pmcw.ena, __entry->schib.pmcw.st, | ||
47 | __entry->schib.pmcw.dnv, __entry->schib.pmcw.dev, | ||
48 | __entry->schib.pmcw.lpm, __entry->schib.pmcw.pnom, | ||
49 | __entry->schib.pmcw.lpum, __entry->schib.pmcw.pim, | ||
50 | __entry->schib.pmcw.pam, __entry->schib.pmcw.pom, | ||
51 | *((u64 *) __entry->schib.pmcw.chpid) | ||
52 | ) | ||
53 | ); | ||
54 | |||
55 | /** | ||
56 | * s390_cio_stsch - Store Subchannel instruction (STSCH) was performed | ||
57 | * @schid: Subchannel ID | ||
58 | * @schib: Subchannel-Information block | ||
59 | * @cc: Condition code | ||
60 | */ | ||
61 | DEFINE_EVENT(s390_class_schib, s390_cio_stsch, | ||
62 | TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc), | ||
63 | TP_ARGS(schid, schib, cc) | ||
64 | ); | ||
65 | |||
66 | /** | ||
67 | * s390_cio_msch - Modify Subchannel instruction (MSCH) was performed | ||
68 | * @schid: Subchannel ID | ||
69 | * @schib: Subchannel-Information block | ||
70 | * @cc: Condition code | ||
71 | */ | ||
72 | DEFINE_EVENT(s390_class_schib, s390_cio_msch, | ||
73 | TP_PROTO(struct subchannel_id schid, struct schib *schib, int cc), | ||
74 | TP_ARGS(schid, schib, cc) | ||
75 | ); | ||
76 | |||
77 | /** | ||
78 | * s390_cio_tsch - Test Subchannel instruction (TSCH) was performed | ||
79 | * @schid: Subchannel ID | ||
80 | * @irb: Interruption-Response Block | ||
81 | * @cc: Condition code | ||
82 | */ | ||
83 | TRACE_EVENT(s390_cio_tsch, | ||
84 | TP_PROTO(struct subchannel_id schid, struct irb *irb, int cc), | ||
85 | TP_ARGS(schid, irb, cc), | ||
86 | TP_STRUCT__entry( | ||
87 | __field(u8, cssid) | ||
88 | __field(u8, ssid) | ||
89 | __field(u16, schno) | ||
90 | __field_struct(struct irb, irb) | ||
91 | __field(int, cc) | ||
92 | ), | ||
93 | TP_fast_assign( | ||
94 | __entry->cssid = schid.cssid; | ||
95 | __entry->ssid = schid.ssid; | ||
96 | __entry->schno = schid.sch_no; | ||
97 | __entry->irb = *irb; | ||
98 | __entry->cc = cc; | ||
99 | ), | ||
100 | TP_printk("schid=%x.%x.%04x cc=%d dcc=%d pno=%d fctl=0x%x actl=0x%x " | ||
101 | "stctl=0x%x dstat=0x%x cstat=0x%x", | ||
102 | __entry->cssid, __entry->ssid, __entry->schno, __entry->cc, | ||
103 | scsw_cc(&__entry->irb.scsw), scsw_pno(&__entry->irb.scsw), | ||
104 | scsw_fctl(&__entry->irb.scsw), scsw_actl(&__entry->irb.scsw), | ||
105 | scsw_stctl(&__entry->irb.scsw), | ||
106 | scsw_dstat(&__entry->irb.scsw), scsw_cstat(&__entry->irb.scsw) | ||
107 | ) | ||
108 | ); | ||
109 | |||
110 | /** | ||
111 | * s390_cio_tpi - Test Pending Interruption instruction (TPI) was performed | ||
112 | * @addr: Address of the I/O interruption code or %NULL | ||
113 | * @cc: Condition code | ||
114 | */ | ||
115 | TRACE_EVENT(s390_cio_tpi, | ||
116 | TP_PROTO(struct tpi_info *addr, int cc), | ||
117 | TP_ARGS(addr, cc), | ||
118 | TP_STRUCT__entry( | ||
119 | __field(int, cc) | ||
120 | __field_struct(struct tpi_info, tpi_info) | ||
121 | __field(u8, cssid) | ||
122 | __field(u8, ssid) | ||
123 | __field(u16, schno) | ||
124 | ), | ||
125 | TP_fast_assign( | ||
126 | __entry->cc = cc; | ||
127 | if (cc != 0) | ||
128 | memset(&__entry->tpi_info, 0, sizeof(struct tpi_info)); | ||
129 | else if (addr) | ||
130 | __entry->tpi_info = *addr; | ||
131 | else { | ||
132 | memcpy(&__entry->tpi_info, &S390_lowcore.subchannel_id, | ||
133 | sizeof(struct tpi_info)); | ||
134 | } | ||
135 | __entry->cssid = __entry->tpi_info.schid.cssid; | ||
136 | __entry->ssid = __entry->tpi_info.schid.ssid; | ||
137 | __entry->schno = __entry->tpi_info.schid.sch_no; | ||
138 | ), | ||
139 | TP_printk("schid=%x.%x.%04x cc=%d a=%d isc=%d type=%d", | ||
140 | __entry->cssid, __entry->ssid, __entry->schno, __entry->cc, | ||
141 | __entry->tpi_info.adapter_IO, __entry->tpi_info.isc, | ||
142 | __entry->tpi_info.type | ||
143 | ) | ||
144 | ); | ||
145 | |||
146 | /** | ||
147 | * s390_cio_ssch - Start Subchannel instruction (SSCH) was performed | ||
148 | * @schid: Subchannel ID | ||
149 | * @orb: Operation-Request Block | ||
150 | * @cc: Condition code | ||
151 | */ | ||
152 | TRACE_EVENT(s390_cio_ssch, | ||
153 | TP_PROTO(struct subchannel_id schid, union orb *orb, int cc), | ||
154 | TP_ARGS(schid, orb, cc), | ||
155 | TP_STRUCT__entry( | ||
156 | __field(u8, cssid) | ||
157 | __field(u8, ssid) | ||
158 | __field(u16, schno) | ||
159 | __field_struct(union orb, orb) | ||
160 | __field(int, cc) | ||
161 | ), | ||
162 | TP_fast_assign( | ||
163 | __entry->cssid = schid.cssid; | ||
164 | __entry->ssid = schid.ssid; | ||
165 | __entry->schno = schid.sch_no; | ||
166 | __entry->orb = *orb; | ||
167 | __entry->cc = cc; | ||
168 | ), | ||
169 | TP_printk("schid=%x.%x.%04x cc=%d", __entry->cssid, __entry->ssid, | ||
170 | __entry->schno, __entry->cc | ||
171 | ) | ||
172 | ); | ||
173 | |||
174 | DECLARE_EVENT_CLASS(s390_class_schid, | ||
175 | TP_PROTO(struct subchannel_id schid, int cc), | ||
176 | TP_ARGS(schid, cc), | ||
177 | TP_STRUCT__entry( | ||
178 | __field(u8, cssid) | ||
179 | __field(u8, ssid) | ||
180 | __field(u16, schno) | ||
181 | __field(int, cc) | ||
182 | ), | ||
183 | TP_fast_assign( | ||
184 | __entry->cssid = schid.cssid; | ||
185 | __entry->ssid = schid.ssid; | ||
186 | __entry->schno = schid.sch_no; | ||
187 | __entry->cc = cc; | ||
188 | ), | ||
189 | TP_printk("schid=%x.%x.%04x cc=%d", __entry->cssid, __entry->ssid, | ||
190 | __entry->schno, __entry->cc | ||
191 | ) | ||
192 | ); | ||
193 | |||
194 | /** | ||
195 | * s390_cio_csch - Clear Subchannel instruction (CSCH) was performed | ||
196 | * @schid: Subchannel ID | ||
197 | * @cc: Condition code | ||
198 | */ | ||
199 | DEFINE_EVENT(s390_class_schid, s390_cio_csch, | ||
200 | TP_PROTO(struct subchannel_id schid, int cc), | ||
201 | TP_ARGS(schid, cc) | ||
202 | ); | ||
203 | |||
204 | /** | ||
205 | * s390_cio_hsch - Halt Subchannel instruction (HSCH) was performed | ||
206 | * @schid: Subchannel ID | ||
207 | * @cc: Condition code | ||
208 | */ | ||
209 | DEFINE_EVENT(s390_class_schid, s390_cio_hsch, | ||
210 | TP_PROTO(struct subchannel_id schid, int cc), | ||
211 | TP_ARGS(schid, cc) | ||
212 | ); | ||
213 | |||
214 | /** | ||
215 | * s390_cio_xsch - Cancel Subchannel instruction (XSCH) was performed | ||
216 | * @schid: Subchannel ID | ||
217 | * @cc: Condition code | ||
218 | */ | ||
219 | DEFINE_EVENT(s390_class_schid, s390_cio_xsch, | ||
220 | TP_PROTO(struct subchannel_id schid, int cc), | ||
221 | TP_ARGS(schid, cc) | ||
222 | ); | ||
223 | |||
224 | /** | ||
225 | * s390_cio_rsch - Resume Subchannel instruction (RSCH) was performed | ||
226 | * @schid: Subchannel ID | ||
227 | * @cc: Condition code | ||
228 | */ | ||
229 | DEFINE_EVENT(s390_class_schid, s390_cio_rsch, | ||
230 | TP_PROTO(struct subchannel_id schid, int cc), | ||
231 | TP_ARGS(schid, cc) | ||
232 | ); | ||
233 | |||
234 | /** | ||
235 | * s390_cio_rchp - Reset Channel Path (RCHP) instruction was performed | ||
236 | * @chpid: Channel-Path Identifier | ||
237 | * @cc: Condition code | ||
238 | */ | ||
239 | TRACE_EVENT(s390_cio_rchp, | ||
240 | TP_PROTO(struct chp_id chpid, int cc), | ||
241 | TP_ARGS(chpid, cc), | ||
242 | TP_STRUCT__entry( | ||
243 | __field(u8, cssid) | ||
244 | __field(u8, id) | ||
245 | __field(int, cc) | ||
246 | ), | ||
247 | TP_fast_assign( | ||
248 | __entry->cssid = chpid.cssid; | ||
249 | __entry->id = chpid.id; | ||
250 | __entry->cc = cc; | ||
251 | ), | ||
252 | TP_printk("chpid=%x.%02x cc=%d", __entry->cssid, __entry->id, | ||
253 | __entry->cc | ||
254 | ) | ||
255 | ); | ||
256 | |||
257 | #define CHSC_MAX_REQUEST_LEN 64 | ||
258 | #define CHSC_MAX_RESPONSE_LEN 64 | ||
259 | |||
260 | /** | ||
261 | * s390_cio_chsc - Channel Subsystem Call (CHSC) instruction was performed | ||
262 | * @chsc: CHSC block | ||
263 | * @cc: Condition code | ||
264 | */ | ||
265 | TRACE_EVENT(s390_cio_chsc, | ||
266 | TP_PROTO(struct chsc_header *chsc, int cc), | ||
267 | TP_ARGS(chsc, cc), | ||
268 | TP_STRUCT__entry( | ||
269 | __field(int, cc) | ||
270 | __field(u16, code) | ||
271 | __field(u16, rcode) | ||
272 | __array(u8, request, CHSC_MAX_REQUEST_LEN) | ||
273 | __array(u8, response, CHSC_MAX_RESPONSE_LEN) | ||
274 | ), | ||
275 | TP_fast_assign( | ||
276 | __entry->cc = cc; | ||
277 | __entry->code = chsc->code; | ||
278 | memcpy(&entry->request, chsc, | ||
279 | min_t(u16, chsc->length, CHSC_MAX_REQUEST_LEN)); | ||
280 | chsc = (struct chsc_header *) ((char *) chsc + chsc->length); | ||
281 | __entry->rcode = chsc->code; | ||
282 | memcpy(&entry->response, chsc, | ||
283 | min_t(u16, chsc->length, CHSC_MAX_RESPONSE_LEN)); | ||
284 | ), | ||
285 | TP_printk("code=0x%04x cc=%d rcode=0x%04x", __entry->code, | ||
286 | __entry->cc, __entry->rcode) | ||
287 | ); | ||
288 | |||
289 | /** | ||
290 | * s390_cio_interrupt - An I/O interrupt occurred | ||
291 | * @tpi_info: Address of the I/O interruption code | ||
292 | */ | ||
293 | TRACE_EVENT(s390_cio_interrupt, | ||
294 | TP_PROTO(struct tpi_info *tpi_info), | ||
295 | TP_ARGS(tpi_info), | ||
296 | TP_STRUCT__entry( | ||
297 | __field_struct(struct tpi_info, tpi_info) | ||
298 | __field(u8, cssid) | ||
299 | __field(u8, ssid) | ||
300 | __field(u16, schno) | ||
301 | ), | ||
302 | TP_fast_assign( | ||
303 | __entry->tpi_info = *tpi_info; | ||
304 | __entry->cssid = __entry->tpi_info.schid.cssid; | ||
305 | __entry->ssid = __entry->tpi_info.schid.ssid; | ||
306 | __entry->schno = __entry->tpi_info.schid.sch_no; | ||
307 | ), | ||
308 | TP_printk("schid=%x.%x.%04x isc=%d type=%d", | ||
309 | __entry->cssid, __entry->ssid, __entry->schno, | ||
310 | __entry->tpi_info.isc, __entry->tpi_info.type | ||
311 | ) | ||
312 | ); | ||
313 | |||
314 | /** | ||
315 | * s390_cio_adapter_int - An adapter interrupt occurred | ||
316 | * @tpi_info: Address of the I/O interruption code | ||
317 | */ | ||
318 | TRACE_EVENT(s390_cio_adapter_int, | ||
319 | TP_PROTO(struct tpi_info *tpi_info), | ||
320 | TP_ARGS(tpi_info), | ||
321 | TP_STRUCT__entry( | ||
322 | __field_struct(struct tpi_info, tpi_info) | ||
323 | ), | ||
324 | TP_fast_assign( | ||
325 | __entry->tpi_info = *tpi_info; | ||
326 | ), | ||
327 | TP_printk("isc=%d", __entry->tpi_info.isc) | ||
328 | ); | ||
329 | |||
330 | /** | ||
331 | * s390_cio_stcrw - Store Channel Report Word (STCRW) was performed | ||
332 | * @crw: Channel Report Word | ||
333 | * @cc: Condition code | ||
334 | */ | ||
335 | TRACE_EVENT(s390_cio_stcrw, | ||
336 | TP_PROTO(struct crw *crw, int cc), | ||
337 | TP_ARGS(crw, cc), | ||
338 | TP_STRUCT__entry( | ||
339 | __field_struct(struct crw, crw) | ||
340 | __field(int, cc) | ||
341 | ), | ||
342 | TP_fast_assign( | ||
343 | __entry->crw = *crw; | ||
344 | __entry->cc = cc; | ||
345 | ), | ||
346 | TP_printk("cc=%d slct=%d oflw=%d chn=%d rsc=%d anc=%d erc=0x%x " | ||
347 | "rsid=0x%x", | ||
348 | __entry->cc, __entry->crw.slct, __entry->crw.oflw, | ||
349 | __entry->crw.chn, __entry->crw.rsc, __entry->crw.anc, | ||
350 | __entry->crw.erc, __entry->crw.rsid | ||
351 | ) | ||
352 | ); | ||
353 | |||
354 | #endif /* _TRACE_S390_CIO_H */ | ||
355 | |||
356 | /* This part must be outside protection */ | ||
357 | #undef TRACE_INCLUDE_PATH | ||
358 | #define TRACE_INCLUDE_PATH . | ||
359 | |||
360 | #undef TRACE_INCLUDE_FILE | ||
361 | #define TRACE_INCLUDE_FILE trace | ||
362 | |||
363 | #include <trace/define_trace.h> | ||
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 9f8fa42c062c..5d3d04c040c2 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
@@ -1428,10 +1428,8 @@ int __init zcrypt_debug_init(void) | |||
1428 | void zcrypt_debug_exit(void) | 1428 | void zcrypt_debug_exit(void) |
1429 | { | 1429 | { |
1430 | debugfs_remove(debugfs_root); | 1430 | debugfs_remove(debugfs_root); |
1431 | if (zcrypt_dbf_common) | 1431 | debug_unregister(zcrypt_dbf_common); |
1432 | debug_unregister(zcrypt_dbf_common); | 1432 | debug_unregister(zcrypt_dbf_devices); |
1433 | if (zcrypt_dbf_devices) | ||
1434 | debug_unregister(zcrypt_dbf_devices); | ||
1435 | } | 1433 | } |
1436 | 1434 | ||
1437 | /** | 1435 | /** |
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 79e86613712f..26a48d76eb9d 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib | |||
@@ -104,8 +104,9 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ | |||
104 | orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ | 104 | orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ |
105 | $(ccflags-y) $(CFLAGS_$(basetarget).o) | 105 | $(ccflags-y) $(CFLAGS_$(basetarget).o) |
106 | _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) | 106 | _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) |
107 | _a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ | 107 | orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ |
108 | $(asflags-y) $(AFLAGS_$(basetarget).o) | 108 | $(asflags-y) $(AFLAGS_$(basetarget).o) |
109 | _a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags)) | ||
109 | _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) | 110 | _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) |
110 | 111 | ||
111 | # | 112 | # |