Commit cbd88cd4 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents 928b3f12 c2ab7282
...@@ -15,19 +15,15 @@ the s390-tools package) to make the device bootable. The operator of a Linux ...@@ -15,19 +15,15 @@ the s390-tools package) to make the device bootable. The operator of a Linux
system can then trigger a SCSI dump by booting the SCSI disk, where zfcpdump system can then trigger a SCSI dump by booting the SCSI disk, where zfcpdump
resides on. resides on.
The kernel part of zfcpdump is implemented as a debugfs file under "zcore/mem", The user space dump tool accesses the memory of the crashed system by means
which exports memory and registers of the crashed Linux in an s390 of the /proc/vmcore interface. This interface exports the crashed system's
standalone dump format. It can be used in the same way as e.g. /dev/mem. The memory and registers in ELF core dump format. To access the memory which has
dump format defines a 4K header followed by plain uncompressed memory. The been saved by the hardware SCLP requests will be created at the time the data
register sets are stored in the prefix pages of the respective CPUs. To build a is needed by /proc/vmcore. The tail part of the crashed systems memory which
dump enabled kernel with the zcore driver, the kernel config option has not been stashed by hardware can just be copied from real memory.
CONFIG_CRASH_DUMP has to be set. When reading from "zcore/mem", the part of
memory, which has been saved by hardware is read by the driver via the SCLP To build a dump enabled kernel the kernel config option CONFIG_CRASH_DUMP
hardware interface. The second part is just copied from the non overwritten real has to be set.
memory.
Since kernel version 3.12 also the /proc/vmcore file can also be used to access
the dump.
To get a valid zfcpdump kernel configuration use "make zfcpdump_defconfig". To get a valid zfcpdump kernel configuration use "make zfcpdump_defconfig".
......
...@@ -166,8 +166,7 @@ config SCHED_OMIT_FRAME_POINTER ...@@ -166,8 +166,7 @@ config SCHED_OMIT_FRAME_POINTER
config PGTABLE_LEVELS config PGTABLE_LEVELS
int int
default 4 if 64BIT default 4
default 2
source "init/Kconfig" source "init/Kconfig"
...@@ -390,9 +389,6 @@ config HOTPLUG_CPU ...@@ -390,9 +389,6 @@ config HOTPLUG_CPU
can be controlled through /sys/devices/system/cpu/cpu#. can be controlled through /sys/devices/system/cpu/cpu#.
Say N if you want to disable CPU hotplug. Say N if you want to disable CPU hotplug.
config SCHED_SMT
def_bool n
# Some NUMA nodes have memory ranges that span # Some NUMA nodes have memory ranges that span
# other nodes. Even though a pfn is valid and # other nodes. Even though a pfn is valid and
# between a node's start and end pfns, it may not # between a node's start and end pfns, it may not
...@@ -403,7 +399,7 @@ config NODES_SPAN_OTHER_NODES ...@@ -403,7 +399,7 @@ config NODES_SPAN_OTHER_NODES
config NUMA config NUMA
bool "NUMA support" bool "NUMA support"
depends on SMP && 64BIT && SCHED_TOPOLOGY depends on SMP && SCHED_TOPOLOGY
default n default n
help help
Enable NUMA support Enable NUMA support
...@@ -463,6 +459,9 @@ config EMU_SIZE ...@@ -463,6 +459,9 @@ config EMU_SIZE
endmenu endmenu
config SCHED_SMT
def_bool n
config SCHED_MC config SCHED_MC
def_bool n def_bool n
......
...@@ -106,6 +106,7 @@ drivers-y += drivers/s390/ ...@@ -106,6 +106,7 @@ drivers-y += drivers/s390/
drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/
boot := arch/s390/boot boot := arch/s390/boot
tools := arch/s390/tools
all: image bzImage all: image bzImage
...@@ -124,9 +125,17 @@ vdso_install: ...@@ -124,9 +125,17 @@ vdso_install:
archclean: archclean:
$(Q)$(MAKE) $(clean)=$(boot) $(Q)$(MAKE) $(clean)=$(boot)
$(Q)$(MAKE) $(clean)=$(tools)
archprepare:
$(Q)$(MAKE) $(build)=$(tools) include/generated/facilities.h
# Don't use tabs in echo arguments # Don't use tabs in echo arguments
define archhelp define archhelp
echo '* image - Kernel image for IPL ($(boot)/image)' echo '* image - Kernel image for IPL ($(boot)/image)'
echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)' echo '* bzImage - Compressed kernel image for IPL ($(boot)/bzImage)'
echo ' install - Install kernel using'
echo ' (your) ~/bin/$(INSTALLKERNEL) or'
echo ' (distribution) /sbin/$(INSTALLKERNEL) or'
echo ' install to $$(INSTALL_PATH)'
endef endef
...@@ -10,28 +10,35 @@ CONFIG_TASKSTATS=y ...@@ -10,28 +10,35 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y CONFIG_IKCONFIG_PROC=y
CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING=y
CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_CPUACCT=y
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y CONFIG_CGROUP_PERF=y
CONFIG_CFS_BANDWIDTH=y CONFIG_CFS_BANDWIDTH=y
CONFIG_RT_GROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y CONFIG_BPF_SYSCALL=y
CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_OPROFILE=m CONFIG_OPROFILE=m
CONFIG_KPROBES=y CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y CONFIG_JUMP_LABEL=y
CONFIG_STATIC_KEYS_SELFTEST=y
CONFIG_MODULES=y CONFIG_MODULES=y
CONFIG_MODULE_FORCE_LOAD=y CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
...@@ -64,7 +71,6 @@ CONFIG_HOTPLUG_PCI=y ...@@ -64,7 +71,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y CONFIG_CRASH_DUMP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y CONFIG_HIBERNATION=y
CONFIG_NET=y CONFIG_NET=y
...@@ -106,7 +112,6 @@ CONFIG_TCP_CONG_LP=m ...@@ -106,7 +112,6 @@ CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m CONFIG_INET6_ESP=m
...@@ -457,19 +462,9 @@ CONFIG_INFINIBAND=m ...@@ -457,19 +462,9 @@ CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m CONFIG_MLX4_INFINIBAND=m
CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_BALLOON=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_FS_SECURITY=y
CONFIG_JBD_DEBUG=y
CONFIG_JBD2_DEBUG=y CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_POSIX_ACL=y
...@@ -490,7 +485,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y ...@@ -490,7 +485,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V1=m CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m CONFIG_FUSE_FS=y
CONFIG_CUSE=m CONFIG_CUSE=m
CONFIG_FSCACHE=m CONFIG_FSCACHE=m
CONFIG_CACHEFILES=m CONFIG_CACHEFILES=m
...@@ -542,10 +537,11 @@ CONFIG_DLM=m ...@@ -542,10 +537,11 @@ CONFIG_DLM=m
CONFIG_PRINTK_TIME=y CONFIG_PRINTK_TIME=y
CONFIG_DYNAMIC_DEBUG=y CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_FRAME_WARN=1024 CONFIG_FRAME_WARN=1024
CONFIG_READABLE_ASM=y CONFIG_READABLE_ASM=y
CONFIG_UNUSED_SYMBOLS=y CONFIG_UNUSED_SYMBOLS=y
CONFIG_HEADERS_CHECK=y
CONFIG_DEBUG_SECTION_MISMATCH=y
CONFIG_MAGIC_SYSRQ=y CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_PAGEALLOC=y CONFIG_DEBUG_PAGEALLOC=y
CONFIG_DEBUG_OBJECTS=y CONFIG_DEBUG_OBJECTS=y
...@@ -588,6 +584,7 @@ CONFIG_FAILSLAB=y ...@@ -588,6 +584,7 @@ CONFIG_FAILSLAB=y
CONFIG_FAIL_PAGE_ALLOC=y CONFIG_FAIL_PAGE_ALLOC=y
CONFIG_FAIL_MAKE_REQUEST=y CONFIG_FAIL_MAKE_REQUEST=y
CONFIG_FAIL_IO_TIMEOUT=y CONFIG_FAIL_IO_TIMEOUT=y
CONFIG_FAIL_FUTEX=y
CONFIG_FAULT_INJECTION_DEBUG_FS=y CONFIG_FAULT_INJECTION_DEBUG_FS=y
CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y
CONFIG_LATENCYTOP=y CONFIG_LATENCYTOP=y
......
...@@ -10,21 +10,27 @@ CONFIG_TASKSTATS=y ...@@ -10,21 +10,27 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y CONFIG_IKCONFIG_PROC=y
CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING=y
CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_CPUACCT=y
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y CONFIG_CGROUP_PERF=y
CONFIG_BLK_CGROUP=y CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y CONFIG_BPF_SYSCALL=y
CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_OPROFILE=m CONFIG_OPROFILE=m
...@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y ...@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y CONFIG_CRASH_DUMP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y CONFIG_HIBERNATION=y
CONFIG_NET=y CONFIG_NET=y
...@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m ...@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m CONFIG_INET6_ESP=m
...@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m ...@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m CONFIG_MLX4_INFINIBAND=m
CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_BALLOON=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_FS_SECURITY=y
CONFIG_JBD_DEBUG=y
CONFIG_JBD2_DEBUG=y CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_POSIX_ACL=y
...@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y ...@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V1=m CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m CONFIG_FUSE_FS=y
CONFIG_CUSE=m CONFIG_CUSE=m
CONFIG_FSCACHE=m CONFIG_FSCACHE=m
CONFIG_CACHEFILES=m CONFIG_CACHEFILES=m
...@@ -550,6 +544,7 @@ CONFIG_NOTIFIER_ERROR_INJECTION=m ...@@ -550,6 +544,7 @@ CONFIG_NOTIFIER_ERROR_INJECTION=m
CONFIG_CPU_NOTIFIER_ERROR_INJECT=m CONFIG_CPU_NOTIFIER_ERROR_INJECT=m
CONFIG_PM_NOTIFIER_ERROR_INJECT=m CONFIG_PM_NOTIFIER_ERROR_INJECT=m
CONFIG_LATENCYTOP=y CONFIG_LATENCYTOP=y
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_BLK_DEV_IO_TRACE=y CONFIG_BLK_DEV_IO_TRACE=y
# CONFIG_KPROBE_EVENT is not set # CONFIG_KPROBE_EVENT is not set
CONFIG_LKDTM=m CONFIG_LKDTM=m
...@@ -557,6 +552,7 @@ CONFIG_RBTREE_TEST=m ...@@ -557,6 +552,7 @@ CONFIG_RBTREE_TEST=m
CONFIG_INTERVAL_TREE_TEST=m CONFIG_INTERVAL_TREE_TEST=m
CONFIG_PERCPU_TEST=m CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y CONFIG_ATOMIC64_SELFTEST=y
CONFIG_TEST_BPF=m
# CONFIG_STRICT_DEVMEM is not set # CONFIG_STRICT_DEVMEM is not set
CONFIG_S390_PTDUMP=y CONFIG_S390_PTDUMP=y
CONFIG_ENCRYPTED_KEYS=m CONFIG_ENCRYPTED_KEYS=m
......
...@@ -10,22 +10,28 @@ CONFIG_TASKSTATS=y ...@@ -10,22 +10,28 @@ CONFIG_TASKSTATS=y
CONFIG_TASK_DELAY_ACCT=y CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_RCU_FAST_NO_HZ=y
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y CONFIG_IKCONFIG_PROC=y
CONFIG_NUMA_BALANCING=y CONFIG_NUMA_BALANCING=y
# CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set # CONFIG_NUMA_BALANCING_DEFAULT_ENABLED is not set
CONFIG_CGROUP_FREEZER=y CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_CPUACCT=y
CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y CONFIG_CGROUP_PERF=y
CONFIG_BLK_CGROUP=y CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_SCHED_AUTOGROUP=y CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y CONFIG_BPF_SYSCALL=y
CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_OPROFILE=m CONFIG_OPROFILE=m
...@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y ...@@ -61,7 +67,6 @@ CONFIG_HOTPLUG_PCI=y
CONFIG_HOTPLUG_PCI_S390=y CONFIG_HOTPLUG_PCI_S390=y
CONFIG_CHSC_SCH=y CONFIG_CHSC_SCH=y
CONFIG_CRASH_DUMP=y CONFIG_CRASH_DUMP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
CONFIG_BINFMT_MISC=m CONFIG_BINFMT_MISC=m
CONFIG_HIBERNATION=y CONFIG_HIBERNATION=y
CONFIG_NET=y CONFIG_NET=y
...@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m ...@@ -103,7 +108,6 @@ CONFIG_TCP_CONG_LP=m
CONFIG_TCP_CONG_VENO=m CONFIG_TCP_CONG_VENO=m
CONFIG_TCP_CONG_YEAH=m CONFIG_TCP_CONG_YEAH=m
CONFIG_TCP_CONG_ILLINOIS=m CONFIG_TCP_CONG_ILLINOIS=m
CONFIG_IPV6=y
CONFIG_IPV6_ROUTER_PREF=y CONFIG_IPV6_ROUTER_PREF=y
CONFIG_INET6_AH=m CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m CONFIG_INET6_ESP=m
...@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m ...@@ -453,19 +457,9 @@ CONFIG_INFINIBAND=m
CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_MLX4_INFINIBAND=m CONFIG_MLX4_INFINIBAND=m
CONFIG_VIRTIO_BALLOON=m CONFIG_VIRTIO_BALLOON=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y
CONFIG_EXT2_FS_XATTR=y
CONFIG_EXT2_FS_POSIX_ACL=y
CONFIG_EXT2_FS_SECURITY=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT3_FS_POSIX_ACL=y
CONFIG_EXT3_FS_SECURITY=y
CONFIG_EXT4_FS=y CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y CONFIG_EXT4_FS_SECURITY=y
CONFIG_JBD_DEBUG=y
CONFIG_JBD2_DEBUG=y CONFIG_JBD2_DEBUG=y
CONFIG_JFS_FS=m CONFIG_JFS_FS=m
CONFIG_JFS_POSIX_ACL=y CONFIG_JFS_POSIX_ACL=y
...@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y ...@@ -485,7 +479,7 @@ CONFIG_QUOTA_NETLINK_INTERFACE=y
CONFIG_QFMT_V1=m CONFIG_QFMT_V1=m
CONFIG_QFMT_V2=m CONFIG_QFMT_V2=m
CONFIG_AUTOFS4_FS=m CONFIG_AUTOFS4_FS=m
CONFIG_FUSE_FS=m CONFIG_FUSE_FS=y
CONFIG_CUSE=m CONFIG_CUSE=m
CONFIG_FSCACHE=m CONFIG_FSCACHE=m
CONFIG_CACHEFILES=m CONFIG_CACHEFILES=m
...@@ -546,6 +540,7 @@ CONFIG_TIMER_STATS=y ...@@ -546,6 +540,7 @@ CONFIG_TIMER_STATS=y
CONFIG_RCU_TORTURE_TEST=m CONFIG_RCU_TORTURE_TEST=m
CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_CPU_STALL_TIMEOUT=60
CONFIG_LATENCYTOP=y CONFIG_LATENCYTOP=y
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
CONFIG_SCHED_TRACER=y CONFIG_SCHED_TRACER=y
CONFIG_FTRACE_SYSCALLS=y CONFIG_FTRACE_SYSCALLS=y
CONFIG_STACK_TRACER=y CONFIG_STACK_TRACER=y
...@@ -554,6 +549,7 @@ CONFIG_UPROBE_EVENT=y ...@@ -554,6 +549,7 @@ CONFIG_UPROBE_EVENT=y
CONFIG_LKDTM=m CONFIG_LKDTM=m
CONFIG_PERCPU_TEST=m CONFIG_PERCPU_TEST=m
CONFIG_ATOMIC64_SELFTEST=y CONFIG_ATOMIC64_SELFTEST=y
CONFIG_TEST_BPF=m
# CONFIG_STRICT_DEVMEM is not set # CONFIG_STRICT_DEVMEM is not set
CONFIG_S390_PTDUMP=y CONFIG_S390_PTDUMP=y
CONFIG_ENCRYPTED_KEYS=m CONFIG_ENCRYPTED_KEYS=m
......
...@@ -23,8 +23,6 @@ CONFIG_CRASH_DUMP=y ...@@ -23,8 +23,6 @@ CONFIG_CRASH_DUMP=y
# CONFIG_SECCOMP is not set # CONFIG_SECCOMP is not set
CONFIG_NET=y CONFIG_NET=y
# CONFIG_IUCV is not set # CONFIG_IUCV is not set
CONFIG_ATM=y
CONFIG_ATM_LANE=y
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS=y
# CONFIG_FIRMWARE_IN_KERNEL is not set # CONFIG_FIRMWARE_IN_KERNEL is not set
...@@ -54,14 +52,10 @@ CONFIG_RAW_DRIVER=y ...@@ -54,14 +52,10 @@ CONFIG_RAW_DRIVER=y
# CONFIG_S390_VMUR is not set # CONFIG_S390_VMUR is not set
# CONFIG_HID is not set # CONFIG_HID is not set
# CONFIG_IOMMU_SUPPORT is not set # CONFIG_IOMMU_SUPPORT is not set
CONFIG_EXT2_FS=y # CONFIG_DNOTIFY is not set
CONFIG_EXT3_FS=y
# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
# CONFIG_INOTIFY_USER is not set # CONFIG_INOTIFY_USER is not set
CONFIG_CONFIGFS_FS=y CONFIG_CONFIGFS_FS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_PRINTK_TIME=y CONFIG_PRINTK_TIME=y
CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_FS=y CONFIG_DEBUG_FS=y
......
...@@ -11,22 +11,31 @@ CONFIG_TASK_IO_ACCOUNTING=y ...@@ -11,22 +11,31 @@ CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_IKCONFIG=y CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y CONFIG_CGROUPS=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_CPUACCT=y
CONFIG_MEMCG=y CONFIG_MEMCG=y
CONFIG_MEMCG_SWAP=y CONFIG_MEMCG_SWAP=y
CONFIG_MEMCG_KMEM=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_SCHED=y CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y CONFIG_NAMESPACES=y
CONFIG_USER_NS=y
CONFIG_BLK_DEV_INITRD=y CONFIG_BLK_DEV_INITRD=y
CONFIG_EXPERT=y CONFIG_EXPERT=y
CONFIG_BPF_SYSCALL=y CONFIG_BPF_SYSCALL=y
CONFIG_USERFAULTFD=y
# CONFIG_COMPAT_BRK is not set # CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y CONFIG_PROFILING=y
CONFIG_OPROFILE=y CONFIG_OPROFILE=y
CONFIG_KPROBES=y CONFIG_KPROBES=y
CONFIG_JUMP_LABEL=y CONFIG_JUMP_LABEL=y
CONFIG_STATIC_KEYS_SELFTEST=y
CONFIG_MODULES=y CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y CONFIG_MODVERSIONS=y
...@@ -37,6 +46,7 @@ CONFIG_DEFAULT_DEADLINE=y ...@@ -37,6 +46,7 @@ CONFIG_DEFAULT_DEADLINE=y
CONFIG_LIVEPATCH=y CONFIG_LIVEPATCH=y
CONFIG_MARCH_Z196=y CONFIG_MARCH_Z196=y
CONFIG_NR_CPUS=256 CONFIG_NR_CPUS=256
CONFIG_NUMA=y
CONFIG_HZ_100=y CONFIG_HZ_100=y
CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y
...@@ -52,7 +62,6 @@ CONFIG_NET_KEY=y ...@@ -52,7 +62,6 @@ CONFIG_NET_KEY=y
CONFIG_INET=y CONFIG_INET=y
CONFIG_IP_MULTICAST=y CONFIG_IP_MULTICAST=y
# CONFIG_INET_LRO is not set # CONFIG_INET_LRO is not set
CONFIG_IPV6=y
CONFIG_L2TP=m CONFIG_L2TP=m
CONFIG_L2TP_DEBUGFS=m CONFIG_L2TP_DEBUGFS=m
CONFIG_VLAN_8021Q=y CONFIG_VLAN_8021Q=y
...@@ -89,10 +98,26 @@ CONFIG_BLK_DEV_SR_VENDOR=y ...@@ -89,10 +98,26 @@ CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_CHR_DEV_SG=y CONFIG_CHR_DEV_SG=y
CONFIG_SCSI_CONSTANTS=y CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_SCSI_FC_ATTRS=y CONFIG_SCSI_FC_ATTRS=y
CONFIG_ZFCP=y CONFIG_ZFCP=y
CONFIG_SCSI_VIRTIO=y CONFIG_SCSI_VIRTIO=y
CONFIG_MD=y
CONFIG_MD_LINEAR=m
CONFIG_MD_RAID0=m
CONFIG_MD_MULTIPATH=m
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=m
CONFIG_DM_SNAPSHOT=m
CONFIG_DM_MIRROR=m
CONFIG_DM_LOG_USERSPACE=m
CONFIG_DM_RAID=m
CONFIG_DM_ZERO=m
CONFIG_DM_MULTIPATH=m
CONFIG_DM_MULTIPATH_QL=m
CONFIG_DM_MULTIPATH_ST=m
CONFIG_DM_UEVENT=y
CONFIG_DM_VERITY=m
CONFIG_DM_SWITCH=m
CONFIG_NETDEVICES=y CONFIG_NETDEVICES=y
CONFIG_BONDING=m CONFIG_BONDING=m
CONFIG_DUMMY=m CONFIG_DUMMY=m
...@@ -137,7 +162,6 @@ CONFIG_DEBUG_PI_LIST=y ...@@ -137,7 +162,6 @@ CONFIG_DEBUG_PI_LIST=y
CONFIG_DEBUG_SG=y CONFIG_DEBUG_SG=y
CONFIG_DEBUG_NOTIFIERS=y CONFIG_DEBUG_NOTIFIERS=y
CONFIG_RCU_CPU_STALL_TIMEOUT=60 CONFIG_RCU_CPU_STALL_TIMEOUT=60
# CONFIG_RCU_CPU_STALL_INFO is not set
CONFIG_RCU_TRACE=y CONFIG_RCU_TRACE=y
CONFIG_LATENCYTOP=y CONFIG_LATENCYTOP=y
CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y CONFIG_DEBUG_STRICT_USER_COPY_CHECKS=y
......
...@@ -284,7 +284,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) ...@@ -284,7 +284,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
static inline int is_compat_task(void) static inline int is_compat_task(void)
{ {
return is_32bit_task(); return test_thread_flag(TIF_31BIT);
} }
static inline void __user *arch_compat_alloc_user_space(long len) static inline void __user *arch_compat_alloc_user_space(long len)
......
...@@ -52,18 +52,4 @@ void crw_wait_for_channel_report(void); ...@@ -52,18 +52,4 @@ void crw_wait_for_channel_report(void);
#define CRW_ERC_PERRI 0x07 /* perm. error, facility init */ #define CRW_ERC_PERRI 0x07 /* perm. error, facility init */
#define CRW_ERC_PMOD 0x08 /* installed parameters modified */ #define CRW_ERC_PMOD 0x08 /* installed parameters modified */
static inline int stcrw(struct crw *pcrw)
{
int ccode;
asm volatile(
" stcrw 0(%2)\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (ccode), "=m" (*pcrw)
: "a" (pcrw)
: "cc" );
return ccode;
}
#endif /* _ASM_S390_CRW_H */ #endif /* _ASM_S390_CRW_H */
...@@ -129,6 +129,7 @@ typedef s390_regs elf_gregset_t; ...@@ -129,6 +129,7 @@ typedef s390_regs elf_gregset_t;
typedef s390_fp_regs compat_elf_fpregset_t; typedef s390_fp_regs compat_elf_fpregset_t;
typedef s390_compat_regs compat_elf_gregset_t; typedef s390_compat_regs compat_elf_gregset_t;
#include <linux/compat.h>
#include <linux/sched.h> /* for task_struct */ #include <linux/sched.h> /* for task_struct */
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
...@@ -162,7 +163,7 @@ extern unsigned int vdso_enabled; ...@@ -162,7 +163,7 @@ extern unsigned int vdso_enabled;
the loader. We need to make sure that it is out of the way of the program the loader. We need to make sure that it is out of the way of the program
that it will "exec", and that there is sufficient room for the brk. 64-bit that it will "exec", and that there is sufficient room for the brk. 64-bit
tasks are aligned to 4GB. */ tasks are aligned to 4GB. */
#define ELF_ET_DYN_BASE (is_32bit_task() ? \ #define ELF_ET_DYN_BASE (is_compat_task() ? \
(STACK_TOP / 3 * 2) : \ (STACK_TOP / 3 * 2) : \
(STACK_TOP / 3 * 2) & ~((1UL << 32) - 1)) (STACK_TOP / 3 * 2) & ~((1UL << 32) - 1))
...@@ -219,9 +220,9 @@ do { \ ...@@ -219,9 +220,9 @@ do { \
* of up to 1GB. For 31-bit processes the virtual address space is limited, * of up to 1GB. For 31-bit processes the virtual address space is limited,
* use no alignment and limit the randomization to 8MB. * use no alignment and limit the randomization to 8MB.
*/ */
#define BRK_RND_MASK (is_32bit_task() ? 0x7ffUL : 0x3ffffUL) #define BRK_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ffffUL)
#define MMAP_RND_MASK (is_32bit_task() ? 0x7ffUL : 0x3ff80UL) #define MMAP_RND_MASK (is_compat_task() ? 0x7ffUL : 0x3ff80UL)
#define MMAP_ALIGN_MASK (is_32bit_task() ? 0 : 0x7fUL) #define MMAP_ALIGN_MASK (is_compat_task() ? 0 : 0x7fUL)
#define STACK_RND_MASK MMAP_RND_MASK #define STACK_RND_MASK MMAP_RND_MASK
#define ARCH_DLINFO \ #define ARCH_DLINFO \
...@@ -236,6 +237,4 @@ struct linux_binprm; ...@@ -236,6 +237,4 @@ struct linux_binprm;
#define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
int arch_setup_additional_pages(struct linux_binprm *, int); int arch_setup_additional_pages(struct linux_binprm *, int);
void *fill_cpu_elf_notes(void *ptr, struct save_area *sa, __vector128 *vxrs);
#endif #endif
/*
* Copyright IBM Corp. 2015
*/
#ifndef S390_GEN_FACILITIES_C
#error "This file can only be included by gen_facilities.c"
#endif
#include <linux/kconfig.h>
struct facility_def {
char *name;
int *bits;
};
static struct facility_def facility_defs[] = {
{
/*
* FACILITIES_ALS contains the list of facilities that are
* required to run a kernel that is compiled e.g. with
* -march=<machine>.
*/
.name = "FACILITIES_ALS",
.bits = (int[]){
#ifdef CONFIG_HAVE_MARCH_Z900_FEATURES
0, /* N3 instructions */
1, /* z/Arch mode installed */
#endif
#ifdef CONFIG_HAVE_MARCH_Z990_FEATURES
18, /* long displacement facility */
#endif
#ifdef CONFIG_HAVE_MARCH_Z9_109_FEATURES
7, /* stfle */
17, /* message security assist */
21, /* extended-immediate facility */
25, /* store clock fast */
#endif
#ifdef CONFIG_HAVE_MARCH_Z10_FEATURES
27, /* mvcos */
32, /* compare and swap and store */
33, /* compare and swap and store 2 */
34, /* general extension facility */
35, /* execute extensions */
#endif
#ifdef CONFIG_HAVE_MARCH_Z196_FEATURES
45, /* fast-BCR, etc. */
#endif
#ifdef CONFIG_HAVE_MARCH_ZEC12_FEATURES
49, /* misc-instruction-extensions */
52, /* interlocked facility 2 */
#endif
#ifdef CONFIG_HAVE_MARCH_Z13_FEATURES
53, /* load-and-zero-rightmost-byte, etc. */
#endif
-1 /* END */
}
},
};
...@@ -7,6 +7,10 @@ ...@@ -7,6 +7,10 @@
#ifndef __ASM_FACILITY_H #ifndef __ASM_FACILITY_H
#define __ASM_FACILITY_H #define __ASM_FACILITY_H
#include <generated/facilities.h>
#ifndef __ASSEMBLY__
#include <linux/string.h> #include <linux/string.h>
#include <linux/preempt.h> #include <linux/preempt.h>
#include <asm/lowcore.h> #include <asm/lowcore.h>
...@@ -30,6 +34,12 @@ static inline int __test_facility(unsigned long nr, void *facilities) ...@@ -30,6 +34,12 @@ static inline int __test_facility(unsigned long nr, void *facilities)
*/ */
static inline int test_facility(unsigned long nr) static inline int test_facility(unsigned long nr)
{ {
unsigned long facilities_als[] = { FACILITIES_ALS };
if (__builtin_constant_p(nr) && nr < sizeof(facilities_als) * 8) {
if (__test_facility(nr, &facilities_als))
return 1;
}
return __test_facility(nr, &S390_lowcore.stfle_fac_list); return __test_facility(nr, &S390_lowcore.stfle_fac_list);
} }
...@@ -44,10 +54,8 @@ static inline void stfle(u64 *stfle_fac_list, int size) ...@@ -44,10 +54,8 @@ static inline void stfle(u64 *stfle_fac_list, int size)
preempt_disable(); preempt_disable();
asm volatile( asm volatile(
" .insn s,0xb2b10000,0(0)\n" /* stfl */ " stfl 0(0)\n"
"0:\n" : "=m" (S390_lowcore.stfl_fac_list));
EX_TABLE(0b, 0b)
: "+m" (S390_lowcore.stfl_fac_list));
nr = 4; /* bytes stored by stfl */ nr = 4; /* bytes stored by stfl */
memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4); memcpy(stfle_fac_list, &S390_lowcore.stfl_fac_list, 4);
if (S390_lowcore.stfl_fac_list & 0x01000000) { if (S390_lowcore.stfl_fac_list & 0x01000000) {
...@@ -64,4 +72,5 @@ static inline void stfle(u64 *stfle_fac_list, int size) ...@@ -64,4 +72,5 @@ static inline void stfle(u64 *stfle_fac_list, int size)
preempt_enable(); preempt_enable();
} }
#endif /* __ASSEMBLY__ */
#endif /* __ASM_FACILITY_H */ #endif /* __ASM_FACILITY_H */
...@@ -12,21 +12,13 @@ ...@@ -12,21 +12,13 @@
#include <asm/ctl_reg.h> #include <asm/ctl_reg.h>
#include <asm/fpu/types.h> #include <asm/fpu/types.h>
static inline void save_vx_regs_safe(__vector128 *vxrs) static inline void save_vx_regs(__vector128 *vxrs)
{ {
unsigned long cr0, flags;
flags = arch_local_irq_save();
__ctl_store(cr0, 0, 0);
__ctl_set_bit(0, 17);
__ctl_set_bit(0, 18);
asm volatile( asm volatile(
" la 1,%0\n" " la 1,%0\n"
" .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */ " .word 0xe70f,0x1000,0x003e\n" /* vstm 0,15,0(1) */
" .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */ " .word 0xe70f,0x1100,0x0c3e\n" /* vstm 16,31,256(1) */
: "=Q" (*(struct vx_array *) vxrs) : : "1"); : "=Q" (*(struct vx_array *) vxrs) : : "1");
__ctl_load(cr0, 0, 0);
arch_local_irq_restore(flags);
} }
static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs) static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
......
...@@ -87,14 +87,12 @@ struct ipl_parameter_block { ...@@ -87,14 +87,12 @@ struct ipl_parameter_block {
* IPL validity flags * IPL validity flags
*/ */
extern u32 ipl_flags; extern u32 ipl_flags;
extern u32 dump_prefix_page;
struct dump_save_areas { struct save_area;
struct save_area_ext **areas; struct save_area * __init save_area_alloc(bool is_boot_cpu);
int count; struct save_area * __init save_area_boot_cpu(void);
}; void __init save_area_add_regs(struct save_area *, void *regs);
void __init save_area_add_vxrs(struct save_area *, __vector128 *vxrs);
extern struct dump_save_areas dump_save_areas;
extern void do_reipl(void); extern void do_reipl(void);
extern void do_halt(void); extern void do_halt(void);
...@@ -176,7 +174,7 @@ enum diag308_rc { ...@@ -176,7 +174,7 @@ enum diag308_rc {
extern int diag308(unsigned long subcode, void *addr); extern int diag308(unsigned long subcode, void *addr);
extern void diag308_reset(void); extern void diag308_reset(void);
extern void store_status(void); extern void store_status(void (*fn)(void *), void *data);
extern void lgr_info_log(void); extern void lgr_info_log(void);
#endif /* _ASM_S390_IPL_H */ #endif /* _ASM_S390_IPL_H */
...@@ -16,28 +16,7 @@ ...@@ -16,28 +16,7 @@
#define LC_ORDER 1 #define LC_ORDER 1
#define LC_PAGES 2 #define LC_PAGES 2
struct save_area { struct lowcore {
u64 fp_regs[16];
u64 gp_regs[16];
u8 psw[16];
u8 pad1[8];
u32 pref_reg;
u32 fp_ctrl_reg;
u8 pad2[4];
u32 tod_reg;
u64 timer;
u64 clk_cmp;
u8 pad3[8];
u32 acc_regs[16];
u64 ctrl_regs[16];
} __packed;
struct save_area_ext {
struct save_area sa;
__vector128 vx_regs[32];
};
struct _lowcore {
__u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */ __u8 pad_0x0000[0x0014-0x0000]; /* 0x0000 */
__u32 ipl_parmblock_ptr; /* 0x0014 */ __u32 ipl_parmblock_ptr; /* 0x0014 */
__u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */ __u8 pad_0x0018[0x0080-0x0018]; /* 0x0018 */
...@@ -204,9 +183,9 @@ struct _lowcore { ...@@ -204,9 +183,9 @@ struct _lowcore {
__u8 vector_save_area[1024]; /* 0x1c00 */ __u8 vector_save_area[1024]; /* 0x1c00 */
} __packed; } __packed;
#define S390_lowcore (*((struct _lowcore *) 0)) #define S390_lowcore (*((struct lowcore *) 0))
extern struct _lowcore *lowcore_ptr[]; extern struct lowcore *lowcore_ptr[];
static inline void set_prefix(__u32 address) static inline void set_prefix(__u32 address)
{ {
......
...@@ -38,7 +38,7 @@ u32 os_info_csum(struct os_info *os_info); ...@@ -38,7 +38,7 @@ u32 os_info_csum(struct os_info *os_info);
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
void *os_info_old_entry(int nr, unsigned long *size); void *os_info_old_entry(int nr, unsigned long *size);
int copy_from_oldmem(void *dest, void *src, size_t count); int copy_oldmem_kernel(void *dst, void *src, size_t count);
#else #else
static inline void *os_info_old_entry(int nr, unsigned long *size) static inline void *os_info_old_entry(int nr, unsigned long *size)
{ {
......
...@@ -23,6 +23,8 @@ enum zpci_ioat_dtype { ...@@ -23,6 +23,8 @@ enum zpci_ioat_dtype {
#define ZPCI_IOTA_FS_2G 2 #define ZPCI_IOTA_FS_2G 2
#define ZPCI_KEY (PAGE_DEFAULT_KEY << 5) #define ZPCI_KEY (PAGE_DEFAULT_KEY << 5)
#define ZPCI_TABLE_SIZE_RT (1UL << 42)
#define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST) #define ZPCI_IOTA_STO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_ST)
#define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT) #define ZPCI_IOTA_RTTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RT)
#define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS) #define ZPCI_IOTA_RSTO_FLAG (ZPCI_IOTA_IOT_ENABLED | ZPCI_KEY | ZPCI_IOTA_DT_RS)
......
...@@ -18,12 +18,14 @@ ...@@ -18,12 +18,14 @@
#define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */ #define CIF_NOHZ_DELAY 2 /* delay HZ disable for a tick */
#define CIF_FPU 3 /* restore FPU registers */ #define CIF_FPU 3 /* restore FPU registers */
#define CIF_IGNORE_IRQ 4 /* ignore interrupt (for udelay) */ #define CIF_IGNORE_IRQ 4 /* ignore interrupt (for udelay) */
#define CIF_ENABLED_WAIT 5 /* in enabled wait state */
#define _CIF_MCCK_PENDING _BITUL(CIF_MCCK_PENDING) #define _CIF_MCCK_PENDING _BITUL(CIF_MCCK_PENDING)
#define _CIF_ASCE _BITUL(CIF_ASCE) #define _CIF_ASCE _BITUL(CIF_ASCE)
#define _CIF_NOHZ_DELAY _BITUL(CIF_NOHZ_DELAY) #define _CIF_NOHZ_DELAY _BITUL(CIF_NOHZ_DELAY)
#define _CIF_FPU _BITUL(CIF_FPU) #define _CIF_FPU _BITUL(CIF_FPU)
#define _CIF_IGNORE_IRQ _BITUL(CIF_IGNORE_IRQ) #define _CIF_IGNORE_IRQ _BITUL(CIF_IGNORE_IRQ)
#define _CIF_ENABLED_WAIT _BITUL(CIF_ENABLED_WAIT)
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
...@@ -52,6 +54,16 @@ static inline int test_cpu_flag(int flag) ...@@ -52,6 +54,16 @@ static inline int test_cpu_flag(int flag)
return !!(S390_lowcore.cpu_flags & (1UL << flag)); return !!(S390_lowcore.cpu_flags & (1UL << flag));
} }
/*
* Test CIF flag of another CPU. The caller needs to ensure that
* CPU hotplug can not happen, e.g. by disabling preemption.
*/
static inline int test_cpu_flag_of(int flag, int cpu)
{
struct lowcore *lc = lowcore_ptr[cpu];
return !!(lc->cpu_flags & (1UL << flag));
}
#define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY) #define arch_needs_cpu() test_cpu_flag(CIF_NOHZ_DELAY)
/* /*
......
...@@ -24,25 +24,25 @@ ...@@ -24,25 +24,25 @@
PSW_MASK_PSTATE | PSW_ASC_PRIMARY) PSW_MASK_PSTATE | PSW_ASC_PRIMARY)
struct psw_bits { struct psw_bits {
unsigned long long : 1; unsigned long : 1;
unsigned long long r : 1; /* PER-Mask */ unsigned long r : 1; /* PER-Mask */
unsigned long long : 3; unsigned long : 3;
unsigned long long t : 1; /* DAT Mode */ unsigned long t : 1; /* DAT Mode */
unsigned long long i : 1; /* Input/Output Mask */ unsigned long i : 1; /* Input/Output Mask */
unsigned long long e : 1; /* External Mask */ unsigned long e : 1; /* External Mask */
unsigned long long key : 4; /* PSW Key */ unsigned long key : 4; /* PSW Key */
unsigned long long : 1; unsigned long : 1;
unsigned long long m : 1; /* Machine-Check Mask */ unsigned long m : 1; /* Machine-Check Mask */
unsigned long long w : 1; /* Wait State */ unsigned long w : 1; /* Wait State */
unsigned long long p : 1; /* Problem State */ unsigned long p : 1; /* Problem State */
unsigned long long as : 2; /* Address Space Control */ unsigned long as : 2; /* Address Space Control */
unsigned long long cc : 2; /* Condition Code */ unsigned long cc : 2; /* Condition Code */
unsigned long long pm : 4; /* Program Mask */ unsigned long pm : 4; /* Program Mask */
unsigned long long ri : 1; /* Runtime Instrumentation */ unsigned long ri : 1; /* Runtime Instrumentation */
unsigned long long : 6; unsigned long : 6;
unsigned long long eaba : 2; /* Addressing Mode */ unsigned long eaba : 2; /* Addressing Mode */
unsigned long long : 31; unsigned long : 31;
unsigned long long ia : 64;/* Instruction Address */ unsigned long ia : 64; /* Instruction Address */
}; };
enum { enum {
......
...@@ -15,6 +15,5 @@ struct reset_call { ...@@ -15,6 +15,5 @@ struct reset_call {
extern void register_reset_call(struct reset_call *reset); extern void register_reset_call(struct reset_call *reset);
extern void unregister_reset_call(struct reset_call *reset); extern void unregister_reset_call(struct reset_call *reset);
extern void s390_reset_system(void (*fn_pre)(void), extern void s390_reset_system(void);
void (*fn_post)(void *), void *data);
#endif /* _ASM_S390_RESET_H */ #endif /* _ASM_S390_RESET_H */
...@@ -63,12 +63,12 @@ struct sclp_info { ...@@ -63,12 +63,12 @@ struct sclp_info {
unsigned int mtid; unsigned int mtid;
unsigned int mtid_cp; unsigned int mtid_cp;
unsigned int mtid_prev; unsigned int mtid_prev;
unsigned long long rzm; unsigned long rzm;
unsigned long long rnmax; unsigned long rnmax;
unsigned long long hamax; unsigned long hamax;
unsigned int max_cores; unsigned int max_cores;
unsigned long hsa_size; unsigned long hsa_size;
unsigned long long facilities; unsigned long facilities;
}; };
extern struct sclp_info sclp; extern struct sclp_info sclp;
...@@ -83,8 +83,9 @@ int sclp_chp_read_info(struct sclp_chp_info *info); ...@@ -83,8 +83,9 @@ int sclp_chp_read_info(struct sclp_chp_info *info);
void sclp_get_ipl_info(struct sclp_ipl_info *info); void sclp_get_ipl_info(struct sclp_ipl_info *info);
int sclp_pci_configure(u32 fid); int sclp_pci_configure(u32 fid);
int sclp_pci_deconfigure(u32 fid); int sclp_pci_deconfigure(u32 fid);
int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode); int memcpy_hsa_kernel(void *dest, unsigned long src, size_t count);
int memcpy_hsa_user(void __user *dest, unsigned long src, size_t count);
void sclp_early_detect(void); void sclp_early_detect(void);
int _sclp_print_early(const char *); void _sclp_print_early(const char *);
#endif /* _ASM_S390_SCLP_H */ #endif /* _ASM_S390_SCLP_H */
...@@ -12,27 +12,24 @@ ...@@ -12,27 +12,24 @@
#define PARMAREA 0x10400 #define PARMAREA 0x10400
/* /*
* Machine features detected in head.S * Machine features detected in early.c
*/ */
#define MACHINE_FLAG_VM _BITUL(0) #define MACHINE_FLAG_VM _BITUL(0)
#define MACHINE_FLAG_IEEE _BITUL(1) #define MACHINE_FLAG_KVM _BITUL(1)
#define MACHINE_FLAG_CSP _BITUL(2) #define MACHINE_FLAG_LPAR _BITUL(2)
#define MACHINE_FLAG_MVPG _BITUL(3) #define MACHINE_FLAG_DIAG9C _BITUL(3)
#define MACHINE_FLAG_DIAG44 _BITUL(4) #define MACHINE_FLAG_ESOP _BITUL(4)
#define MACHINE_FLAG_IDTE _BITUL(5) #define MACHINE_FLAG_IDTE _BITUL(5)
#define MACHINE_FLAG_DIAG9C _BITUL(6) #define MACHINE_FLAG_DIAG44 _BITUL(6)
#define MACHINE_FLAG_KVM _BITUL(8) #define MACHINE_FLAG_EDAT1 _BITUL(7)
#define MACHINE_FLAG_ESOP _BITUL(9) #define MACHINE_FLAG_EDAT2 _BITUL(8)
#define MACHINE_FLAG_EDAT1 _BITUL(10) #define MACHINE_FLAG_LPP _BITUL(9)
#define MACHINE_FLAG_EDAT2 _BITUL(11) #define MACHINE_FLAG_TOPOLOGY _BITUL(10)
#define MACHINE_FLAG_LPAR _BITUL(12) #define MACHINE_FLAG_TE _BITUL(11)
#define MACHINE_FLAG_LPP _BITUL(13) #define MACHINE_FLAG_TLB_LC _BITUL(12)
#define MACHINE_FLAG_TOPOLOGY _BITUL(14) #define MACHINE_FLAG_VX _BITUL(13)
#define MACHINE_FLAG_TE _BITUL(15) #define MACHINE_FLAG_CAD _BITUL(14)
#define MACHINE_FLAG_TLB_LC _BITUL(17)
#define MACHINE_FLAG_VX _BITUL(18)
#define MACHINE_FLAG_CAD _BITUL(19)
#define LPP_MAGIC _BITUL(31) #define LPP_MAGIC _BITUL(31)
#define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL) #define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL)
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
extern struct mutex smp_cpu_state_mutex; extern struct mutex smp_cpu_state_mutex;
extern unsigned int smp_cpu_mt_shift; extern unsigned int smp_cpu_mt_shift;
extern unsigned int smp_cpu_mtid; extern unsigned int smp_cpu_mtid;
extern __vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS];
extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
...@@ -55,7 +56,6 @@ static inline int smp_store_status(int cpu) { return 0; } ...@@ -55,7 +56,6 @@ static inline int smp_store_status(int cpu) { return 0; }
static inline int smp_vcpu_scheduled(int cpu) { return 1; } static inline int smp_vcpu_scheduled(int cpu) { return 1; }
static inline void smp_yield_cpu(int cpu) { } static inline void smp_yield_cpu(int cpu) { }
static inline void smp_fill_possible_mask(void) { } static inline void smp_fill_possible_mask(void) { }
static inline void smp_save_dump_cpus(void) { }
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
......
...@@ -56,7 +56,12 @@ struct sysinfo_1_2_2 { ...@@ -56,7 +56,12 @@ struct sysinfo_1_2_2 {
char format; char format;
char reserved_0[1]; char reserved_0[1];
unsigned short acc_offset; unsigned short acc_offset;
char reserved_1[20]; unsigned char mt_installed :1;
unsigned char :2;
unsigned char mt_stid :5;
unsigned char :3;
unsigned char mt_gtid :5;
char reserved_1[18];
unsigned int nominal_cap; unsigned int nominal_cap;
unsigned int secondary_cap; unsigned int secondary_cap;
unsigned int capability; unsigned int capability;
...@@ -92,9 +97,13 @@ struct sysinfo_2_2_2 { ...@@ -92,9 +97,13 @@ struct sysinfo_2_2_2 {
char name[8]; char name[8];
unsigned int caf; unsigned int caf;
char reserved_2[8]; char reserved_2[8];
unsigned char mt_installed; unsigned char mt_installed :1;
unsigned char mt_general; unsigned char :2;
unsigned char mt_psmtid; unsigned char mt_stid :5;
unsigned char :3;
unsigned char mt_gtid :5;
unsigned char :3;
unsigned char mt_psmtid :5;
char reserved_3[5]; char reserved_3[5];
unsigned short cpus_dedicated; unsigned short cpus_dedicated;
unsigned short cpus_shared; unsigned short cpus_shared;
......
...@@ -96,6 +96,4 @@ void arch_release_task_struct(struct task_struct *tsk); ...@@ -96,6 +96,4 @@ void arch_release_task_struct(struct task_struct *tsk);
#define _TIF_31BIT _BITUL(TIF_31BIT) #define _TIF_31BIT _BITUL(TIF_31BIT)
#define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP) #define _TIF_SINGLE_STEP _BITUL(TIF_SINGLE_STEP)
#define is_32bit_task() (test_thread_flag(TIF_31BIT))
#endif /* _ASM_THREAD_INFO_H */ #endif /* _ASM_THREAD_INFO_H */
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
struct sysinfo_15_1_x; struct sysinfo_15_1_x;
struct cpu; struct cpu;
#ifdef CONFIG_SCHED_BOOK #ifdef CONFIG_SCHED_TOPOLOGY
struct cpu_topology_s390 { struct cpu_topology_s390 {
unsigned short thread_id; unsigned short thread_id;
...@@ -40,13 +40,13 @@ void store_topology(struct sysinfo_15_1_x *info); ...@@ -40,13 +40,13 @@ void store_topology(struct sysinfo_15_1_x *info);
void topology_expect_change(void); void topology_expect_change(void);
const struct cpumask *cpu_coregroup_mask(int cpu); const struct cpumask *cpu_coregroup_mask(int cpu);
#else /* CONFIG_SCHED_BOOK */ #else /* CONFIG_SCHED_TOPOLOGY */
static inline void topology_schedule_update(void) { } static inline void topology_schedule_update(void) { }
static inline int topology_cpu_init(struct cpu *cpu) { return 0; } static inline int topology_cpu_init(struct cpu *cpu) { return 0; }
static inline void topology_expect_change(void) { } static inline void topology_expect_change(void) { }
#endif /* CONFIG_SCHED_BOOK */ #endif /* CONFIG_SCHED_TOPOLOGY */
#define POLARIZATION_UNKNOWN (-1) #define POLARIZATION_UNKNOWN (-1)
#define POLARIZATION_HRZ (0) #define POLARIZATION_HRZ (0)
......
...@@ -38,12 +38,14 @@ struct vdso_data { ...@@ -38,12 +38,14 @@ struct vdso_data {
struct vdso_per_cpu_data { struct vdso_per_cpu_data {
__u64 ectg_timer_base; __u64 ectg_timer_base;
__u64 ectg_user_time; __u64 ectg_user_time;
__u32 cpu_nr;
__u32 node_id;
}; };
extern struct vdso_data *vdso_data; extern struct vdso_data *vdso_data;
int vdso_alloc_per_cpu(struct _lowcore *lowcore); int vdso_alloc_per_cpu(struct lowcore *lowcore);
void vdso_free_per_cpu(struct _lowcore *lowcore); void vdso_free_per_cpu(struct lowcore *lowcore);
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#endif /* __S390_VDSO_H__ */ #endif /* __S390_VDSO_H__ */
...@@ -34,8 +34,10 @@ CFLAGS_sysinfo.o += -w ...@@ -34,8 +34,10 @@ CFLAGS_sysinfo.o += -w
# #
CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE) CFLAGS_REMOVE_sclp.o = $(CC_FLAGS_FTRACE)
ifneq ($(CC_FLAGS_MARCH),-march=z900) ifneq ($(CC_FLAGS_MARCH),-march=z900)
CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH) CFLAGS_REMOVE_sclp.o += $(CC_FLAGS_MARCH)
CFLAGS_sclp.o += -march=z900 CFLAGS_sclp.o += -march=z900
AFLAGS_REMOVE_head.o += $(CC_FLAGS_MARCH)
AFLAGS_head.o += -march=z900
endif endif
GCOV_PROFILE_sclp.o := n GCOV_PROFILE_sclp.o := n
...@@ -50,7 +52,7 @@ extra-y += head.o head64.o vmlinux.lds ...@@ -50,7 +52,7 @@ extra-y += head.o head64.o vmlinux.lds
obj-$(CONFIG_MODULES) += s390_ksyms.o module.o obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SCHED_BOOK) += topology.o obj-$(CONFIG_SCHED_TOPOLOGY) += topology.o
obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o obj-$(CONFIG_HIBERNATION) += suspend.o swsusp.o
obj-$(CONFIG_AUDIT) += audit.o obj-$(CONFIG_AUDIT) += audit.o
compat-obj-$(CONFIG_AUDIT) += compat_audit.o compat-obj-$(CONFIG_AUDIT) += compat_audit.o
......
...@@ -80,6 +80,8 @@ int main(void) ...@@ -80,6 +80,8 @@ int main(void)
OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift); OFFSET(__VDSO_TK_SHIFT, vdso_data, tk_shift);
OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base); OFFSET(__VDSO_ECTG_BASE, vdso_per_cpu_data, ectg_timer_base);
OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time); OFFSET(__VDSO_ECTG_USER, vdso_per_cpu_data, ectg_user_time);
OFFSET(__VDSO_CPU_NR, vdso_per_cpu_data, cpu_nr);
OFFSET(__VDSO_NODE_ID, vdso_per_cpu_data, node_id);
BLANK(); BLANK();
/* constants used by the vdso */ /* constants used by the vdso */
DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME); DEFINE(__CLOCK_REALTIME, CLOCK_REALTIME);
...@@ -97,95 +99,96 @@ int main(void) ...@@ -97,95 +99,96 @@ int main(void)
OFFSET(__TIMER_IDLE_EXIT, s390_idle_data, timer_idle_exit); OFFSET(__TIMER_IDLE_EXIT, s390_idle_data, timer_idle_exit);
BLANK(); BLANK();
/* hardware defined lowcore locations 0x000 - 0x1ff */ /* hardware defined lowcore locations 0x000 - 0x1ff */
OFFSET(__LC_EXT_PARAMS, _lowcore, ext_params); OFFSET(__LC_EXT_PARAMS, lowcore, ext_params);
OFFSET(__LC_EXT_CPU_ADDR, _lowcore, ext_cpu_addr); OFFSET(__LC_EXT_CPU_ADDR, lowcore, ext_cpu_addr);
OFFSET(__LC_EXT_INT_CODE, _lowcore, ext_int_code); OFFSET(__LC_EXT_INT_CODE, lowcore, ext_int_code);
OFFSET(__LC_SVC_ILC, _lowcore, svc_ilc); OFFSET(__LC_SVC_ILC, lowcore, svc_ilc);
OFFSET(__LC_SVC_INT_CODE, _lowcore, svc_code); OFFSET(__LC_SVC_INT_CODE, lowcore, svc_code);
OFFSET(__LC_PGM_ILC, _lowcore, pgm_ilc); OFFSET(__LC_PGM_ILC, lowcore, pgm_ilc);
OFFSET(__LC_PGM_INT_CODE, _lowcore, pgm_code); OFFSET(__LC_PGM_INT_CODE, lowcore, pgm_code);
OFFSET(__LC_DATA_EXC_CODE, _lowcore, data_exc_code); OFFSET(__LC_DATA_EXC_CODE, lowcore, data_exc_code);
OFFSET(__LC_MON_CLASS_NR, _lowcore, mon_class_num); OFFSET(__LC_MON_CLASS_NR, lowcore, mon_class_num);
OFFSET(__LC_PER_CODE, _lowcore, per_code); OFFSET(__LC_PER_CODE, lowcore, per_code);
OFFSET(__LC_PER_ATMID, _lowcore, per_atmid); OFFSET(__LC_PER_ATMID, lowcore, per_atmid);
OFFSET(__LC_PER_ADDRESS, _lowcore, per_address); OFFSET(__LC_PER_ADDRESS, lowcore, per_address);
OFFSET(__LC_EXC_ACCESS_ID, _lowcore, exc_access_id); OFFSET(__LC_EXC_ACCESS_ID, lowcore, exc_access_id);
OFFSET(__LC_PER_ACCESS_ID, _lowcore, per_access_id); OFFSET(__LC_PER_ACCESS_ID, lowcore, per_access_id);
OFFSET(__LC_OP_ACCESS_ID, _lowcore, op_access_id); OFFSET(__LC_OP_ACCESS_ID, lowcore, op_access_id);
OFFSET(__LC_AR_MODE_ID, _lowcore, ar_mode_id); OFFSET(__LC_AR_MODE_ID, lowcore, ar_mode_id);
OFFSET(__LC_TRANS_EXC_CODE, _lowcore, trans_exc_code); OFFSET(__LC_TRANS_EXC_CODE, lowcore, trans_exc_code);
OFFSET(__LC_MON_CODE, _lowcore, monitor_code); OFFSET(__LC_MON_CODE, lowcore, monitor_code);
OFFSET(__LC_SUBCHANNEL_ID, _lowcore, subchannel_id); OFFSET(__LC_SUBCHANNEL_ID, lowcore, subchannel_id);
OFFSET(__LC_SUBCHANNEL_NR, _lowcore, subchannel_nr); OFFSET(__LC_SUBCHANNEL_NR, lowcore, subchannel_nr);
OFFSET(__LC_IO_INT_PARM, _lowcore, io_int_parm); OFFSET(__LC_IO_INT_PARM, lowcore, io_int_parm);
OFFSET(__LC_IO_INT_WORD, _lowcore, io_int_word); OFFSET(__LC_IO_INT_WORD, lowcore, io_int_word);
OFFSET(__LC_STFL_FAC_LIST, _lowcore, stfl_fac_list); OFFSET(__LC_STFL_FAC_LIST, lowcore, stfl_fac_list);
OFFSET(__LC_MCCK_CODE, _lowcore, mcck_interruption_code); OFFSET(__LC_STFLE_FAC_LIST, lowcore, stfle_fac_list);
OFFSET(__LC_MCCK_FAIL_STOR_ADDR, _lowcore, failing_storage_address); OFFSET(__LC_MCCK_CODE, lowcore, mcck_interruption_code);
OFFSET(__LC_LAST_BREAK, _lowcore, breaking_event_addr); OFFSET(__LC_MCCK_FAIL_STOR_ADDR, lowcore, failing_storage_address);
OFFSET(__LC_RST_OLD_PSW, _lowcore, restart_old_psw); OFFSET(__LC_LAST_BREAK, lowcore, breaking_event_addr);
OFFSET(__LC_EXT_OLD_PSW, _lowcore, external_old_psw); OFFSET(__LC_RST_OLD_PSW, lowcore, restart_old_psw);
OFFSET(__LC_SVC_OLD_PSW, _lowcore, svc_old_psw); OFFSET(__LC_EXT_OLD_PSW, lowcore, external_old_psw);
OFFSET(__LC_PGM_OLD_PSW, _lowcore, program_old_psw); OFFSET(__LC_SVC_OLD_PSW, lowcore, svc_old_psw);
OFFSET(__LC_MCK_OLD_PSW, _lowcore, mcck_old_psw); OFFSET(__LC_PGM_OLD_PSW, lowcore, program_old_psw);
OFFSET(__LC_IO_OLD_PSW, _lowcore, io_old_psw); OFFSET(__LC_MCK_OLD_PSW, lowcore, mcck_old_psw);
OFFSET(__LC_RST_NEW_PSW, _lowcore, restart_psw); OFFSET(__LC_IO_OLD_PSW, lowcore, io_old_psw);
OFFSET(__LC_EXT_NEW_PSW, _lowcore, external_new_psw); OFFSET(__LC_RST_NEW_PSW, lowcore, restart_psw);
OFFSET(__LC_SVC_NEW_PSW, _lowcore, svc_new_psw); OFFSET(__LC_EXT_NEW_PSW, lowcore, external_new_psw);
OFFSET(__LC_PGM_NEW_PSW, _lowcore, program_new_psw); OFFSET(__LC_SVC_NEW_PSW, lowcore, svc_new_psw);
OFFSET(__LC_MCK_NEW_PSW, _lowcore, mcck_new_psw); OFFSET(__LC_PGM_NEW_PSW, lowcore, program_new_psw);
OFFSET(__LC_IO_NEW_PSW, _lowcore, io_new_psw); OFFSET(__LC_MCK_NEW_PSW, lowcore, mcck_new_psw);
OFFSET(__LC_IO_NEW_PSW, lowcore, io_new_psw);
/* software defined lowcore locations 0x200 - 0xdff*/ /* software defined lowcore locations 0x200 - 0xdff*/
OFFSET(__LC_SAVE_AREA_SYNC, _lowcore, save_area_sync); OFFSET(__LC_SAVE_AREA_SYNC, lowcore, save_area_sync);
OFFSET(__LC_SAVE_AREA_ASYNC, _lowcore, save_area_async); OFFSET(__LC_SAVE_AREA_ASYNC, lowcore, save_area_async);
OFFSET(__LC_SAVE_AREA_RESTART, _lowcore, save_area_restart); OFFSET(__LC_SAVE_AREA_RESTART, lowcore, save_area_restart);
OFFSET(__LC_CPU_FLAGS, _lowcore, cpu_flags); OFFSET(__LC_CPU_FLAGS, lowcore, cpu_flags);
OFFSET(__LC_RETURN_PSW, _lowcore, return_psw); OFFSET(__LC_RETURN_PSW, lowcore, return_psw);
OFFSET(__LC_RETURN_MCCK_PSW, _lowcore, return_mcck_psw); OFFSET(__LC_RETURN_MCCK_PSW, lowcore, return_mcck_psw);
OFFSET(__LC_SYNC_ENTER_TIMER, _lowcore, sync_enter_timer); OFFSET(__LC_SYNC_ENTER_TIMER, lowcore, sync_enter_timer);
OFFSET(__LC_ASYNC_ENTER_TIMER, _lowcore, async_enter_timer); OFFSET(__LC_ASYNC_ENTER_TIMER, lowcore, async_enter_timer);
OFFSET(__LC_MCCK_ENTER_TIMER, _lowcore, mcck_enter_timer); OFFSET(__LC_MCCK_ENTER_TIMER, lowcore, mcck_enter_timer);
OFFSET(__LC_EXIT_TIMER, _lowcore, exit_timer); OFFSET(__LC_EXIT_TIMER, lowcore, exit_timer);
OFFSET(__LC_USER_TIMER, _lowcore, user_timer); OFFSET(__LC_USER_TIMER, lowcore, user_timer);
OFFSET(__LC_SYSTEM_TIMER, _lowcore, system_timer); OFFSET(__LC_SYSTEM_TIMER, lowcore, system_timer);
OFFSET(__LC_STEAL_TIMER, _lowcore, steal_timer); OFFSET(__LC_STEAL_TIMER, lowcore, steal_timer);
OFFSET(__LC_LAST_UPDATE_TIMER, _lowcore, last_update_timer); OFFSET(__LC_LAST_UPDATE_TIMER, lowcore, last_update_timer);
OFFSET(__LC_LAST_UPDATE_CLOCK, _lowcore, last_update_clock); OFFSET(__LC_LAST_UPDATE_CLOCK, lowcore, last_update_clock);
OFFSET(__LC_INT_CLOCK, _lowcore, int_clock); OFFSET(__LC_INT_CLOCK, lowcore, int_clock);
OFFSET(__LC_MCCK_CLOCK, _lowcore, mcck_clock); OFFSET(__LC_MCCK_CLOCK, lowcore, mcck_clock);
OFFSET(__LC_CURRENT, _lowcore, current_task); OFFSET(__LC_CURRENT, lowcore, current_task);
OFFSET(__LC_THREAD_INFO, _lowcore, thread_info); OFFSET(__LC_THREAD_INFO, lowcore, thread_info);
OFFSET(__LC_KERNEL_STACK, _lowcore, kernel_stack); OFFSET(__LC_KERNEL_STACK, lowcore, kernel_stack);
OFFSET(__LC_ASYNC_STACK, _lowcore, async_stack); OFFSET(__LC_ASYNC_STACK, lowcore, async_stack);
OFFSET(__LC_PANIC_STACK, _lowcore, panic_stack); OFFSET(__LC_PANIC_STACK, lowcore, panic_stack);
OFFSET(__LC_RESTART_STACK, _lowcore, restart_stack); OFFSET(__LC_RESTART_STACK, lowcore, restart_stack);
OFFSET(__LC_RESTART_FN, _lowcore, restart_fn); OFFSET(__LC_RESTART_FN, lowcore, restart_fn);
OFFSET(__LC_RESTART_DATA, _lowcore, restart_data); OFFSET(__LC_RESTART_DATA, lowcore, restart_data);
OFFSET(__LC_RESTART_SOURCE, _lowcore, restart_source); OFFSET(__LC_RESTART_SOURCE, lowcore, restart_source);
OFFSET(__LC_USER_ASCE, _lowcore, user_asce); OFFSET(__LC_USER_ASCE, lowcore, user_asce);
OFFSET(__LC_LPP, _lowcore, lpp); OFFSET(__LC_LPP, lowcore, lpp);
OFFSET(__LC_CURRENT_PID, _lowcore, current_pid); OFFSET(__LC_CURRENT_PID, lowcore, current_pid);
OFFSET(__LC_PERCPU_OFFSET, _lowcore, percpu_offset); OFFSET(__LC_PERCPU_OFFSET, lowcore, percpu_offset);
OFFSET(__LC_VDSO_PER_CPU, _lowcore, vdso_per_cpu_data); OFFSET(__LC_VDSO_PER_CPU, lowcore, vdso_per_cpu_data);
OFFSET(__LC_MACHINE_FLAGS, _lowcore, machine_flags); OFFSET(__LC_MACHINE_FLAGS, lowcore, machine_flags);
OFFSET(__LC_GMAP, _lowcore, gmap); OFFSET(__LC_GMAP, lowcore, gmap);
OFFSET(__LC_PASTE, _lowcore, paste); OFFSET(__LC_PASTE, lowcore, paste);
/* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */ /* software defined ABI-relevant lowcore locations 0xe00 - 0xe20 */
OFFSET(__LC_DUMP_REIPL, _lowcore, ipib); OFFSET(__LC_DUMP_REIPL, lowcore, ipib);
/* hardware defined lowcore locations 0x1000 - 0x18ff */ /* hardware defined lowcore locations 0x1000 - 0x18ff */
OFFSET(__LC_VX_SAVE_AREA_ADDR, _lowcore, vector_save_area_addr); OFFSET(__LC_VX_SAVE_AREA_ADDR, lowcore, vector_save_area_addr);
OFFSET(__LC_EXT_PARAMS2, _lowcore, ext_params2); OFFSET(__LC_EXT_PARAMS2, lowcore, ext_params2);
OFFSET(SAVE_AREA_BASE, _lowcore, floating_pt_save_area); OFFSET(__LC_FPREGS_SAVE_AREA, lowcore, floating_pt_save_area);
OFFSET(__LC_FPREGS_SAVE_AREA, _lowcore, floating_pt_save_area); OFFSET(__LC_GPREGS_SAVE_AREA, lowcore, gpregs_save_area);
OFFSET(__LC_GPREGS_SAVE_AREA, _lowcore, gpregs_save_area); OFFSET(__LC_PSW_SAVE_AREA, lowcore, psw_save_area);
OFFSET(__LC_PSW_SAVE_AREA, _lowcore, psw_save_area); OFFSET(__LC_PREFIX_SAVE_AREA, lowcore, prefixreg_save_area);
OFFSET(__LC_PREFIX_SAVE_AREA, _lowcore, prefixreg_save_area); OFFSET(__LC_FP_CREG_SAVE_AREA, lowcore, fpt_creg_save_area);
OFFSET(__LC_FP_CREG_SAVE_AREA, _lowcore, fpt_creg_save_area); OFFSET(__LC_TOD_PROGREG_SAVE_AREA, lowcore, tod_progreg_save_area);
OFFSET(__LC_CPU_TIMER_SAVE_AREA, _lowcore, cpu_timer_save_area); OFFSET(__LC_CPU_TIMER_SAVE_AREA, lowcore, cpu_timer_save_area);
OFFSET(__LC_CLOCK_COMP_SAVE_AREA, _lowcore, clock_comp_save_area); OFFSET(__LC_CLOCK_COMP_SAVE_AREA, lowcore, clock_comp_save_area);
OFFSET(__LC_AREGS_SAVE_AREA, _lowcore, access_regs_save_area); OFFSET(__LC_AREGS_SAVE_AREA, lowcore, access_regs_save_area);
OFFSET(__LC_CREGS_SAVE_AREA, _lowcore, cregs_save_area); OFFSET(__LC_CREGS_SAVE_AREA, lowcore, cregs_save_area);
OFFSET(__LC_PGM_TDB, _lowcore, pgm_tdb); OFFSET(__LC_PGM_TDB, lowcore, pgm_tdb);
BLANK(); BLANK();
/* gmap/sie offsets */ /* gmap/sie offsets */
OFFSET(__GMAP_ASCE, gmap, asce); OFFSET(__GMAP_ASCE, gmap, asce);
......
This diff is collapsed.
...@@ -2022,7 +2022,7 @@ void show_code(struct pt_regs *regs) ...@@ -2022,7 +2022,7 @@ void show_code(struct pt_regs *regs)
*ptr++ = '\t'; *ptr++ = '\t';
ptr += print_insn(ptr, code + start, addr); ptr += print_insn(ptr, code + start, addr);
start += opsize; start += opsize;
printk(buffer); printk("%s", buffer);
ptr = buffer; ptr = buffer;
ptr += sprintf(ptr, "\n "); ptr += sprintf(ptr, "\n ");
hops++; hops++;
...@@ -2049,7 +2049,7 @@ void print_fn_code(unsigned char *code, unsigned long len) ...@@ -2049,7 +2049,7 @@ void print_fn_code(unsigned char *code, unsigned long len)
ptr += print_insn(ptr, code, (unsigned long) code); ptr += print_insn(ptr, code, (unsigned long) code);
*ptr++ = '\n'; *ptr++ = '\n';
*ptr++ = 0; *ptr++ = 0;
printk(buffer); printk("%s", buffer);
code += opsize; code += opsize;
len -= opsize; len -= opsize;
} }
......
...@@ -335,6 +335,14 @@ static __init void detect_machine_facilities(void) ...@@ -335,6 +335,14 @@ static __init void detect_machine_facilities(void)
} }
} }
static inline void save_vector_registers(void)
{
#ifdef CONFIG_CRASH_DUMP
if (test_facility(129))
save_vx_regs(boot_cpu_vector_save_area);
#endif
}
static int __init disable_vector_extension(char *str) static int __init disable_vector_extension(char *str)
{ {
S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX; S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX;
...@@ -451,6 +459,7 @@ void __init startup_init(void) ...@@ -451,6 +459,7 @@ void __init startup_init(void)
detect_diag9c(); detect_diag9c();
detect_diag44(); detect_diag44();
detect_machine_facilities(); detect_machine_facilities();
save_vector_registers();
setup_topology(); setup_topology();
sclp_early_detect(); sclp_early_detect();
lockdep_on(); lockdep_on();
......
...@@ -764,6 +764,7 @@ ENTRY(psw_idle) ...@@ -764,6 +764,7 @@ ENTRY(psw_idle)
.insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15) .insn rsy,0xeb0000000017,%r1,5,__SF_EMPTY+16(%r15)
.Lpsw_idle_stcctm: .Lpsw_idle_stcctm:
#endif #endif
oi __LC_CPU_FLAGS+7,_CIF_ENABLED_WAIT
STCK __CLOCK_IDLE_ENTER(%r2) STCK __CLOCK_IDLE_ENTER(%r2)
stpt __TIMER_IDLE_ENTER(%r2) stpt __TIMER_IDLE_ENTER(%r2)
.Lpsw_idle_lpsw: .Lpsw_idle_lpsw:
...@@ -1146,6 +1147,7 @@ cleanup_critical: ...@@ -1146,6 +1147,7 @@ cleanup_critical:
.quad .Lio_done - 4 .quad .Lio_done - 4
.Lcleanup_idle: .Lcleanup_idle:
ni __LC_CPU_FLAGS+7,255-_CIF_ENABLED_WAIT
# copy interrupt clock & cpu timer # copy interrupt clock & cpu timer
mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#include <asm/facility.h>
#include <asm/page.h> #include <asm/page.h>
#include <asm/ptrace.h> #include <asm/ptrace.h>
...@@ -300,27 +301,27 @@ ENTRY(startup_kdump) ...@@ -300,27 +301,27 @@ ENTRY(startup_kdump)
xc 0x200(256),0x200 # partially clear lowcore xc 0x200(256),0x200 # partially clear lowcore
xc 0x300(256),0x300 xc 0x300(256),0x300
xc 0xe00(256),0xe00 xc 0xe00(256),0xe00
xc 0xf00(256),0xf00
lctlg %c0,%c15,0x200(%r0) # initialize control registers lctlg %c0,%c15,0x200(%r0) # initialize control registers
stck __LC_LAST_UPDATE_CLOCK stck __LC_LAST_UPDATE_CLOCK
spt 6f-.LPG0(%r13) spt 6f-.LPG0(%r13)
mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13) mvc __LC_LAST_UPDATE_TIMER(8),6f-.LPG0(%r13)
xc __LC_STFL_FAC_LIST(8),__LC_STFL_FAC_LIST stfl 0(%r0) # store facilities @ __LC_STFL_FAC_LIST
# check capabilities against MARCH_{G5,Z900,Z990,Z9_109,Z10} mvc __LC_STFLE_FAC_LIST(4),__LC_STFL_FAC_LIST
.insn s,0xb2b10000,0 # store facilities @ __LC_STFL_FAC_LIST tm __LC_STFLE_FAC_LIST,0x01 # stfle available ?
tm __LC_STFL_FAC_LIST,0x01 # stfle available ?
jz 0f jz 0f
la %r0,1 lghi %r0,FACILITIES_ALS_DWORDS-1
.insn s,0xb2b00000,__LC_STFL_FAC_LIST # store facility list extended .insn s,0xb2b00000,__LC_STFLE_FAC_LIST # store facility list extended
# verify if all required facilities are supported by the machine # verify if all required facilities are supported by the machine
0: la %r1,__LC_STFL_FAC_LIST 0: la %r1,__LC_STFLE_FAC_LIST
la %r2,3f+8-.LPG0(%r13) la %r2,3f+8-.LPG0(%r13)
l %r3,0(%r2) lhi %r3,FACILITIES_ALS_DWORDS
1: l %r0,0(%r1) 1: lg %r0,0(%r1)
n %r0,4(%r2) ng %r0,0(%r2)
cl %r0,4(%r2) clg %r0,0(%r2)
jne 2f jne 2f
la %r1,4(%r1) la %r1,8(%r1)
la %r2,4(%r2) la %r2,8(%r2)
ahi %r3,-1 ahi %r3,-1
jnz 1b jnz 1b
j 4f j 4f
...@@ -340,24 +341,10 @@ ENTRY(startup_kdump) ...@@ -340,24 +341,10 @@ ENTRY(startup_kdump)
3: .long 0x000a0000,0x8badcccc 3: .long 0x000a0000,0x8badcccc
# List of facilities that are required. If not all facilities are present # List of facilities that are required. If not all facilities are present
# the kernel will crash. Format is number of facility words with bits set, # the kernel will crash.
# followed by the facility words.
.quad FACILITIES_ALS
#if defined(CONFIG_MARCH_Z13)
.long 2, 0xc100eff2, 0xf46cc800
#elif defined(CONFIG_MARCH_ZEC12)
.long 2, 0xc100eff2, 0xf46cc800
#elif defined(CONFIG_MARCH_Z196)
.long 2, 0xc100eff2, 0xf46c0000
#elif defined(CONFIG_MARCH_Z10)
.long 2, 0xc100eff2, 0xf0680000
#elif defined(CONFIG_MARCH_Z9_109)
.long 1, 0xc100efc2
#elif defined(CONFIG_MARCH_Z990)
.long 1, 0xc0002000
#elif defined(CONFIG_MARCH_Z900)
.long 1, 0xc0000000
#endif
4: 4:
/* Continue with startup code in head64.S */ /* Continue with startup code in head64.S */
jg startup_continue jg startup_continue
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
__HEAD __HEAD
ENTRY(startup_continue) ENTRY(startup_continue)
tm __LC_STFL_FAC_LIST+6,0x80 # LPP available ? tm __LC_STFLE_FAC_LIST+6,0x80 # LPP available ?
jz 0f jz 0f
xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid
mvi __LC_LPP,0x80 # and set LPP_MAGIC mvi __LC_LPP,0x80 # and set LPP_MAGIC
......
...@@ -2039,21 +2039,15 @@ static void do_reset_calls(void) ...@@ -2039,21 +2039,15 @@ static void do_reset_calls(void)
reset->fn(); reset->fn();
} }
u32 dump_prefix_page; void s390_reset_system(void)
void s390_reset_system(void (*fn_pre)(void),
void (*fn_post)(void *), void *data)
{ {
struct _lowcore *lc; struct lowcore *lc;
lc = (struct _lowcore *)(unsigned long) store_prefix(); lc = (struct lowcore *)(unsigned long) store_prefix();
/* Stack for interrupt/machine check handler */ /* Stack for interrupt/machine check handler */
lc->panic_stack = S390_lowcore.panic_stack; lc->panic_stack = S390_lowcore.panic_stack;
/* Save prefix page address for dump case */
dump_prefix_page = (u32)(unsigned long) lc;
/* Disable prefixing */ /* Disable prefixing */
set_prefix(0); set_prefix(0);
...@@ -2077,14 +2071,5 @@ void s390_reset_system(void (*fn_pre)(void), ...@@ -2077,14 +2071,5 @@ void s390_reset_system(void (*fn_pre)(void),
S390_lowcore.subchannel_id = 0; S390_lowcore.subchannel_id = 0;
S390_lowcore.subchannel_nr = 0; S390_lowcore.subchannel_nr = 0;
/* Store status at absolute zero */
store_status();
/* Call function before reset */
if (fn_pre)
fn_pre();
do_reset_calls(); do_reset_calls();
/* Call function after reset */
if (fn_post)
fn_post(data);
} }
...@@ -34,46 +34,6 @@ extern const unsigned long long relocate_kernel_len; ...@@ -34,46 +34,6 @@ extern const unsigned long long relocate_kernel_len;
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
/*
* Create ELF notes for one CPU
*/
static void add_elf_notes(int cpu)
{
struct save_area *sa = (void *) 4608 + store_prefix();
void *ptr;
memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa));
ptr = (u64 *) per_cpu_ptr(crash_notes, cpu);
ptr = fill_cpu_elf_notes(ptr, sa, NULL);
memset(ptr, 0, sizeof(struct elf_note));
}
/*
* Initialize CPU ELF notes
*/
static void setup_regs(void)
{
unsigned long sa = S390_lowcore.prefixreg_save_area + SAVE_AREA_BASE;
struct _lowcore *lc;
int cpu, this_cpu;
/* Get lowcore pointer from store status of this CPU (absolute zero) */
lc = (struct _lowcore *)(unsigned long)S390_lowcore.prefixreg_save_area;
this_cpu = smp_find_processor_id(stap());
add_elf_notes(this_cpu);
for_each_online_cpu(cpu) {
if (cpu == this_cpu)
continue;
if (smp_store_status(cpu))
continue;
add_elf_notes(cpu);
}
if (MACHINE_HAS_VX)
save_vx_regs_safe((void *) lc->vector_save_area_addr);
/* Copy dump CPU store status info to absolute zero */
memcpy((void *) SAVE_AREA_BASE, (void *) sa, sizeof(struct save_area));
}
/* /*
* PM notifier callback for kdump * PM notifier callback for kdump
*/ */
...@@ -105,14 +65,66 @@ static int __init machine_kdump_pm_init(void) ...@@ -105,14 +65,66 @@ static int __init machine_kdump_pm_init(void)
arch_initcall(machine_kdump_pm_init); arch_initcall(machine_kdump_pm_init);
/* /*
* Start kdump: We expect here that a store status has been done on our CPU * Reset the system, copy boot CPU registers to absolute zero,
* and jump to the kdump image
*/ */
static void __do_machine_kdump(void *image) static void __do_machine_kdump(void *image)
{ {
int (*start_kdump)(int) = (void *)((struct kimage *) image)->start; int (*start_kdump)(int);
unsigned long prefix;
/* store_status() saved the prefix register to lowcore */
prefix = (unsigned long) S390_lowcore.prefixreg_save_area;
/* Now do the reset */
s390_reset_system();
/*
* Copy dump CPU store status info to absolute zero.
* This need to be done *after* s390_reset_system set the
* prefix register of this CPU to zero
*/
memcpy((void *) __LC_FPREGS_SAVE_AREA,
(void *)(prefix + __LC_FPREGS_SAVE_AREA), 512);
__load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA); __load_psw_mask(PSW_MASK_BASE | PSW_DEFAULT_KEY | PSW_MASK_EA | PSW_MASK_BA);
start_kdump = (void *)((struct kimage *) image)->start;
start_kdump(1); start_kdump(1);
/* Die if start_kdump returns */
disabled_wait((unsigned long) __builtin_return_address(0));
}
/*
* Start kdump: create a LGR log entry, store status of all CPUs and
* branch to __do_machine_kdump.
*/
static noinline void __machine_kdump(void *image)
{
int this_cpu, cpu;
lgr_info_log();
/* Get status of the other CPUs */
this_cpu = smp_find_processor_id(stap());
for_each_online_cpu(cpu) {
if (cpu == this_cpu)
continue;
if (smp_store_status(cpu))
continue;
}
/* Store status of the boot CPU */
if (MACHINE_HAS_VX)
save_vx_regs((void *) &S390_lowcore.vector_save_area);
/*
* To create a good backchain for this CPU in the dump store_status
* is passed the address of a function. The address is saved into
* the PSW save area of the boot CPU and the function is invoked as
* a tail call of store_status. The backchain in the dump will look
* like this:
* restart_int_handler -> __machine_kexec -> __do_machine_kdump
* The call to store_status() will not return.
*/
store_status(__do_machine_kdump, image);
} }
#endif #endif
...@@ -235,10 +247,14 @@ static void __do_machine_kexec(void *data) ...@@ -235,10 +247,14 @@ static void __do_machine_kexec(void *data)
relocate_kernel_t data_mover; relocate_kernel_t data_mover;
struct kimage *image = data; struct kimage *image = data;
s390_reset_system();
data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page); data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page);
/* Call the moving routine */ /* Call the moving routine */
(*data_mover)(&image->head, image->start); (*data_mover)(&image->head, image->start);
/* Die if kexec returns */
disabled_wait((unsigned long) __builtin_return_address(0));
} }
/* /*
...@@ -251,14 +267,10 @@ static void __machine_kexec(void *data) ...@@ -251,14 +267,10 @@ static void __machine_kexec(void *data)
tracing_off(); tracing_off();
debug_locks_off(); debug_locks_off();
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH) { if (((struct kimage *) data)->type == KEXEC_TYPE_CRASH)
__machine_kdump(data);
lgr_info_log();
s390_reset_system(setup_regs, __do_machine_kdump, data);
} else
#endif #endif
s390_reset_system(NULL, __do_machine_kexec, data); __do_machine_kexec(data);
disabled_wait((unsigned long) __builtin_return_address(0));
} }
/* /*
......
...@@ -89,7 +89,7 @@ static void os_info_old_alloc(int nr, int align) ...@@ -89,7 +89,7 @@ static void os_info_old_alloc(int nr, int align)
goto fail; goto fail;
} }
buf_align = PTR_ALIGN(buf, align); buf_align = PTR_ALIGN(buf, align);
if (copy_from_oldmem(buf_align, (void *) addr, size)) { if (copy_oldmem_kernel(buf_align, (void *) addr, size)) {
msg = "copy failed"; msg = "copy failed";
goto fail_free; goto fail_free;
} }
...@@ -122,14 +122,15 @@ static void os_info_old_init(void) ...@@ -122,14 +122,15 @@ static void os_info_old_init(void)
return; return;
if (!OLDMEM_BASE) if (!OLDMEM_BASE)
goto fail; goto fail;
if (copy_from_oldmem(&addr, &S390_lowcore.os_info, sizeof(addr))) if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr)))
goto fail; goto fail;
if (addr == 0 || addr % PAGE_SIZE) if (addr == 0 || addr % PAGE_SIZE)
goto fail; goto fail;
os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL); os_info_old = kzalloc(sizeof(*os_info_old), GFP_KERNEL);
if (!os_info_old) if (!os_info_old)
goto fail; goto fail;
if (copy_from_oldmem(os_info_old, (void *) addr, sizeof(*os_info_old))) if (copy_oldmem_kernel(os_info_old, (void *) addr,
sizeof(*os_info_old)))
goto fail_free; goto fail_free;
if (os_info_old->magic != OS_INFO_MAGIC) if (os_info_old->magic != OS_INFO_MAGIC)
goto fail_free; goto fail_free;
......
...@@ -9,60 +9,66 @@ ...@@ -9,60 +9,66 @@
#include <asm/sigp.h> #include <asm/sigp.h>
# #
# store_status # Issue "store status" for the current CPU to its prefix page
# and call passed function afterwards
# #
# Prerequisites to run this function: # r2 = Function to be called after store status
# - Prefix register is set to zero # r3 = Parameter for function
# - Original prefix register is stored in "dump_prefix_page"
# - Lowcore protection is off
# #
ENTRY(store_status) ENTRY(store_status)
/* Save register one and load save area base */ /* Save register one and load save area base */
stg %r1,__LC_SAVE_AREA_RESTART stg %r1,__LC_SAVE_AREA_RESTART
lghi %r1,SAVE_AREA_BASE
/* General purpose registers */ /* General purpose registers */
stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) lghi %r1,__LC_GPREGS_SAVE_AREA
lg %r2,__LC_SAVE_AREA_RESTART stmg %r0,%r15,0(%r1)
stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) mvc 8(8,%r1),__LC_SAVE_AREA_RESTART
/* Control registers */ /* Control registers */
stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) lghi %r1,__LC_CREGS_SAVE_AREA
stctg %c0,%c15,0(%r1)
/* Access registers */ /* Access registers */
stam %a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) lghi %r1,__LC_AREGS_SAVE_AREA
stam %a0,%a15,0(%r1)
/* Floating point registers */ /* Floating point registers */
std %f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) lghi %r1,__LC_FPREGS_SAVE_AREA
std %f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f0, 0x00(%r1)
std %f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f1, 0x08(%r1)
std %f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f2, 0x10(%r1)
std %f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f3, 0x18(%r1)
std %f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f4, 0x20(%r1)
std %f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f5, 0x28(%r1)
std %f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f6, 0x30(%r1)
std %f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f7, 0x38(%r1)
std %f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f8, 0x40(%r1)
std %f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f9, 0x48(%r1)
std %f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f10,0x50(%r1)
std %f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f11,0x58(%r1)
std %f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f12,0x60(%r1)
std %f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f13,0x68(%r1)
std %f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) std %f14,0x70(%r1)
std %f15,0x78(%r1)
/* Floating point control register */ /* Floating point control register */
stfpc __LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1) lghi %r1,__LC_FP_CREG_SAVE_AREA
stfpc 0(%r1)
/* CPU timer */ /* CPU timer */
stpt __LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1) lghi %r1,__LC_CPU_TIMER_SAVE_AREA
/* Saved prefix register */ stpt 0(%r1)
larl %r2,dump_prefix_page /* Store prefix register */
mvc __LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2) lghi %r1,__LC_PREFIX_SAVE_AREA
stpx 0(%r1)
/* Clock comparator - seven bytes */ /* Clock comparator - seven bytes */
larl %r2,.Lclkcmp lghi %r1,__LC_CLOCK_COMP_SAVE_AREA
stckc 0(%r2) larl %r4,.Lclkcmp
mvc __LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2) stckc 0(%r4)
mvc 1(7,%r1),1(%r4)
/* Program status word */ /* Program status word */
epsw %r2,%r3 lghi %r1,__LC_PSW_SAVE_AREA
st %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1) epsw %r4,%r5
st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1) st %r4,0(%r1)
larl %r2,store_status st %r5,4(%r1)
stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1) stg %r2,8(%r1)
br %r14 lgr %r1,%r2
lgr %r2,%r3
br %r1
.section .bss .section .bss
.align 8 .align 8
...@@ -77,9 +83,11 @@ ENTRY(store_status) ...@@ -77,9 +83,11 @@ ENTRY(store_status)
ENTRY(do_reipl_asm) ENTRY(do_reipl_asm)
basr %r13,0 basr %r13,0
.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) .Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
.Lpg1: brasl %r14,store_status .Lpg1: lgr %r3,%r2
larl %r2,.Lstatus
brasl %r14,store_status
lctlg %c6,%c6,.Lall-.Lpg0(%r13) .Lstatus: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
lgr %r1,%r2 lgr %r1,%r2
mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
stsch .Lschib-.Lpg0(%r13) stsch .Lschib-.Lpg0(%r13)
......
...@@ -9,7 +9,11 @@ ...@@ -9,7 +9,11 @@
#include <asm/processor.h> #include <asm/processor.h>
#include <asm/sclp.h> #include <asm/sclp.h>
#define EVTYP_VT220MSG_MASK 0x00000040
#define EVTYP_MSG_MASK 0x40000000
static char _sclp_work_area[4096] __aligned(PAGE_SIZE); static char _sclp_work_area[4096] __aligned(PAGE_SIZE);
static bool have_vt220, have_linemode;
static void _sclp_wait_int(void) static void _sclp_wait_int(void)
{ {
...@@ -68,7 +72,7 @@ static int _sclp_setup(int disable) ...@@ -68,7 +72,7 @@ static int _sclp_setup(int disable)
0x00, 0x1c, 0x00, 0x1c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x04, 0x00, 0x04,
0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
unsigned int *masks; unsigned int *masks;
...@@ -82,13 +86,13 @@ static int _sclp_setup(int disable) ...@@ -82,13 +86,13 @@ static int _sclp_setup(int disable)
rc = _sclp_servc(0x00780005, _sclp_work_area); rc = _sclp_servc(0x00780005, _sclp_work_area);
if (rc) if (rc)
return rc; return rc;
if ((masks[0] & masks[3]) != masks[0] || have_vt220 = masks[2] & EVTYP_VT220MSG_MASK;
(masks[1] & masks[2]) != masks[1]) have_linemode = masks[2] & EVTYP_MSG_MASK;
return -EIO;
return 0; return 0;
} }
static int _sclp_print(const char *str) /* Output multi-line text using SCLP Message interface. */
static void _sclp_print_lm(const char *str)
{ {
static unsigned char write_head[] = { static unsigned char write_head[] = {
/* sccb header */ /* sccb header */
...@@ -143,18 +147,49 @@ static int _sclp_print(const char *str) ...@@ -143,18 +147,49 @@ static int _sclp_print(const char *str)
} while (ch != 0); } while (ch != 0);
/* SCLP write data */ /* SCLP write data */
return _sclp_servc(0x00760005, _sclp_work_area); _sclp_servc(0x00760005, _sclp_work_area);
} }
int _sclp_print_early(const char *str) /* Output multi-line text (plus a newline) using SCLP VT220
* interface.
*/
static void _sclp_print_vt220(const char *str)
{ {
int rc; static unsigned char const write_head[] = {
/* sccb header */
0x00, 0x0e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* evbuf header */
0x00, 0x06,
0x1a, 0x00, 0x00, 0x00,
};
size_t len = strlen(str);
rc = _sclp_setup(0); if (sizeof(write_head) + len >= sizeof(_sclp_work_area))
if (rc) len = sizeof(_sclp_work_area) - sizeof(write_head) - 1;
return rc;
rc = _sclp_print(str); memcpy(_sclp_work_area, write_head, sizeof(write_head));
if (rc) memcpy(_sclp_work_area + sizeof(write_head), str, len);
return rc; _sclp_work_area[sizeof(write_head) + len] = '\n';
return _sclp_setup(1);
/* Update length fields in evbuf and sccb headers */
*(unsigned short *)(_sclp_work_area + 8) += len + 1;
*(unsigned short *)(_sclp_work_area + 0) += len + 1;
/* SCLP write data */
(void)_sclp_servc(0x00760005, _sclp_work_area);
}
/* Output one or more lines of text on the SCLP console (VT220 and /
* or line-mode). All lines get terminated; no need for a trailing LF.
*/
void _sclp_print_early(const char *str)
{
if (_sclp_setup(0) != 0)
return;
if (have_linemode)
_sclp_print_lm(str);
if (have_vt220)
_sclp_print_vt220(str);
_sclp_setup(1);
} }
...@@ -99,7 +99,7 @@ unsigned long MODULES_VADDR; ...@@ -99,7 +99,7 @@ unsigned long MODULES_VADDR;
unsigned long MODULES_END; unsigned long MODULES_END;
/* An array with a pointer to the lowcore of every CPU. */ /* An array with a pointer to the lowcore of every CPU. */
struct _lowcore *lowcore_ptr[NR_CPUS]; struct lowcore *lowcore_ptr[NR_CPUS];
EXPORT_SYMBOL(lowcore_ptr); EXPORT_SYMBOL(lowcore_ptr);
/* /*
...@@ -293,12 +293,12 @@ void *restart_stack __attribute__((__section__(".data"))); ...@@ -293,12 +293,12 @@ void *restart_stack __attribute__((__section__(".data")));
static void __init setup_lowcore(void) static void __init setup_lowcore(void)
{ {
struct _lowcore *lc; struct lowcore *lc;
/* /*
* Setup lowcore for boot cpu * Setup lowcore for boot cpu
*/ */
BUILD_BUG_ON(sizeof(struct _lowcore) != LC_PAGES * 4096); BUILD_BUG_ON(sizeof(struct lowcore) != LC_PAGES * 4096);
lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0);
lc->restart_psw.mask = PSW_KERNEL_BITS; lc->restart_psw.mask = PSW_KERNEL_BITS;
lc->restart_psw.addr = lc->restart_psw.addr =
...@@ -663,15 +663,6 @@ static void __init reserve_kernel(void) ...@@ -663,15 +663,6 @@ static void __init reserve_kernel(void)
#endif #endif
} }
static void __init reserve_elfcorehdr(void)
{
#ifdef CONFIG_CRASH_DUMP
if (is_kdump_kernel())
memblock_reserve(elfcorehdr_addr - OLDMEM_BASE,
PAGE_ALIGN(elfcorehdr_size));
#endif
}
static void __init setup_memory(void) static void __init setup_memory(void)
{ {
struct memblock_region *reg; struct memblock_region *reg;
...@@ -850,6 +841,11 @@ void __init setup_arch(char **cmdline_p) ...@@ -850,6 +841,11 @@ void __init setup_arch(char **cmdline_p)
init_mm.brk = (unsigned long) &_end; init_mm.brk = (unsigned long) &_end;
parse_early_param(); parse_early_param();
#ifdef CONFIG_CRASH_DUMP
/* Deactivate elfcorehdr= kernel parameter */
elfcorehdr_addr = ELFCORE_ADDR_MAX;
#endif
os_info_init(); os_info_init();
setup_ipl(); setup_ipl();
...@@ -858,7 +854,6 @@ void __init setup_arch(char **cmdline_p) ...@@ -858,7 +854,6 @@ void __init setup_arch(char **cmdline_p)
reserve_oldmem(); reserve_oldmem();
reserve_kernel(); reserve_kernel();
reserve_initrd(); reserve_initrd();
reserve_elfcorehdr();
memblock_allow_resize(); memblock_allow_resize();
/* Get information about *all* installed memory */ /* Get information about *all* installed memory */
...@@ -879,11 +874,13 @@ void __init setup_arch(char **cmdline_p) ...@@ -879,11 +874,13 @@ void __init setup_arch(char **cmdline_p)
check_initrd(); check_initrd();
reserve_crashkernel(); reserve_crashkernel();
#ifdef CONFIG_CRASH_DUMP
/* /*
* Be aware that smp_save_dump_cpus() triggers a system reset. * Be aware that smp_save_dump_cpus() triggers a system reset.
* Therefore CPU and device initialization should be done afterwards. * Therefore CPU and device initialization should be done afterwards.
*/ */
smp_save_dump_cpus(); smp_save_dump_cpus();
#endif
setup_resources(); setup_resources();
setup_vmcoreinfo(); setup_vmcoreinfo();
......
This diff is collapsed.
...@@ -111,8 +111,7 @@ static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info) ...@@ -111,8 +111,7 @@ static void stsi_1_1_1(struct seq_file *m, struct sysinfo_1_1_1 *info)
static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info) static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
{ {
static int max_mnest; int i;
int i, rc;
seq_putc(m, '\n'); seq_putc(m, '\n');
if (!MACHINE_HAS_TOPOLOGY) 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,7 +122,7 @@ static void stsi_15_1_x(struct seq_file *m, struct sysinfo_15_1_x *info)
for (i = 0; i < TOPOLOGY_NR_MAG; i++) for (i = 0; i < TOPOLOGY_NR_MAG; i++)
seq_printf(m, " %d", info->mag[i]); seq_printf(m, " %d", info->mag[i]);
seq_putc(m, '\n'); seq_putc(m, '\n');
#ifdef CONFIG_SCHED_MC #ifdef CONFIG_SCHED_TOPOLOGY
store_topology(info); store_topology(info);
seq_printf(m, "CPU Topology SW: "); seq_printf(m, "CPU Topology SW: ");
for (i = 0; i < TOPOLOGY_NR_MAG; i++) 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,6 +144,10 @@ static void stsi_1_2_2(struct seq_file *m, struct sysinfo_1_2_2 *info)
seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured); seq_printf(m, "CPUs Configured: %d\n", info->cpus_configured);
seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby); seq_printf(m, "CPUs Standby: %d\n", info->cpus_standby);
seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved); seq_printf(m, "CPUs Reserved: %d\n", info->cpus_reserved);
if (info->mt_installed) {
seq_printf(m, "CPUs G-MTID: %d\n", info->mt_gtid);
seq_printf(m, "CPUs S-MTID: %d\n", info->mt_stid);
}
/* /*
* Sigh 2. According to the specification the alternate * Sigh 2. According to the specification the alternate
* capability field is a 32 bit floating point number * 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,13 +197,10 @@ static void stsi_2_2_2(struct seq_file *m, struct sysinfo_2_2_2 *info)
seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved); seq_printf(m, "LPAR CPUs Reserved: %d\n", info->cpus_reserved);
seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated); seq_printf(m, "LPAR CPUs Dedicated: %d\n", info->cpus_dedicated);
seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared); seq_printf(m, "LPAR CPUs Shared: %d\n", info->cpus_shared);
if (info->mt_installed & 0x80) { if (info->mt_installed) {
seq_printf(m, "LPAR CPUs G-MTID: %d\n", seq_printf(m, "LPAR CPUs G-MTID: %d\n", info->mt_gtid);
info->mt_general & 0x1f); seq_printf(m, "LPAR CPUs S-MTID: %d\n", info->mt_stid);
seq_printf(m, "LPAR CPUs S-MTID: %d\n", seq_printf(m, "LPAR CPUs PS-MTID: %d\n", info->mt_psmtid);
info->mt_installed & 0x1f);
seq_printf(m, "LPAR CPUs PS-MTID: %d\n",
info->mt_psmtid & 0x1f);
} }
} }
......
...@@ -260,11 +260,8 @@ void vector_exception(struct pt_regs *regs) ...@@ -260,11 +260,8 @@ void vector_exception(struct pt_regs *regs)
void data_exception(struct pt_regs *regs) void data_exception(struct pt_regs *regs)
{ {
__u16 __user *location;
int signal = 0; int signal = 0;
location = get_trap_ip(regs);
save_fpu_regs(); save_fpu_regs();
if (current->thread.fpu.fpc & FPC_DXC_MASK) if (current->thread.fpu.fpc & FPC_DXC_MASK)
signal = SIGFPE; signal = SIGFPE;
......
...@@ -80,7 +80,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data; ...@@ -80,7 +80,7 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
/* /*
* Setup vdso data page. * Setup vdso data page.
*/ */
static void vdso_init_data(struct vdso_data *vd) static void __init vdso_init_data(struct vdso_data *vd)
{ {
vd->ectg_available = test_facility(31); vd->ectg_available = test_facility(31);
} }
...@@ -90,9 +90,10 @@ static void vdso_init_data(struct vdso_data *vd) ...@@ -90,9 +90,10 @@ static void vdso_init_data(struct vdso_data *vd)
*/ */
#define SEGMENT_ORDER 2 #define SEGMENT_ORDER 2
int vdso_alloc_per_cpu(struct _lowcore *lowcore) int vdso_alloc_per_cpu(struct lowcore *lowcore)
{ {
unsigned long segment_table, page_table, page_frame; unsigned long segment_table, page_table, page_frame;
struct vdso_per_cpu_data *vd;
u32 *psal, *aste; u32 *psal, *aste;
int i; int i;
...@@ -107,6 +108,12 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore) ...@@ -107,6 +108,12 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
if (!segment_table || !page_table || !page_frame) if (!segment_table || !page_table || !page_frame)
goto out; goto out;
/* Initialize per-cpu vdso data page */
vd = (struct vdso_per_cpu_data *) page_frame;
vd->cpu_nr = lowcore->cpu_nr;
vd->node_id = cpu_to_node(vd->cpu_nr);
/* Set up access register mode page table */
clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY, clear_table((unsigned long *) segment_table, _SEGMENT_ENTRY_EMPTY,
PAGE_SIZE << SEGMENT_ORDER); PAGE_SIZE << SEGMENT_ORDER);
clear_table((unsigned long *) page_table, _PAGE_INVALID, clear_table((unsigned long *) page_table, _PAGE_INVALID,
...@@ -138,7 +145,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore) ...@@ -138,7 +145,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
return -ENOMEM; return -ENOMEM;
} }
void vdso_free_per_cpu(struct _lowcore *lowcore) void vdso_free_per_cpu(struct lowcore *lowcore)
{ {
unsigned long segment_table, page_table, page_frame; unsigned long segment_table, page_table, page_frame;
u32 *psal, *aste; u32 *psal, *aste;
...@@ -163,7 +170,7 @@ static void vdso_init_cr5(void) ...@@ -163,7 +170,7 @@ static void vdso_init_cr5(void)
if (!vdso_enabled) if (!vdso_enabled)
return; return;
cr5 = offsetof(struct _lowcore, paste); cr5 = offsetof(struct lowcore, paste);
__ctl_load(cr5, 5, 5); __ctl_load(cr5, 5, 5);
} }
...@@ -299,8 +306,6 @@ static int __init vdso_init(void) ...@@ -299,8 +306,6 @@ static int __init vdso_init(void)
get_page(virt_to_page(vdso_data)); get_page(virt_to_page(vdso_data));
smp_mb();
return 0; return 0;
} }
early_initcall(vdso_init); early_initcall(vdso_init);
# List of files in the vdso, has to be asm only for now # List of files in the vdso, has to be asm only for now
obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o obj-vdso32 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
# Build rules # Build rules
......
/*
* Userland implementation of getcpu() for 32 bits processes in a
* s390 kernel for use in the vDSO
*
* Copyright IBM Corp. 2016
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <asm/vdso.h>
#include <asm/asm-offsets.h>
.text
.align 4
.globl __kernel_getcpu
.type __kernel_getcpu,@function
__kernel_getcpu:
.cfi_startproc
ear %r1,%a4
lhi %r4,1
sll %r4,24
sar %a4,%r4
la %r4,0
epsw %r0,0
sacf 512
l %r5,__VDSO_CPU_NR(%r4)
l %r4,__VDSO_NODE_ID(%r4)
tml %r0,0x4000
jo 1f
tml %r0,0x8000
jno 0f
sacf 256
j 1f
0: sacf 0
1: sar %a4,%r1
ltr %r2,%r2
jz 2f
st %r5,0(%r2)
2: ltr %r3,%r3
jz 3f
st %r4,0(%r3)
3: lhi %r2,0
br %r14
.cfi_endproc
.size __kernel_getcpu,.-__kernel_getcpu
...@@ -132,6 +132,7 @@ VERSION ...@@ -132,6 +132,7 @@ VERSION
__kernel_gettimeofday; __kernel_gettimeofday;
__kernel_clock_gettime; __kernel_clock_gettime;
__kernel_clock_getres; __kernel_clock_getres;
__kernel_getcpu;
local: *; local: *;
}; };
......
# List of files in the vdso, has to be asm only for now # List of files in the vdso, has to be asm only for now
obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o obj-vdso64 = gettimeofday.o clock_getres.o clock_gettime.o note.o getcpu.o
# Build rules # Build rules
......
/*
* Userland implementation of getcpu() for 64 bits processes in a
* s390 kernel for use in the vDSO
*
* Copyright IBM Corp. 2016
* Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
*/
#include <asm/vdso.h>
#include <asm/asm-offsets.h>
.text
.align 4
.globl __kernel_getcpu
.type __kernel_getcpu,@function
__kernel_getcpu:
.cfi_startproc
ear %r1,%a4
llilh %r4,0x0100
sar %a4,%r4
la %r4,0
epsw %r0,0
sacf 512
l %r5,__VDSO_CPU_NR(%r4)
l %r4,__VDSO_NODE_ID(%r4)
tml %r0,0x4000
jo 1f
tml %r0,0x8000
jno 0f
sacf 256
j 1f
0: sacf 0
1: sar %a4,%r1
ltgr %r2,%r2
jz 2f
st %r5,0(%r2)
2: ltgr %r3,%r3
jz 3f
st %r4,0(%r3)
3: lghi %r2,0
br %r14
.cfi_endproc
.size __kernel_getcpu,.-__kernel_getcpu
...@@ -132,6 +132,7 @@ VERSION ...@@ -132,6 +132,7 @@ VERSION
__kernel_gettimeofday; __kernel_gettimeofday;
__kernel_clock_gettime; __kernel_clock_gettime;
__kernel_clock_getres; __kernel_clock_getres;
__kernel_getcpu;
local: *; local: *;
}; };
......
...@@ -499,9 +499,9 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu) ...@@ -499,9 +499,9 @@ static int __must_check __deliver_restart(struct kvm_vcpu *vcpu)
trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0); trace_kvm_s390_deliver_interrupt(vcpu->vcpu_id, KVM_S390_RESTART, 0, 0);
rc = write_guest_lc(vcpu, rc = write_guest_lc(vcpu,
offsetof(struct _lowcore, restart_old_psw), offsetof(struct lowcore, restart_old_psw),
&vcpu->arch.sie_block->gpsw, sizeof(psw_t)); &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
rc |= read_guest_lc(vcpu, offsetof(struct _lowcore, restart_psw), rc |= read_guest_lc(vcpu, offsetof(struct lowcore, restart_psw),
&vcpu->arch.sie_block->gpsw, sizeof(psw_t)); &vcpu->arch.sie_block->gpsw, sizeof(psw_t));
clear_bit(IRQ_PEND_RESTART, &li->pending_irqs); clear_bit(IRQ_PEND_RESTART, &li->pending_irqs);
return rc ? -EFAULT : 0; return rc ? -EFAULT : 0;
......
...@@ -2400,37 +2400,37 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa) ...@@ -2400,37 +2400,37 @@ int kvm_s390_store_status_unloaded(struct kvm_vcpu *vcpu, unsigned long gpa)
u64 clkcomp; u64 clkcomp;
int rc; int rc;
px = kvm_s390_get_prefix(vcpu);
if (gpa == KVM_S390_STORE_STATUS_NOADDR) { if (gpa == KVM_S390_STORE_STATUS_NOADDR) {
if (write_guest_abs(vcpu, 163, &archmode, 1)) if (write_guest_abs(vcpu, 163, &archmode, 1))
return -EFAULT; return -EFAULT;
gpa = SAVE_AREA_BASE; gpa = 0;
} else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) { } else if (gpa == KVM_S390_STORE_STATUS_PREFIXED) {
if (write_guest_real(vcpu, 163, &archmode, 1)) if (write_guest_real(vcpu, 163, &archmode, 1))
return -EFAULT; return -EFAULT;
gpa = kvm_s390_real_to_abs(vcpu, SAVE_AREA_BASE); gpa = px;
} } else
rc = write_guest_abs(vcpu, gpa + offsetof(struct save_area, fp_regs), gpa -= __LC_FPREGS_SAVE_AREA;
rc = write_guest_abs(vcpu, gpa + __LC_FPREGS_SAVE_AREA,
vcpu->arch.guest_fpregs.fprs, 128); vcpu->arch.guest_fpregs.fprs, 128);
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, gp_regs), rc |= write_guest_abs(vcpu, gpa + __LC_GPREGS_SAVE_AREA,
vcpu->run->s.regs.gprs, 128); vcpu->run->s.regs.gprs, 128);
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, psw), rc |= write_guest_abs(vcpu, gpa + __LC_PSW_SAVE_AREA,
&vcpu->arch.sie_block->gpsw, 16); &vcpu->arch.sie_block->gpsw, 16);
px = kvm_s390_get_prefix(vcpu); rc |= write_guest_abs(vcpu, gpa + __LC_PREFIX_SAVE_AREA,
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, pref_reg),
&px, 4); &px, 4);
rc |= write_guest_abs(vcpu, rc |= write_guest_abs(vcpu, gpa + __LC_FP_CREG_SAVE_AREA,
gpa + offsetof(struct save_area, fp_ctrl_reg),
&vcpu->arch.guest_fpregs.fpc, 4); &vcpu->arch.guest_fpregs.fpc, 4);
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, tod_reg), rc |= write_guest_abs(vcpu, gpa + __LC_TOD_PROGREG_SAVE_AREA,
&vcpu->arch.sie_block->todpr, 4); &vcpu->arch.sie_block->todpr, 4);
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, timer), rc |= write_guest_abs(vcpu, gpa + __LC_CPU_TIMER_SAVE_AREA,
&vcpu->arch.sie_block->cputm, 8); &vcpu->arch.sie_block->cputm, 8);
clkcomp = vcpu->arch.sie_block->ckc >> 8; clkcomp = vcpu->arch.sie_block->ckc >> 8;
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, clk_cmp), rc |= write_guest_abs(vcpu, gpa + __LC_CLOCK_COMP_SAVE_AREA,
&clkcomp, 8); &clkcomp, 8);
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, acc_regs), rc |= write_guest_abs(vcpu, gpa + __LC_AREGS_SAVE_AREA,
&vcpu->run->s.regs.acrs, 64); &vcpu->run->s.regs.acrs, 64);
rc |= write_guest_abs(vcpu, gpa + offsetof(struct save_area, ctrl_regs), rc |= write_guest_abs(vcpu, gpa + __LC_CREGS_SAVE_AREA,
&vcpu->arch.sie_block->gcr, 128); &vcpu->arch.sie_block->gcr, 128);
return rc ? -EFAULT : 0; return rc ? -EFAULT : 0;
} }
......
...@@ -355,7 +355,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu) ...@@ -355,7 +355,7 @@ static int handle_stfl(struct kvm_vcpu *vcpu)
* into a u32 memory representation. They will remain bits 0-31. * into a u32 memory representation. They will remain bits 0-31.
*/ */
fac = *vcpu->kvm->arch.model.fac->list >> 32; fac = *vcpu->kvm->arch.model.fac->list >> 32;
rc = write_guest_lc(vcpu, offsetof(struct _lowcore, stfl_fac_list), rc = write_guest_lc(vcpu, offsetof(struct lowcore, stfl_fac_list),
&fac, sizeof(fac)); &fac, sizeof(fac));
if (rc) if (rc)
return rc; return rc;
......
...@@ -37,12 +37,22 @@ static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old) ...@@ -37,12 +37,22 @@ static inline void _raw_compare_and_delay(unsigned int *lock, unsigned int old)
asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock)); asm(".insn rsy,0xeb0000000022,%0,0,%1" : : "d" (old), "Q" (*lock));
} }
static inline int cpu_is_preempted(int cpu)
{
if (test_cpu_flag_of(CIF_ENABLED_WAIT, cpu))
return 0;
if (smp_vcpu_scheduled(cpu))
return 0;
return 1;
}
void arch_spin_lock_wait(arch_spinlock_t *lp) void arch_spin_lock_wait(arch_spinlock_t *lp)
{ {
unsigned int cpu = SPINLOCK_LOCKVAL; unsigned int cpu = SPINLOCK_LOCKVAL;
unsigned int owner; unsigned int owner;
int count; int count, first_diag;
first_diag = 1;
while (1) { while (1) {
owner = ACCESS_ONCE(lp->lock); owner = ACCESS_ONCE(lp->lock);
/* Try to get the lock if it is free. */ /* Try to get the lock if it is free. */
...@@ -51,9 +61,10 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) ...@@ -51,9 +61,10 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
return; return;
continue; continue;
} }
/* Check if the lock owner is running. */ /* First iteration: check if the lock owner is running. */
if (!smp_vcpu_scheduled(~owner)) { if (first_diag && cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner); smp_yield_cpu(~owner);
first_diag = 0;
continue; continue;
} }
/* Loop for a while on the lock value. */ /* Loop for a while on the lock value. */
...@@ -67,10 +78,13 @@ void arch_spin_lock_wait(arch_spinlock_t *lp) ...@@ -67,10 +78,13 @@ void arch_spin_lock_wait(arch_spinlock_t *lp)
continue; continue;
/* /*
* For multiple layers of hypervisors, e.g. z/VM + LPAR * For multiple layers of hypervisors, e.g. z/VM + LPAR
* yield the CPU if the lock is still unavailable. * yield the CPU unconditionally. For LPAR rely on the
* sense running status.
*/ */
if (!MACHINE_IS_LPAR) if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner); smp_yield_cpu(~owner);
first_diag = 0;
}
} }
} }
EXPORT_SYMBOL(arch_spin_lock_wait); EXPORT_SYMBOL(arch_spin_lock_wait);
...@@ -79,9 +93,10 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) ...@@ -79,9 +93,10 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
{ {
unsigned int cpu = SPINLOCK_LOCKVAL; unsigned int cpu = SPINLOCK_LOCKVAL;
unsigned int owner; unsigned int owner;
int count; int count, first_diag;
local_irq_restore(flags); local_irq_restore(flags);
first_diag = 1;
while (1) { while (1) {
owner = ACCESS_ONCE(lp->lock); owner = ACCESS_ONCE(lp->lock);
/* Try to get the lock if it is free. */ /* 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,8 +107,9 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
local_irq_restore(flags); local_irq_restore(flags);
} }
/* Check if the lock owner is running. */ /* Check if the lock owner is running. */
if (!smp_vcpu_scheduled(~owner)) { if (first_diag && cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner); smp_yield_cpu(~owner);
first_diag = 0;
continue; continue;
} }
/* Loop for a while on the lock value. */ /* 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,10 +123,13 @@ void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags)
continue; continue;
/* /*
* For multiple layers of hypervisors, e.g. z/VM + LPAR * For multiple layers of hypervisors, e.g. z/VM + LPAR
* yield the CPU if the lock is still unavailable. * yield the CPU unconditionally. For LPAR rely on the
* sense running status.
*/ */
if (!MACHINE_IS_LPAR) if (!MACHINE_IS_LPAR || cpu_is_preempted(~owner)) {
smp_yield_cpu(~owner); smp_yield_cpu(~owner);
first_diag = 0;
}
} }
} }
EXPORT_SYMBOL(arch_spin_lock_wait_flags); EXPORT_SYMBOL(arch_spin_lock_wait_flags);
...@@ -145,7 +164,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw) ...@@ -145,7 +164,7 @@ void _raw_read_lock_wait(arch_rwlock_t *rw)
owner = 0; owner = 0;
while (1) { while (1) {
if (count-- <= 0) { if (count-- <= 0) {
if (owner && !smp_vcpu_scheduled(~owner)) if (owner && cpu_is_preempted(~owner))
smp_yield_cpu(~owner); smp_yield_cpu(~owner);
count = spin_retry; count = spin_retry;
} }
...@@ -191,7 +210,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev) ...@@ -191,7 +210,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw, unsigned int prev)
owner = 0; owner = 0;
while (1) { while (1) {
if (count-- <= 0) { if (count-- <= 0) {
if (owner && !smp_vcpu_scheduled(~owner)) if (owner && cpu_is_preempted(~owner))
smp_yield_cpu(~owner); smp_yield_cpu(~owner);
count = spin_retry; count = spin_retry;
} }
...@@ -221,7 +240,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw) ...@@ -221,7 +240,7 @@ void _raw_write_lock_wait(arch_rwlock_t *rw)
owner = 0; owner = 0;
while (1) { while (1) {
if (count-- <= 0) { if (count-- <= 0) {
if (owner && !smp_vcpu_scheduled(~owner)) if (owner && cpu_is_preempted(~owner))
smp_yield_cpu(~owner); smp_yield_cpu(~owner);
count = spin_retry; count = spin_retry;
} }
...@@ -265,7 +284,7 @@ void arch_lock_relax(unsigned int cpu) ...@@ -265,7 +284,7 @@ void arch_lock_relax(unsigned int cpu)
{ {
if (!cpu) if (!cpu)
return; return;
if (MACHINE_IS_LPAR && smp_vcpu_scheduled(~cpu)) if (MACHINE_IS_LPAR && !cpu_is_preempted(~cpu))
return; return;
smp_yield_cpu(~cpu); smp_yield_cpu(~cpu);
} }
......
...@@ -52,12 +52,16 @@ void sort_extable(struct exception_table_entry *start, ...@@ -52,12 +52,16 @@ void sort_extable(struct exception_table_entry *start,
int i; int i;
/* Normalize entries to being relative to the start of the section */ /* Normalize entries to being relative to the start of the section */
for (p = start, i = 0; p < finish; p++, i += 8) for (p = start, i = 0; p < finish; p++, i += 8) {
p->insn += i; p->insn += i;
p->fixup += i + 4;
}
sort(start, finish - start, sizeof(*start), cmp_ex, NULL); sort(start, finish - start, sizeof(*start), cmp_ex, NULL);
/* Denormalize all entries */ /* Denormalize all entries */
for (p = start, i = 0; p < finish; p++, i += 8) for (p = start, i = 0; p < finish; p++, i += 8) {
p->insn -= i; p->insn -= i;
p->fixup -= i + 4;
}
} }
#ifdef CONFIG_MODULES #ifdef CONFIG_MODULES
......
...@@ -94,7 +94,7 @@ static DEFINE_MUTEX(dcss_lock); ...@@ -94,7 +94,7 @@ static DEFINE_MUTEX(dcss_lock);
static LIST_HEAD(dcss_list); static LIST_HEAD(dcss_list);
static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
"EW/EN-MIXED" }; "EW/EN-MIXED" };
static int loadshr_scode, loadnsr_scode, findseg_scode; static int loadshr_scode, loadnsr_scode;
static int segext_scode, purgeseg_scode; static int segext_scode, purgeseg_scode;
static int scode_set; static int scode_set;
...@@ -130,7 +130,6 @@ dcss_set_subcodes(void) ...@@ -130,7 +130,6 @@ dcss_set_subcodes(void)
loadshr_scode = DCSS_LOADSHRX; loadshr_scode = DCSS_LOADSHRX;
loadnsr_scode = DCSS_LOADNSRX; loadnsr_scode = DCSS_LOADNSRX;
purgeseg_scode = DCSS_PURGESEG; purgeseg_scode = DCSS_PURGESEG;
findseg_scode = DCSS_FINDSEGX;
segext_scode = DCSS_SEGEXTX; segext_scode = DCSS_SEGEXTX;
return 0; return 0;
} }
...@@ -138,7 +137,6 @@ dcss_set_subcodes(void) ...@@ -138,7 +137,6 @@ dcss_set_subcodes(void)
loadshr_scode = DCSS_LOADNOLY; loadshr_scode = DCSS_LOADNOLY;
loadnsr_scode = DCSS_LOADNSR; loadnsr_scode = DCSS_LOADNSR;
purgeseg_scode = DCSS_PURGESEG; purgeseg_scode = DCSS_PURGESEG;
findseg_scode = DCSS_FINDSEG;
segext_scode = DCSS_SEGEXT; segext_scode = DCSS_SEGEXT;
return 0; return 0;
} }
......
...@@ -254,7 +254,6 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code) ...@@ -254,7 +254,6 @@ static noinline void do_sigsegv(struct pt_regs *regs, int si_code)
static noinline void do_no_context(struct pt_regs *regs) static noinline void do_no_context(struct pt_regs *regs)
{ {
const struct exception_table_entry *fixup; const struct exception_table_entry *fixup;
unsigned long address;
/* Are we prepared to handle this kernel fault? */ /* Are we prepared to handle this kernel fault? */
fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 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,7 +266,6 @@ static noinline void do_no_context(struct pt_regs *regs)
* Oops. The kernel tried to access some bad page. We'll have to * Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice. * terminate things with extreme prejudice.
*/ */
address = regs->int_parm_long & __FAIL_ADDR_MASK;
if (!user_space_fault(regs)) if (!user_space_fault(regs))
printk(KERN_ALERT "Unable to handle kernel pointer dereference" printk(KERN_ALERT "Unable to handle kernel pointer dereference"
" in virtual kernel address space\n"); " in virtual kernel address space\n");
......
...@@ -233,6 +233,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write, ...@@ -233,6 +233,7 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
struct mm_struct *mm = current->mm; struct mm_struct *mm = current->mm;
int nr, ret; int nr, ret;
might_sleep();
start &= PAGE_MASK; start &= PAGE_MASK;
nr = __get_user_pages_fast(start, nr_pages, write, pages); nr = __get_user_pages_fast(start, nr_pages, write, pages);
if (nr == nr_pages) if (nr == nr_pages)
......
...@@ -163,11 +163,11 @@ static int is_swapped(unsigned long addr) ...@@ -163,11 +163,11 @@ static int is_swapped(unsigned long addr)
unsigned long lc; unsigned long lc;
int cpu; int cpu;
if (addr < sizeof(struct _lowcore)) if (addr < sizeof(struct lowcore))
return 1; return 1;
for_each_online_cpu(cpu) { for_each_online_cpu(cpu) {
lc = (unsigned long) lowcore_ptr[cpu]; lc = (unsigned long) lowcore_ptr[cpu];
if (addr > lc + sizeof(struct _lowcore) - 1 || addr < lc) if (addr > lc + sizeof(struct lowcore) - 1 || addr < lc)
continue; continue;
return 1; return 1;
} }
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
#include <asm/sclp.h> #include <asm/sclp.h>
#include <asm/setup.h> #include <asm/setup.h>
#define ADDR2G (1ULL << 31)
#define CHUNK_READ_WRITE 0 #define CHUNK_READ_WRITE 0
#define CHUNK_READ_ONLY 1 #define CHUNK_READ_ONLY 1
...@@ -27,15 +25,14 @@ static inline void memblock_physmem_add(phys_addr_t start, phys_addr_t size) ...@@ -27,15 +25,14 @@ static inline void memblock_physmem_add(phys_addr_t start, phys_addr_t size)
void __init detect_memory_memblock(void) void __init detect_memory_memblock(void)
{ {
unsigned long long memsize, rnmax, rzm; unsigned long memsize, rnmax, rzm, addr, size;
unsigned long addr, size;
int type; int type;
rzm = sclp.rzm; rzm = sclp.rzm;
rnmax = sclp.rnmax; rnmax = sclp.rnmax;
memsize = rzm * rnmax; memsize = rzm * rnmax;
if (!rzm) if (!rzm)
rzm = 1ULL << 17; rzm = 1UL << 17;
max_physmem_end = memsize; max_physmem_end = memsize;
addr = 0; addr = 0;
/* keep memblock lists close to the kernel */ /* keep memblock lists close to the kernel */
......
...@@ -701,8 +701,7 @@ static int zpci_restore(struct device *dev) ...@@ -701,8 +701,7 @@ static int zpci_restore(struct device *dev)
goto out; goto out;
zpci_map_resources(pdev); zpci_map_resources(pdev);
zpci_register_ioat(zdev, 0, zdev->start_dma + PAGE_OFFSET, zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
zdev->start_dma + zdev->iommu_size - 1,
(u64) zdev->dma_table); (u64) zdev->dma_table);
out: out:
......
...@@ -457,7 +457,19 @@ int zpci_dma_init_device(struct zpci_dev *zdev) ...@@ -457,7 +457,19 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
goto out_clean; goto out_clean;
} }
zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET; /*
* Restrict the iommu bitmap size to the minimum of the following:
* - main memory size
* - 3-level pagetable address limit minus start_dma offset
* - DMA address range allowed by the hardware (clp query pci fn)
*
* Also set zdev->end_dma to the actual end address of the usable
* range, instead of the theoretical maximum as reported by hardware.
*/
zdev->iommu_size = min3((u64) high_memory,
ZPCI_TABLE_SIZE_RT - zdev->start_dma,
zdev->end_dma - zdev->start_dma + 1);
zdev->end_dma = zdev->start_dma + zdev->iommu_size - 1;
zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT; zdev->iommu_pages = zdev->iommu_size >> PAGE_SHIFT;
zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
if (!zdev->iommu_bitmap) { if (!zdev->iommu_bitmap) {
...@@ -465,10 +477,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) ...@@ -465,10 +477,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
goto out_reg; goto out_reg;
} }
rc = zpci_register_ioat(zdev, rc = zpci_register_ioat(zdev, 0, zdev->start_dma, zdev->end_dma,
0,
zdev->start_dma + PAGE_OFFSET,
zdev->start_dma + zdev->iommu_size - 1,
(u64) zdev->dma_table); (u64) zdev->dma_table);
if (rc) if (rc)
goto out_reg; goto out_reg;
......
#
# Makefile for s390 specific build tools
#
hostprogs-y += gen_facilities
HOSTCFLAGS_gen_facilities.o += -Wall $(LINUXINCLUDE)
define filechk_facilities.h
$(obj)/gen_facilities
endef
$(obj)/gen_facilities.o: $(srctree)/arch/s390/tools/gen_facilities.c
include/generated/facilities.h: $(obj)/gen_facilities FORCE
$(call filechk,facilities.h)
/*
* Simple program to generate defines out of facility lists that use the bit
* numbering scheme from the Princples of Operations: most significant bit
* has bit number 0.
*
* Copyright IBM Corp. 2015
*
*/
#define S390_GEN_FACILITIES_C
#include <strings.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <asm/facilities_src.h>
static void print_facility_list(struct facility_def *def)
{
unsigned int high, bit, dword, i;
unsigned long long *array;
array = calloc(1, 8);
if (!array)
exit(EXIT_FAILURE);
high = 0;
for (i = 0; def->bits[i] != -1; i++) {
bit = 63 - (def->bits[i] & 63);
dword = def->bits[i] / 64;
if (dword > high) {
array = realloc(array, (dword + 1) * 8);
if (!array)
exit(EXIT_FAILURE);
memset(array + high + 1, 0, (dword - high) * 8);
high = dword;
}
array[dword] |= 1ULL << bit;
}
printf("#define %s ", def->name);
for (i = 0; i <= high; i++)
printf("_AC(0x%016llx,UL)%c", array[i], i < high ? ',' : '\n');
printf("#define %s_DWORDS %d\n", def->name, high + 1);
free(array);
}
static void print_facility_lists(void)
{
unsigned int i;
for (i = 0; i < sizeof(facility_defs) / sizeof(facility_defs[0]); i++)
print_facility_list(&facility_defs[i]);
}
int main(int argc, char **argv)
{
printf("#ifndef __ASM_S390_FACILITIES__\n");
printf("#define __ASM_S390_FACILITIES__\n");
printf("/*\n");
printf(" * DO NOT MODIFY.\n");
printf(" *\n");
printf(" * This file was generated by %s\n", __FILE__);
printf(" */\n\n");
printf("#include <linux/const.h>\n\n");
print_facility_lists();
printf("\n#endif\n");
return 0;
}
...@@ -2556,8 +2556,12 @@ static void __dasd_process_request_queue(struct dasd_block *block) ...@@ -2556,8 +2556,12 @@ static void __dasd_process_request_queue(struct dasd_block *block)
return; return;
} }
/* if device ist stopped do not fetch new requests */ /*
if (basedev->stopped) * if device is stopped do not fetch new requests
* except failfast is active which will let requests fail
* immediately in __dasd_block_start_head()
*/
if (basedev->stopped && !(basedev->features & DASD_FEATURE_FAILFAST))
return; return;
/* Now we try to fetch requests from the request queue */ /* Now we try to fetch requests from the request queue */
......
...@@ -78,19 +78,6 @@ config SCLP_VT220_CONSOLE ...@@ -78,19 +78,6 @@ config SCLP_VT220_CONSOLE
Include support for using an IBM SCLP VT220-compatible terminal as a Include support for using an IBM SCLP VT220-compatible terminal as a
Linux system console. Linux system console.
config SCLP_CPI
def_tristate m
prompt "Control-Program Identification"
depends on S390
help
This option enables the hardware console interface for system
identification. This is commonly used for workload management and
gives you a nice name for the system on the service element.
Please select this option as a module since built-in operation is
completely untested.
You should only select this option if you know what you are doing,
need this feature and intend to run your kernel in LPAR.
config SCLP_ASYNC config SCLP_ASYNC
def_tristate m def_tristate m
prompt "Support for Call Home via Asynchronous SCLP Records" prompt "Support for Call Home via Asynchronous SCLP Records"
...@@ -125,6 +112,14 @@ config HMC_DRV ...@@ -125,6 +112,14 @@ config HMC_DRV
transfer cache size from it's default value 0.5MB to N bytes. If N transfer cache size from it's default value 0.5MB to N bytes. If N
is zero, then no caching is performed. is zero, then no caching is performed.
config SCLP_OFB
def_bool n
prompt "Support for Open-for-Business SCLP Event"
depends on S390
help
This option enables the Open-for-Business interface to the s390
Service Element.
config S390_TAPE config S390_TAPE
def_tristate m def_tristate m
prompt "S/390 tape device support" prompt "S/390 tape device support"
......
...@@ -16,7 +16,6 @@ obj-$(CONFIG_TN3215) += con3215.o ...@@ -16,7 +16,6 @@ obj-$(CONFIG_TN3215) += con3215.o
obj-$(CONFIG_SCLP_TTY) += sclp_tty.o obj-$(CONFIG_SCLP_TTY) += sclp_tty.o
obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o obj-$(CONFIG_SCLP_CONSOLE) += sclp_con.o
obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o obj-$(CONFIG_SCLP_VT220_TTY) += sclp_vt220.o
obj-$(CONFIG_SCLP_CPI) += sclp_cpi.o
obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o obj-$(CONFIG_SCLP_ASYNC) += sclp_async.o
obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o obj-$(CONFIG_VMLOGRDR) += vmlogrdr.o
...@@ -30,9 +29,7 @@ obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o ...@@ -30,9 +29,7 @@ obj-$(CONFIG_S390_TAPE_3590) += tape_3590.o
obj-$(CONFIG_MONREADER) += monreader.o obj-$(CONFIG_MONREADER) += monreader.o
obj-$(CONFIG_MONWRITER) += monwriter.o obj-$(CONFIG_MONWRITER) += monwriter.o
obj-$(CONFIG_S390_VMUR) += vmur.o obj-$(CONFIG_S390_VMUR) += vmur.o
obj-$(CONFIG_CRASH_DUMP) += sclp_sdias.o zcore.o
zcore_mod-objs := sclp_sdias.o zcore.o
obj-$(CONFIG_CRASH_DUMP) += zcore_mod.o
hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o hmcdrv-objs := hmcdrv_mod.o hmcdrv_dev.o hmcdrv_ftp.o hmcdrv_cache.o diag_ftp.o sclp_ftp.o
obj-$(CONFIG_HMC_DRV) += hmcdrv.o obj-$(CONFIG_HMC_DRV) += hmcdrv.o
...@@ -922,6 +922,8 @@ static int __init con3215_init(void) ...@@ -922,6 +922,8 @@ static int __init con3215_init(void)
spin_lock_init(&raw3215_freelist_lock); spin_lock_init(&raw3215_freelist_lock);
for (i = 0; i < NR_3215_REQ; i++) { for (i = 0; i < NR_3215_REQ; i++) {
req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA);
if (!req)
return -ENOMEM;
req->next = raw3215_freelist; req->next = raw3215_freelist;
raw3215_freelist = req; raw3215_freelist = req;
} }
......
...@@ -606,6 +606,8 @@ con3270_init(void) ...@@ -606,6 +606,8 @@ con3270_init(void)
return PTR_ERR(rp); return PTR_ERR(rp);
condev = kzalloc(sizeof(struct con3270), GFP_KERNEL | GFP_DMA); condev = kzalloc(sizeof(struct con3270), GFP_KERNEL | GFP_DMA);
if (!condev)
return -ENOMEM;
condev->view.dev = rp; condev->view.dev = rp;
condev->read = raw3270_request_alloc(0); condev->read = raw3270_request_alloc(0);
......
...@@ -37,7 +37,7 @@ struct hmcdrv_ftp_ops { ...@@ -37,7 +37,7 @@ struct hmcdrv_ftp_ops {
static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len); static enum hmcdrv_ftp_cmdid hmcdrv_ftp_cmd_getid(const char *cmd, int len);
static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp); static int hmcdrv_ftp_parse(char *cmd, struct hmcdrv_ftp_cmdspec *ftp);
static struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */ static const struct hmcdrv_ftp_ops *hmcdrv_ftp_funcs; /* current operations */
static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */ static DEFINE_MUTEX(hmcdrv_ftp_mutex); /* mutex for hmcdrv_ftp_funcs */
static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */ static unsigned hmcdrv_ftp_refcnt; /* start/shutdown reference counter */
...@@ -290,13 +290,13 @@ ssize_t hmcdrv_ftp_cmd(char __kernel *cmd, loff_t offset, ...@@ -290,13 +290,13 @@ ssize_t hmcdrv_ftp_cmd(char __kernel *cmd, loff_t offset,
*/ */
int hmcdrv_ftp_startup(void) int hmcdrv_ftp_startup(void)
{ {
static struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = { static const struct hmcdrv_ftp_ops hmcdrv_ftp_zvm = {
.startup = diag_ftp_startup, .startup = diag_ftp_startup,
.shutdown = diag_ftp_shutdown, .shutdown = diag_ftp_shutdown,
.transfer = diag_ftp_cmd .transfer = diag_ftp_cmd
}; };
static struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = { static const struct hmcdrv_ftp_ops hmcdrv_ftp_lpar = {
.startup = sclp_ftp_startup, .startup = sclp_ftp_startup,
.shutdown = sclp_ftp_shutdown, .shutdown = sclp_ftp_shutdown,
.transfer = sclp_ftp_cmd .transfer = sclp_ftp_cmd
......
...@@ -579,9 +579,8 @@ sclp_sync_wait(void) ...@@ -579,9 +579,8 @@ sclp_sync_wait(void)
old_tick = local_tick_disable(); old_tick = local_tick_disable();
trace_hardirqs_on(); trace_hardirqs_on();
__ctl_store(cr0, 0, 0); __ctl_store(cr0, 0, 0);
cr0_sync = cr0; cr0_sync = cr0 & ~CR0_IRQ_SUBCLASS_MASK;
cr0_sync &= 0xffff00a0; cr0_sync |= 1UL << (63 - 54);
cr0_sync |= 0x00000200;
__ctl_load(cr0_sync, 0, 0); __ctl_load(cr0_sync, 0, 0);
__arch_local_irq_stosm(0x01); __arch_local_irq_stosm(0x01);
/* Loop until driver state indicates finished request */ /* Loop until driver state indicates finished request */
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <asm/smp.h> #include <asm/smp.h>
#include "sclp.h" #include "sclp.h"
...@@ -20,8 +22,22 @@ struct conf_mgm_data { ...@@ -20,8 +22,22 @@ struct conf_mgm_data {
u8 ev_qualifier; u8 ev_qualifier;
} __attribute__((packed)); } __attribute__((packed));
#define OFB_DATA_MAX 64
struct sclp_ofb_evbuf {
struct evbuf_header header;
struct conf_mgm_data cm_data;
char ev_data[OFB_DATA_MAX];
} __packed;
struct sclp_ofb_sccb {
struct sccb_header header;
struct sclp_ofb_evbuf ofb_evbuf;
} __packed;
#define EV_QUAL_CPU_CHANGE 1 #define EV_QUAL_CPU_CHANGE 1
#define EV_QUAL_CAP_CHANGE 3 #define EV_QUAL_CAP_CHANGE 3
#define EV_QUAL_OPEN4BUSINESS 5
static struct work_struct sclp_cpu_capability_work; static struct work_struct sclp_cpu_capability_work;
static struct work_struct sclp_cpu_change_work; static struct work_struct sclp_cpu_change_work;
...@@ -63,15 +79,99 @@ static void sclp_conf_receiver_fn(struct evbuf_header *evbuf) ...@@ -63,15 +79,99 @@ static void sclp_conf_receiver_fn(struct evbuf_header *evbuf)
static struct sclp_register sclp_conf_register = static struct sclp_register sclp_conf_register =
{ {
#ifdef CONFIG_SCLP_OFB
.send_mask = EVTYP_CONFMGMDATA_MASK,
#endif
.receive_mask = EVTYP_CONFMGMDATA_MASK, .receive_mask = EVTYP_CONFMGMDATA_MASK,
.receiver_fn = sclp_conf_receiver_fn, .receiver_fn = sclp_conf_receiver_fn,
}; };
#ifdef CONFIG_SCLP_OFB
static int sclp_ofb_send_req(char *ev_data, size_t len)
{
static DEFINE_MUTEX(send_mutex);
struct sclp_ofb_sccb *sccb;
int rc, response;
if (len > OFB_DATA_MAX)
return -EINVAL;
sccb = (struct sclp_ofb_sccb *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
if (!sccb)
return -ENOMEM;
/* Setup SCCB for Control-Program Identification */
sccb->header.length = sizeof(struct sclp_ofb_sccb);
sccb->ofb_evbuf.header.length = sizeof(struct sclp_ofb_evbuf);
sccb->ofb_evbuf.header.type = EVTYP_CONFMGMDATA;
sccb->ofb_evbuf.cm_data.ev_qualifier = EV_QUAL_OPEN4BUSINESS;
memcpy(sccb->ofb_evbuf.ev_data, ev_data, len);
if (!(sclp_conf_register.sclp_receive_mask & EVTYP_CONFMGMDATA_MASK))
pr_warn("SCLP receiver did not register to receive "
"Configuration Management Data Events.\n");
mutex_lock(&send_mutex);
rc = sclp_sync_request(SCLP_CMDW_WRITE_EVENT_DATA, sccb);
mutex_unlock(&send_mutex);
if (rc)
goto out;
response = sccb->header.response_code;
if (response != 0x0020) {
pr_err("Open for Business request failed with response code "
"0x%04x\n", response);
rc = -EIO;
}
out:
free_page((unsigned long)sccb);
return rc;
}
static ssize_t sysfs_ofb_data_write(struct file *filp, struct kobject *kobj,
struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
int rc;
rc = sclp_ofb_send_req(buf, count);
return rc ?: count;
}
static struct bin_attribute ofb_bin_attr = {
.attr = {
.name = "event_data",
.mode = S_IWUSR,
},
.write = sysfs_ofb_data_write,
};
#endif
static int __init sclp_ofb_setup(void)
{
#ifdef CONFIG_SCLP_OFB
struct kset *ofb_kset;
int rc;
ofb_kset = kset_create_and_add("ofb", NULL, firmware_kobj);
if (!ofb_kset)
return -ENOMEM;
rc = sysfs_create_bin_file(&ofb_kset->kobj, &ofb_bin_attr);
if (rc) {
kset_unregister(ofb_kset);
return rc;
}
#endif
return 0;
}
static int __init sclp_conf_init(void) static int __init sclp_conf_init(void)
{ {
int rc;
INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify); INIT_WORK(&sclp_cpu_capability_work, sclp_cpu_capability_notify);
INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify); INIT_WORK(&sclp_cpu_change_work, sclp_cpu_change_notify);
return sclp_register(&sclp_conf_register); rc = sclp_register(&sclp_conf_register);
if (rc)
return rc;
return sclp_ofb_setup();
} }
__initcall(sclp_conf_init); __initcall(sclp_conf_init);
/*
* SCLP control programm identification
*
* Copyright IBM Corp. 2001, 2007
* Author(s): Martin Peschke <mpeschke@de.ibm.com>
* Michael Ernst <mernst@de.ibm.com>
*/
#include <linux/kmod.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/version.h>
#include "sclp_cpi_sys.h"
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Identify this operating system instance "
"to the System z hardware");
MODULE_AUTHOR("Martin Peschke <mpeschke@de.ibm.com>, "
"Michael Ernst <mernst@de.ibm.com>");
static char *system_name = "";
static char *sysplex_name = "";
module_param(system_name, charp, 0);
MODULE_PARM_DESC(system_name, "e.g. hostname - max. 8 characters");
module_param(sysplex_name, charp, 0);
MODULE_PARM_DESC(sysplex_name, "if applicable - max. 8 characters");
static int __init cpi_module_init(void)
{
return sclp_cpi_set_data(system_name, sysplex_name, "LINUX",
LINUX_VERSION_CODE);
}
static void __exit cpi_module_exit(void)
{
}
module_init(cpi_module_init);
module_exit(cpi_module_exit);
This diff is collapsed.
...@@ -2,8 +2,11 @@ ...@@ -2,8 +2,11 @@
# Makefile for the S/390 common i/o drivers # Makefile for the S/390 common i/o drivers
# #
# The following is required for define_trace.h to find ./trace.h
CFLAGS_trace.o := -I$(src)
obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \ obj-y += airq.o blacklist.o chsc.o cio.o css.o chp.o idset.o isc.o \
fcx.o itcw.o crw.o ccwreq.o fcx.o itcw.o crw.o ccwreq.o trace.o ioasm.o
ccw_device-objs += device.o device_fsm.o device_ops.o ccw_device-objs += device.o device_fsm.o device_ops.o
ccw_device-objs += device_id.o device_pgid.o device_status.o ccw_device-objs += device_id.o device_pgid.o device_status.o
obj-y += ccw_device.o cmf.o obj-y += ccw_device.o cmf.o
......
...@@ -89,6 +89,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy) ...@@ -89,6 +89,7 @@ static irqreturn_t do_airq_interrupt(int irq, void *dummy)
set_cpu_flag(CIF_NOHZ_DELAY); set_cpu_flag(CIF_NOHZ_DELAY);
tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
trace_s390_cio_adapter_int(tpi_info);
head = &airq_lists[tpi_info->isc]; head = &airq_lists[tpi_info->isc];
rcu_read_lock(); rcu_read_lock();
hlist_for_each_entry_rcu(airq, head, list) hlist_for_each_entry_rcu(airq, head, list)
......
...@@ -133,7 +133,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch) ...@@ -133,7 +133,7 @@ static int chsc_subchannel_prepare(struct subchannel *sch)
* since we don't have a way to clear the subchannel and * since we don't have a way to clear the subchannel and
* cannot disable it with a request running. * cannot disable it with a request running.
*/ */
cc = stsch_err(sch->schid, &schib); cc = stsch(sch->schid, &schib);
if (!cc && scsw_stctl(&schib.scsw)) if (!cc && scsw_stctl(&schib.scsw))
return -EAGAIN; return -EAGAIN;
return 0; return 0;
...@@ -185,8 +185,7 @@ static int __init chsc_init_dbfs(void) ...@@ -185,8 +185,7 @@ static int __init chsc_init_dbfs(void)
debug_set_level(chsc_debug_log_id, 2); debug_set_level(chsc_debug_log_id, 2);
return 0; return 0;
out: out:
if (chsc_debug_msg_id) debug_unregister(chsc_debug_msg_id);
debug_unregister(chsc_debug_msg_id);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include "blacklist.h" #include "blacklist.h"
#include "cio_debug.h" #include "cio_debug.h"
#include "chp.h" #include "chp.h"
#include "trace.h"
debug_info_t *cio_debug_msg_id; debug_info_t *cio_debug_msg_id;
debug_info_t *cio_debug_trace_id; debug_info_t *cio_debug_trace_id;
...@@ -76,12 +77,9 @@ static int __init cio_debug_init(void) ...@@ -76,12 +77,9 @@ static int __init cio_debug_init(void)
return 0; return 0;
out_unregister: out_unregister:
if (cio_debug_msg_id) debug_unregister(cio_debug_msg_id);
debug_unregister(cio_debug_msg_id); debug_unregister(cio_debug_trace_id);
if (cio_debug_trace_id) debug_unregister(cio_debug_crw_id);
debug_unregister(cio_debug_trace_id);
if (cio_debug_crw_id)
debug_unregister(cio_debug_crw_id);
return -1; return -1;
} }
...@@ -348,18 +346,18 @@ int cio_commit_config(struct subchannel *sch) ...@@ -348,18 +346,18 @@ int cio_commit_config(struct subchannel *sch)
struct schib schib; struct schib schib;
struct irb irb; struct irb irb;
if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
return -ENODEV; return -ENODEV;
for (retry = 0; retry < 5; retry++) { for (retry = 0; retry < 5; retry++) {
/* copy desired changes to local schib */ /* copy desired changes to local schib */
cio_apply_config(sch, &schib); cio_apply_config(sch, &schib);
ccode = msch_err(sch->schid, &schib); ccode = msch(sch->schid, &schib);
if (ccode < 0) /* -EIO if msch gets a program check. */ if (ccode < 0) /* -EIO if msch gets a program check. */
return ccode; return ccode;
switch (ccode) { switch (ccode) {
case 0: /* successful */ case 0: /* successful */
if (stsch_err(sch->schid, &schib) || if (stsch(sch->schid, &schib) ||
!css_sch_is_valid(&schib)) !css_sch_is_valid(&schib))
return -ENODEV; return -ENODEV;
if (cio_check_config(sch, &schib)) { if (cio_check_config(sch, &schib)) {
...@@ -394,7 +392,7 @@ int cio_update_schib(struct subchannel *sch) ...@@ -394,7 +392,7 @@ int cio_update_schib(struct subchannel *sch)
{ {
struct schib schib; struct schib schib;
if (stsch_err(sch->schid, &schib) || !css_sch_is_valid(&schib)) if (stsch(sch->schid, &schib) || !css_sch_is_valid(&schib))
return -ENODEV; return -ENODEV;
memcpy(&sch->schib, &schib, sizeof(schib)); memcpy(&sch->schib, &schib, sizeof(schib));
...@@ -503,7 +501,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid) ...@@ -503,7 +501,7 @@ int cio_validate_subchannel(struct subchannel *sch, struct subchannel_id schid)
* If stsch gets an exception, it means the current subchannel set * If stsch gets an exception, it means the current subchannel set
* is not valid. * is not valid.
*/ */
ccode = stsch_err(schid, &sch->schib); ccode = stsch(schid, &sch->schib);
if (ccode) { if (ccode) {
err = (ccode == 3) ? -ENXIO : ccode; err = (ccode == 3) ? -ENXIO : ccode;
goto out; goto out;
...@@ -542,6 +540,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy) ...@@ -542,6 +540,7 @@ static irqreturn_t do_cio_interrupt(int irq, void *dummy)
set_cpu_flag(CIF_NOHZ_DELAY); set_cpu_flag(CIF_NOHZ_DELAY);
tpi_info = (struct tpi_info *) &get_irq_regs()->int_code; tpi_info = (struct tpi_info *) &get_irq_regs()->int_code;
trace_s390_cio_interrupt(tpi_info);
irb = this_cpu_ptr(&cio_irb); irb = this_cpu_ptr(&cio_irb);
sch = (struct subchannel *)(unsigned long) tpi_info->intparm; sch = (struct subchannel *)(unsigned long) tpi_info->intparm;
if (!sch) { if (!sch) {
...@@ -619,7 +618,7 @@ static int cio_test_for_console(struct subchannel_id schid, void *data) ...@@ -619,7 +618,7 @@ static int cio_test_for_console(struct subchannel_id schid, void *data)
{ {
struct schib schib; struct schib schib;
if (stsch_err(schid, &schib) != 0) if (stsch(schid, &schib) != 0)
return -ENXIO; return -ENXIO;
if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv && if ((schib.pmcw.st == SUBCHANNEL_TYPE_IO) && schib.pmcw.dnv &&
(schib.pmcw.dev == console_devno)) { (schib.pmcw.dev == console_devno)) {
...@@ -638,7 +637,7 @@ static int cio_get_console_sch_no(void) ...@@ -638,7 +637,7 @@ static int cio_get_console_sch_no(void)
if (console_irq != -1) { if (console_irq != -1) {
/* VM provided us with the irq number of the console. */ /* VM provided us with the irq number of the console. */
schid.sch_no = console_irq; schid.sch_no = console_irq;
if (stsch_err(schid, &schib) != 0 || if (stsch(schid, &schib) != 0 ||
(schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv) (schib.pmcw.st != SUBCHANNEL_TYPE_IO) || !schib.pmcw.dnv)
return -1; return -1;
console_devno = schib.pmcw.dev; console_devno = schib.pmcw.dev;
...@@ -708,10 +707,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib) ...@@ -708,10 +707,10 @@ __disable_subchannel_easy(struct subchannel_id schid, struct schib *schib)
cc = 0; cc = 0;
for (retry=0;retry<3;retry++) { for (retry=0;retry<3;retry++) {
schib->pmcw.ena = 0; schib->pmcw.ena = 0;
cc = msch_err(schid, schib); cc = msch(schid, schib);
if (cc) if (cc)
return (cc==3?-ENODEV:-EBUSY); return (cc==3?-ENODEV:-EBUSY);
if (stsch_err(schid, schib) || !css_sch_is_valid(schib)) if (stsch(schid, schib) || !css_sch_is_valid(schib))
return -ENODEV; return -ENODEV;
if (!schib->pmcw.ena) if (!schib->pmcw.ena)
return 0; return 0;
...@@ -758,7 +757,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr) ...@@ -758,7 +757,7 @@ static int stsch_reset(struct subchannel_id schid, struct schib *addr)
pgm_check_occured = 0; pgm_check_occured = 0;
s390_base_pgm_handler_fn = cio_reset_pgm_check_handler; s390_base_pgm_handler_fn = cio_reset_pgm_check_handler;
rc = stsch_err(schid, addr); rc = stsch(schid, addr);
s390_base_pgm_handler_fn = NULL; s390_base_pgm_handler_fn = NULL;
/* The program check handler could have changed pgm_check_occured. */ /* 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,7 +794,7 @@ static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
/* No default clear strategy */ /* No default clear strategy */
break; break;
} }
stsch_err(schid, &schib); stsch(schid, &schib);
__disable_subchannel_easy(schid, &schib); __disable_subchannel_easy(schid, &schib);
} }
out: out:
...@@ -917,7 +916,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid) ...@@ -917,7 +916,7 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
{ {
struct subchannel_id uninitialized_var(schid); struct subchannel_id uninitialized_var(schid);
s390_reset_system(NULL, NULL, NULL); s390_reset_system();
if (reipl_find_schid(devid, &schid) != 0) if (reipl_find_schid(devid, &schid) != 0)
panic("IPL Device not found\n"); panic("IPL Device not found\n");
do_reipl_asm(*((__u32*)&schid)); do_reipl_asm(*((__u32*)&schid));
...@@ -943,7 +942,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo) ...@@ -943,7 +942,7 @@ int __init cio_get_iplinfo(struct cio_iplinfo *iplinfo)
if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS)) if (__chsc_enable_facility(&sda_area, CHSC_SDA_OC_MSS))
return -ENODEV; return -ENODEV;
} }
if (stsch_err(schid, &schib)) if (stsch(schid, &schib))
return -ENODEV; return -ENODEV;
if (schib.pmcw.st != SUBCHANNEL_TYPE_IO) if (schib.pmcw.st != SUBCHANNEL_TYPE_IO)
return -ENODEV; return -ENODEV;
......
...@@ -45,6 +45,18 @@ struct pmcw { ...@@ -45,6 +45,18 @@ struct pmcw {
/* ... in an operand exception. */ /* ... in an operand exception. */
} __attribute__ ((packed)); } __attribute__ ((packed));
/* I/O-Interruption Code as stored by TEST PENDING INTERRUPTION (TPI). */
struct tpi_info {
struct subchannel_id schid;
u32 intparm;
u32 adapter_IO:1;
u32 :1;
u32 isc:3;
u32 :27;
u32 type:3;
u32 :12;
} __packed __aligned(4);
/* Target SCHIB configuration. */ /* Target SCHIB configuration. */
struct schib_config { struct schib_config {
u64 mba; u64 mba;
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/wait.h> #include <linux/wait.h>
#include <asm/crw.h> #include <asm/crw.h>
#include <asm/ctl_reg.h> #include <asm/ctl_reg.h>
#include "ioasm.h"
static DEFINE_MUTEX(crw_handler_mutex); static DEFINE_MUTEX(crw_handler_mutex);
static crw_handler_t crw_handlers[NR_RSCS]; static crw_handler_t crw_handlers[NR_RSCS];
......
...@@ -390,7 +390,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow) ...@@ -390,7 +390,7 @@ static int css_evaluate_new_subchannel(struct subchannel_id schid, int slow)
/* Will be done on the slow path. */ /* Will be done on the slow path. */
return -EAGAIN; return -EAGAIN;
} }
if (stsch_err(schid, &schib)) { if (stsch(schid, &schib)) {
/* Subchannel is not provided. */ /* Subchannel is not provided. */
return -ENXIO; return -ENXIO;
} }
......
...@@ -44,7 +44,7 @@ static void ccw_timeout_log(struct ccw_device *cdev) ...@@ -44,7 +44,7 @@ static void ccw_timeout_log(struct ccw_device *cdev)
sch = to_subchannel(cdev->dev.parent); sch = to_subchannel(cdev->dev.parent);
private = to_io_private(sch); private = to_io_private(sch);
orb = &private->orb; orb = &private->orb;
cc = stsch_err(sch->schid, &schib); cc = stsch(sch->schid, &schib);
printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, " printk(KERN_WARNING "cio: ccw device timeout occurred at %llx, "
"device information:\n", get_tod_clock()); "device information:\n", get_tod_clock());
......
...@@ -169,49 +169,4 @@ struct ccw_device_private { ...@@ -169,49 +169,4 @@ struct ccw_device_private {
enum interruption_class int_class; enum interruption_class int_class;
}; };
static inline int rsch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" rsch\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc", "memory");
return ccode;
}
static inline int hsch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" hsch\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc");
return ccode;
}
static inline int xsch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" .insn rre,0xb2760000,%1,0\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc");
return ccode;
}
#endif #endif
/*
* Channel subsystem I/O instructions.
*/
#include <linux/export.h>
#include <asm/chpid.h>
#include <asm/schid.h>
#include <asm/crw.h>
#include "ioasm.h"
#include "orb.h"
#include "cio.h"
int stsch(struct subchannel_id schid, struct schib *addr)
{
register struct subchannel_id reg1 asm ("1") = schid;
int ccode = -EIO;
asm volatile(
" stsch 0(%3)\n"
"0: ipm %0\n"
" srl %0,28\n"
"1:\n"
EX_TABLE(0b, 1b)
: "+d" (ccode), "=m" (*addr)
: "d" (reg1), "a" (addr)
: "cc");
trace_s390_cio_stsch(schid, addr, ccode);
return ccode;
}
EXPORT_SYMBOL(stsch);
int msch(struct subchannel_id schid, struct schib *addr)
{
register struct subchannel_id reg1 asm ("1") = schid;
int ccode = -EIO;
asm volatile(
" msch 0(%2)\n"
"0: ipm %0\n"
" srl %0,28\n"
"1:\n"
EX_TABLE(0b, 1b)
: "+d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc");
trace_s390_cio_msch(schid, addr, ccode);
return ccode;
}
int tsch(struct subchannel_id schid, struct irb *addr)
{
register struct subchannel_id reg1 asm ("1") = schid;
int ccode;
asm volatile(
" tsch 0(%3)\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode), "=m" (*addr)
: "d" (reg1), "a" (addr)
: "cc");
trace_s390_cio_tsch(schid, addr, ccode);
return ccode;
}
int ssch(struct subchannel_id schid, union orb *addr)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode = -EIO;
asm volatile(
" ssch 0(%2)\n"
"0: ipm %0\n"
" srl %0,28\n"
"1:\n"
EX_TABLE(0b, 1b)
: "+d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc", "memory");
trace_s390_cio_ssch(schid, addr, ccode);
return ccode;
}
EXPORT_SYMBOL(ssch);
int csch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" csch\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc");
trace_s390_cio_csch(schid, ccode);
return ccode;
}
EXPORT_SYMBOL(csch);
int tpi(struct tpi_info *addr)
{
int ccode;
asm volatile(
" tpi 0(%2)\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode), "=m" (*addr)
: "a" (addr)
: "cc");
trace_s390_cio_tpi(addr, ccode);
return ccode;
}
int chsc(void *chsc_area)
{
typedef struct { char _[4096]; } addr_type;
int cc;
asm volatile(
" .insn rre,0xb25f0000,%2,0\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (cc), "=m" (*(addr_type *) chsc_area)
: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
: "cc");
trace_s390_cio_chsc(chsc_area, cc);
return cc;
}
EXPORT_SYMBOL(chsc);
int rchp(struct chp_id chpid)
{
register struct chp_id reg1 asm ("1") = chpid;
int ccode;
asm volatile(
" lr 1,%1\n"
" rchp\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode) : "d" (reg1) : "cc");
trace_s390_cio_rchp(chpid, ccode);
return ccode;
}
int rsch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" rsch\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc", "memory");
trace_s390_cio_rsch(schid, ccode);
return ccode;
}
int hsch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" hsch\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc");
trace_s390_cio_hsch(schid, ccode);
return ccode;
}
int xsch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" xsch\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc");
trace_s390_cio_xsch(schid, ccode);
return ccode;
}
int stcrw(struct crw *crw)
{
int ccode;
asm volatile(
" stcrw 0(%2)\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (ccode), "=m" (*crw)
: "a" (crw)
: "cc");
trace_s390_cio_stcrw(crw, ccode);
return ccode;
}
...@@ -3,165 +3,26 @@ ...@@ -3,165 +3,26 @@
#include <asm/chpid.h> #include <asm/chpid.h>
#include <asm/schid.h> #include <asm/schid.h>
#include <asm/crw.h>
#include "orb.h" #include "orb.h"
#include "cio.h" #include "cio.h"
#include "trace.h"
/* /*
* TPI info structure * Some S390 specific IO instructions
*/ */
struct tpi_info {
struct subchannel_id schid;
__u32 intparm; /* interruption parameter */
__u32 adapter_IO : 1;
__u32 reserved2 : 1;
__u32 isc : 3;
__u32 reserved3 : 12;
__u32 int_type : 3;
__u32 reserved4 : 12;
} __attribute__ ((packed));
int stsch(struct subchannel_id schid, struct schib *addr);
/* int msch(struct subchannel_id schid, struct schib *addr);
* Some S390 specific IO instructions as inline int tsch(struct subchannel_id schid, struct irb *addr);
*/ int ssch(struct subchannel_id schid, union orb *addr);
int csch(struct subchannel_id schid);
static inline int stsch_err(struct subchannel_id schid, struct schib *addr) int tpi(struct tpi_info *addr);
{ int chsc(void *chsc_area);
register struct subchannel_id reg1 asm ("1") = schid; int rchp(struct chp_id chpid);
int ccode = -EIO; int rsch(struct subchannel_id schid);
int hsch(struct subchannel_id schid);
asm volatile( int xsch(struct subchannel_id schid);
" stsch 0(%3)\n" int stcrw(struct crw *crw);
"0: ipm %0\n"
" srl %0,28\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (ccode), "=m" (*addr)
: "d" (reg1), "a" (addr)
: "cc");
return ccode;
}
static inline int msch(struct subchannel_id schid, struct schib *addr)
{
register struct subchannel_id reg1 asm ("1") = schid;
int ccode;
asm volatile(
" msch 0(%2)\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc");
return ccode;
}
static inline int msch_err(struct subchannel_id schid, struct schib *addr)
{
register struct subchannel_id reg1 asm ("1") = schid;
int ccode = -EIO;
asm volatile(
" msch 0(%2)\n"
"0: ipm %0\n"
" srl %0,28\n"
"1:\n"
EX_TABLE(0b,1b)
: "+d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc");
return ccode;
}
static inline int tsch(struct subchannel_id schid, struct irb *addr)
{
register struct subchannel_id reg1 asm ("1") = schid;
int ccode;
asm volatile(
" tsch 0(%3)\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode), "=m" (*addr)
: "d" (reg1), "a" (addr)
: "cc");
return ccode;
}
static inline int ssch(struct subchannel_id schid, union orb *addr)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode = -EIO;
asm volatile(
" ssch 0(%2)\n"
"0: ipm %0\n"
" srl %0,28\n"
"1:\n"
EX_TABLE(0b, 1b)
: "+d" (ccode)
: "d" (reg1), "a" (addr), "m" (*addr)
: "cc", "memory");
return ccode;
}
static inline int csch(struct subchannel_id schid)
{
register struct subchannel_id reg1 asm("1") = schid;
int ccode;
asm volatile(
" csch\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode)
: "d" (reg1)
: "cc");
return ccode;
}
static inline int tpi(struct tpi_info *addr)
{
int ccode;
asm volatile(
" tpi 0(%2)\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode), "=m" (*addr)
: "a" (addr)
: "cc");
return ccode;
}
static inline int chsc(void *chsc_area)
{
typedef struct { char _[4096]; } addr_type;
int cc;
asm volatile(
" .insn rre,0xb25f0000,%2,0\n"
" ipm %0\n"
" srl %0,28\n"
: "=d" (cc), "=m" (*(addr_type *) chsc_area)
: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
: "cc");
return cc;
}
static inline int rchp(struct chp_id chpid)
{
register struct chp_id reg1 asm ("1") = chpid;
int ccode;
asm volatile(
" lr 1,%1\n"
" rchp\n"
" ipm %0\n"
" srl %0,28"
: "=d" (ccode) : "d" (reg1) : "cc");
return ccode;
}
#endif #endif
...@@ -366,8 +366,6 @@ void qdio_debug_exit(void) ...@@ -366,8 +366,6 @@ void qdio_debug_exit(void)
{ {
qdio_clear_dbf_list(); qdio_clear_dbf_list();
debugfs_remove(debugfs_root); debugfs_remove(debugfs_root);
if (qdio_dbf_setup) debug_unregister(qdio_dbf_setup);
debug_unregister(qdio_dbf_setup); debug_unregister(qdio_dbf_error);
if (qdio_dbf_error)
debug_unregister(qdio_dbf_error);
} }
/*
* Tracepoint definitions for s390_cio
*
* Copyright IBM Corp. 2015
* Author(s): Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
*/
#include <asm/crw.h>
#include "cio.h"
#define CREATE_TRACE_POINTS
#include "trace.h"
EXPORT_TRACEPOINT_SYMBOL(s390_cio_stsch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_msch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_tsch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_tpi);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_ssch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_csch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_hsch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_xsch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_rsch);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_rchp);
EXPORT_TRACEPOINT_SYMBOL(s390_cio_chsc);
This diff is collapsed.
...@@ -1428,10 +1428,8 @@ int __init zcrypt_debug_init(void) ...@@ -1428,10 +1428,8 @@ int __init zcrypt_debug_init(void)
void zcrypt_debug_exit(void) void zcrypt_debug_exit(void)
{ {
debugfs_remove(debugfs_root); debugfs_remove(debugfs_root);
if (zcrypt_dbf_common) debug_unregister(zcrypt_dbf_common);
debug_unregister(zcrypt_dbf_common); debug_unregister(zcrypt_dbf_devices);
if (zcrypt_dbf_devices)
debug_unregister(zcrypt_dbf_devices);
} }
/** /**
......
...@@ -104,8 +104,9 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\ ...@@ -104,8 +104,9 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\
orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
$(ccflags-y) $(CFLAGS_$(basetarget).o) $(ccflags-y) $(CFLAGS_$(basetarget).o)
_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \ orig_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \
$(asflags-y) $(AFLAGS_$(basetarget).o) $(asflags-y) $(AFLAGS_$(basetarget).o)
_a_flags = $(filter-out $(AFLAGS_REMOVE_$(basetarget).o), $(orig_a_flags))
_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F)) _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
# #
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment