aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/defconfig37
-rw-r--r--arch/s390/include/asm/lowcore.h9
-rw-r--r--arch/s390/include/asm/processor.h2
-rw-r--r--arch/s390/kernel/asm-offsets.c7
-rw-r--r--arch/s390/kernel/compat_linux.c83
-rw-r--r--arch/s390/kernel/compat_linux.h4
-rw-r--r--arch/s390/kernel/compat_wrapper.S27
-rw-r--r--arch/s390/kernel/entry.h6
-rw-r--r--arch/s390/kernel/process.c40
-rw-r--r--arch/s390/kernel/ptrace.c19
-rw-r--r--arch/s390/kernel/sclp.S5
-rw-r--r--arch/s390/kernel/smp.c50
-rw-r--r--arch/s390/kernel/suspend.c24
-rw-r--r--arch/s390/kernel/swsusp_asm64.S102
-rw-r--r--arch/s390/kernel/syscalls.S8
-rw-r--r--arch/s390/mm/page-states.c52
-rw-r--r--arch/s390/mm/pgtable.c17
-rw-r--r--drivers/s390/block/dasd_eckd.c13
-rw-r--r--drivers/s390/cio/css.c252
-rw-r--r--drivers/s390/cio/css.h3
-rw-r--r--drivers/s390/cio/device.c38
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/cio/idset.c22
-rw-r--r--drivers/s390/cio/idset.h2
-rw-r--r--drivers/s390/cio/qdio_main.c32
-rw-r--r--drivers/s390/crypto/ap_bus.c40
26 files changed, 478 insertions, 417 deletions
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 4e91a2573cc4..ab4464486b7a 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.30 3# Linux kernel version: 2.6.31
4# Mon Jun 22 11:08:16 2009 4# Tue Sep 22 17:43:13 2009
5# 5#
6CONFIG_SCHED_MC=y 6CONFIG_SCHED_MC=y
7CONFIG_MMU=y 7CONFIG_MMU=y
@@ -24,6 +24,7 @@ CONFIG_PGSTE=y
24CONFIG_VIRT_CPU_ACCOUNTING=y 24CONFIG_VIRT_CPU_ACCOUNTING=y
25CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y 25CONFIG_ARCH_SUPPORTS_DEBUG_PAGEALLOC=y
26CONFIG_S390=y 26CONFIG_S390=y
27CONFIG_SCHED_OMIT_FRAME_POINTER=y
27CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" 28CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
28CONFIG_CONSTRUCTORS=y 29CONFIG_CONSTRUCTORS=y
29 30
@@ -48,11 +49,12 @@ CONFIG_AUDIT=y
48# 49#
49# RCU Subsystem 50# RCU Subsystem
50# 51#
51CONFIG_CLASSIC_RCU=y 52CONFIG_TREE_RCU=y
52# CONFIG_TREE_RCU is not set 53# CONFIG_TREE_PREEMPT_RCU is not set
53# CONFIG_PREEMPT_RCU is not set 54# CONFIG_RCU_TRACE is not set
55CONFIG_RCU_FANOUT=64
56# CONFIG_RCU_FANOUT_EXACT is not set
54# CONFIG_TREE_RCU_TRACE is not set 57# CONFIG_TREE_RCU_TRACE is not set
55# CONFIG_PREEMPT_RCU_TRACE is not set
56CONFIG_IKCONFIG=y 58CONFIG_IKCONFIG=y
57CONFIG_IKCONFIG_PROC=y 59CONFIG_IKCONFIG_PROC=y
58CONFIG_LOG_BUF_SHIFT=17 60CONFIG_LOG_BUF_SHIFT=17
@@ -103,11 +105,12 @@ CONFIG_TIMERFD=y
103CONFIG_EVENTFD=y 105CONFIG_EVENTFD=y
104CONFIG_SHMEM=y 106CONFIG_SHMEM=y
105CONFIG_AIO=y 107CONFIG_AIO=y
106CONFIG_HAVE_PERF_COUNTERS=y 108CONFIG_HAVE_PERF_EVENTS=y
107 109
108# 110#
109# Performance Counters 111# Kernel Performance Events And Counters
110# 112#
113# CONFIG_PERF_EVENTS is not set
111# CONFIG_PERF_COUNTERS is not set 114# CONFIG_PERF_COUNTERS is not set
112CONFIG_VM_EVENT_COUNTERS=y 115CONFIG_VM_EVENT_COUNTERS=y
113# CONFIG_STRIP_ASM_SYMS is not set 116# CONFIG_STRIP_ASM_SYMS is not set
@@ -116,7 +119,6 @@ CONFIG_SLAB=y
116# CONFIG_SLUB is not set 119# CONFIG_SLUB is not set
117# CONFIG_SLOB is not set 120# CONFIG_SLOB is not set
118# CONFIG_PROFILING is not set 121# CONFIG_PROFILING is not set
119# CONFIG_MARKERS is not set
120CONFIG_HAVE_OPROFILE=y 122CONFIG_HAVE_OPROFILE=y
121CONFIG_KPROBES=y 123CONFIG_KPROBES=y
122CONFIG_HAVE_SYSCALL_WRAPPERS=y 124CONFIG_HAVE_SYSCALL_WRAPPERS=y
@@ -176,6 +178,7 @@ CONFIG_NO_HZ=y
176CONFIG_HIGH_RES_TIMERS=y 178CONFIG_HIGH_RES_TIMERS=y
177CONFIG_GENERIC_CLOCKEVENTS_BUILD=y 179CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
178CONFIG_64BIT=y 180CONFIG_64BIT=y
181# CONFIG_KTIME_SCALAR is not set
179CONFIG_SMP=y 182CONFIG_SMP=y
180CONFIG_NR_CPUS=32 183CONFIG_NR_CPUS=32
181CONFIG_HOTPLUG_CPU=y 184CONFIG_HOTPLUG_CPU=y
@@ -257,7 +260,6 @@ CONFIG_FORCE_MAX_ZONEORDER=9
257CONFIG_PFAULT=y 260CONFIG_PFAULT=y
258# CONFIG_SHARED_KERNEL is not set 261# CONFIG_SHARED_KERNEL is not set
259# CONFIG_CMM is not set 262# CONFIG_CMM is not set
260# CONFIG_PAGE_STATES is not set
261# CONFIG_APPLDATA_BASE is not set 263# CONFIG_APPLDATA_BASE is not set
262CONFIG_HZ_100=y 264CONFIG_HZ_100=y
263# CONFIG_HZ_250 is not set 265# CONFIG_HZ_250 is not set
@@ -280,6 +282,7 @@ CONFIG_PM_SLEEP_SMP=y
280CONFIG_PM_SLEEP=y 282CONFIG_PM_SLEEP=y
281CONFIG_HIBERNATION=y 283CONFIG_HIBERNATION=y
282CONFIG_PM_STD_PARTITION="" 284CONFIG_PM_STD_PARTITION=""
285# CONFIG_PM_RUNTIME is not set
283CONFIG_NET=y 286CONFIG_NET=y
284 287
285# 288#
@@ -394,6 +397,7 @@ CONFIG_IP_SCTP=m
394# CONFIG_SCTP_HMAC_NONE is not set 397# CONFIG_SCTP_HMAC_NONE is not set
395# CONFIG_SCTP_HMAC_SHA1 is not set 398# CONFIG_SCTP_HMAC_SHA1 is not set
396CONFIG_SCTP_HMAC_MD5=y 399CONFIG_SCTP_HMAC_MD5=y
400# CONFIG_RDS is not set
397# CONFIG_TIPC is not set 401# CONFIG_TIPC is not set
398# CONFIG_ATM is not set 402# CONFIG_ATM is not set
399# CONFIG_BRIDGE is not set 403# CONFIG_BRIDGE is not set
@@ -487,6 +491,7 @@ CONFIG_CCW=y
487# Generic Driver Options 491# Generic Driver Options
488# 492#
489CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" 493CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
494# CONFIG_DEVTMPFS is not set
490CONFIG_STANDALONE=y 495CONFIG_STANDALONE=y
491CONFIG_PREVENT_FIRMWARE_BUILD=y 496CONFIG_PREVENT_FIRMWARE_BUILD=y
492CONFIG_FW_LOADER=y 497CONFIG_FW_LOADER=y
@@ -501,6 +506,7 @@ CONFIG_BLK_DEV=y
501CONFIG_BLK_DEV_LOOP=m 506CONFIG_BLK_DEV_LOOP=m
502# CONFIG_BLK_DEV_CRYPTOLOOP is not set 507# CONFIG_BLK_DEV_CRYPTOLOOP is not set
503CONFIG_BLK_DEV_NBD=m 508CONFIG_BLK_DEV_NBD=m
509# CONFIG_BLK_DEV_OSD is not set
504CONFIG_BLK_DEV_RAM=y 510CONFIG_BLK_DEV_RAM=y
505CONFIG_BLK_DEV_RAM_COUNT=16 511CONFIG_BLK_DEV_RAM_COUNT=16
506CONFIG_BLK_DEV_RAM_SIZE=4096 512CONFIG_BLK_DEV_RAM_SIZE=4096
@@ -594,8 +600,11 @@ CONFIG_BLK_DEV_DM=y
594CONFIG_DM_CRYPT=y 600CONFIG_DM_CRYPT=y
595CONFIG_DM_SNAPSHOT=y 601CONFIG_DM_SNAPSHOT=y
596CONFIG_DM_MIRROR=y 602CONFIG_DM_MIRROR=y
603# CONFIG_DM_LOG_USERSPACE is not set
597CONFIG_DM_ZERO=y 604CONFIG_DM_ZERO=y
598CONFIG_DM_MULTIPATH=m 605CONFIG_DM_MULTIPATH=m
606# CONFIG_DM_MULTIPATH_QL is not set
607# CONFIG_DM_MULTIPATH_ST is not set
599# CONFIG_DM_DELAY is not set 608# CONFIG_DM_DELAY is not set
600# CONFIG_DM_UEVENT is not set 609# CONFIG_DM_UEVENT is not set
601CONFIG_NETDEVICES=y 610CONFIG_NETDEVICES=y
@@ -615,7 +624,6 @@ CONFIG_NET_ETHERNET=y
615# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set 624# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
616# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set 625# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
617# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set 626# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
618# CONFIG_KS8842 is not set
619CONFIG_NETDEV_1000=y 627CONFIG_NETDEV_1000=y
620CONFIG_NETDEV_10000=y 628CONFIG_NETDEV_10000=y
621# CONFIG_TR is not set 629# CONFIG_TR is not set
@@ -678,6 +686,7 @@ CONFIG_SCLP_CONSOLE=y
678CONFIG_SCLP_VT220_TTY=y 686CONFIG_SCLP_VT220_TTY=y
679CONFIG_SCLP_VT220_CONSOLE=y 687CONFIG_SCLP_VT220_CONSOLE=y
680CONFIG_SCLP_CPI=m 688CONFIG_SCLP_CPI=m
689CONFIG_SCLP_ASYNC=m
681CONFIG_S390_TAPE=m 690CONFIG_S390_TAPE=m
682 691
683# 692#
@@ -737,6 +746,7 @@ CONFIG_FS_POSIX_ACL=y
737# CONFIG_GFS2_FS is not set 746# CONFIG_GFS2_FS is not set
738# CONFIG_OCFS2_FS is not set 747# CONFIG_OCFS2_FS is not set
739# CONFIG_BTRFS_FS is not set 748# CONFIG_BTRFS_FS is not set
749# CONFIG_NILFS2_FS is not set
740CONFIG_FILE_LOCKING=y 750CONFIG_FILE_LOCKING=y
741CONFIG_FSNOTIFY=y 751CONFIG_FSNOTIFY=y
742CONFIG_DNOTIFY=y 752CONFIG_DNOTIFY=y
@@ -798,7 +808,6 @@ CONFIG_MISC_FILESYSTEMS=y
798# CONFIG_SYSV_FS is not set 808# CONFIG_SYSV_FS is not set
799# CONFIG_UFS_FS is not set 809# CONFIG_UFS_FS is not set
800# CONFIG_EXOFS_FS is not set 810# CONFIG_EXOFS_FS is not set
801# CONFIG_NILFS2_FS is not set
802CONFIG_NETWORK_FILESYSTEMS=y 811CONFIG_NETWORK_FILESYSTEMS=y
803CONFIG_NFS_FS=y 812CONFIG_NFS_FS=y
804CONFIG_NFS_V3=y 813CONFIG_NFS_V3=y
@@ -885,11 +894,13 @@ CONFIG_DEBUG_MEMORY_INIT=y
885# CONFIG_DEBUG_LIST is not set 894# CONFIG_DEBUG_LIST is not set
886# CONFIG_DEBUG_SG is not set 895# CONFIG_DEBUG_SG is not set
887# CONFIG_DEBUG_NOTIFIERS is not set 896# CONFIG_DEBUG_NOTIFIERS is not set
897# CONFIG_DEBUG_CREDENTIALS is not set
888# CONFIG_RCU_TORTURE_TEST is not set 898# CONFIG_RCU_TORTURE_TEST is not set
889# CONFIG_RCU_CPU_STALL_DETECTOR is not set 899# CONFIG_RCU_CPU_STALL_DETECTOR is not set
890# CONFIG_KPROBES_SANITY_TEST is not set 900# CONFIG_KPROBES_SANITY_TEST is not set
891# CONFIG_BACKTRACE_SELF_TEST is not set 901# CONFIG_BACKTRACE_SELF_TEST is not set
892# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set 902# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
903CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
893# CONFIG_LKDTM is not set 904# CONFIG_LKDTM is not set
894# CONFIG_FAULT_INJECTION is not set 905# CONFIG_FAULT_INJECTION is not set
895# CONFIG_LATENCYTOP is not set 906# CONFIG_LATENCYTOP is not set
@@ -979,11 +990,13 @@ CONFIG_CRYPTO_PCBC=m
979# 990#
980CONFIG_CRYPTO_HMAC=m 991CONFIG_CRYPTO_HMAC=m
981# CONFIG_CRYPTO_XCBC is not set 992# CONFIG_CRYPTO_XCBC is not set
993CONFIG_CRYPTO_VMAC=m
982 994
983# 995#
984# Digest 996# Digest
985# 997#
986CONFIG_CRYPTO_CRC32C=m 998CONFIG_CRYPTO_CRC32C=m
999CONFIG_CRYPTO_GHASH=m
987# CONFIG_CRYPTO_MD4 is not set 1000# CONFIG_CRYPTO_MD4 is not set
988CONFIG_CRYPTO_MD5=m 1001CONFIG_CRYPTO_MD5=m
989# CONFIG_CRYPTO_MICHAEL_MIC is not set 1002# CONFIG_CRYPTO_MICHAEL_MIC is not set
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h
index 6bc9426a6fbf..f2ef4b619ce1 100644
--- a/arch/s390/include/asm/lowcore.h
+++ b/arch/s390/include/asm/lowcore.h
@@ -86,6 +86,7 @@
86#define __LC_PGM_OLD_PSW 0x0150 86#define __LC_PGM_OLD_PSW 0x0150
87#define __LC_MCK_OLD_PSW 0x0160 87#define __LC_MCK_OLD_PSW 0x0160
88#define __LC_IO_OLD_PSW 0x0170 88#define __LC_IO_OLD_PSW 0x0170
89#define __LC_RESTART_PSW 0x01a0
89#define __LC_EXT_NEW_PSW 0x01b0 90#define __LC_EXT_NEW_PSW 0x01b0
90#define __LC_SVC_NEW_PSW 0x01c0 91#define __LC_SVC_NEW_PSW 0x01c0
91#define __LC_PGM_NEW_PSW 0x01d0 92#define __LC_PGM_NEW_PSW 0x01d0
@@ -189,6 +190,14 @@ union save_area {
189#define SAVE_AREA_BASE SAVE_AREA_BASE_S390X 190#define SAVE_AREA_BASE SAVE_AREA_BASE_S390X
190#endif 191#endif
191 192
193#ifndef __s390x__
194#define LC_ORDER 0
195#else
196#define LC_ORDER 1
197#endif
198
199#define LC_PAGES (1UL << LC_ORDER)
200
192struct _lowcore 201struct _lowcore
193{ 202{
194#ifndef __s390x__ 203#ifndef __s390x__
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index cf8eed3fa779..b42715458312 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -295,7 +295,7 @@ static inline void ATTRIB_NORET disabled_wait(unsigned long code)
295 " oi 0x384(1),0x10\n"/* fake protection bit */ 295 " oi 0x384(1),0x10\n"/* fake protection bit */
296 " lpswe 0(%1)" 296 " lpswe 0(%1)"
297 : "=m" (ctl_buf) 297 : "=m" (ctl_buf)
298 : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0"); 298 : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0", "1");
299#endif /* __s390x__ */ 299#endif /* __s390x__ */
300 while (1); 300 while (1);
301} 301}
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index fa9905ce7d0b..63e46433e81d 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -7,6 +7,7 @@
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/kbuild.h> 8#include <linux/kbuild.h>
9#include <asm/vdso.h> 9#include <asm/vdso.h>
10#include <asm/sigp.h>
10 11
11int main(void) 12int main(void)
12{ 13{
@@ -59,6 +60,10 @@ int main(void)
59 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME); 60 DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
60 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC); 61 DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
61 DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC); 62 DEFINE(CLOCK_REALTIME_RES, MONOTONIC_RES_NSEC);
62 63 /* constants for SIGP */
64 DEFINE(__SIGP_STOP, sigp_stop);
65 DEFINE(__SIGP_RESTART, sigp_restart);
66 DEFINE(__SIGP_SENSE, sigp_sense);
67 DEFINE(__SIGP_INITIAL_CPU_RESET, sigp_initial_cpu_reset);
63 return 0; 68 return 0;
64} 69}
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 9ab188d67a3d..5519cb745106 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -443,66 +443,28 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
443 * sys32_execve() executes a new program after the asm stub has set 443 * sys32_execve() executes a new program after the asm stub has set
444 * things up for us. This should basically do what I want it to. 444 * things up for us. This should basically do what I want it to.
445 */ 445 */
446asmlinkage long sys32_execve(void) 446asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
447 compat_uptr_t __user *envp)
447{ 448{
448 struct pt_regs *regs = task_pt_regs(current); 449 struct pt_regs *regs = task_pt_regs(current);
449 char *filename; 450 char *filename;
450 unsigned long result; 451 long rc;
451 int rc; 452
452 453 filename = getname(name);
453 filename = getname(compat_ptr(regs->orig_gpr2)); 454 rc = PTR_ERR(filename);
454 if (IS_ERR(filename)) { 455 if (IS_ERR(filename))
455 result = PTR_ERR(filename); 456 return rc;
456 goto out; 457 rc = compat_do_execve(filename, argv, envp, regs);
457 } 458 if (rc)
458 rc = compat_do_execve(filename, compat_ptr(regs->gprs[3]), 459 goto out;
459 compat_ptr(regs->gprs[4]), regs);
460 if (rc) {
461 result = rc;
462 goto out_putname;
463 }
464 current->thread.fp_regs.fpc=0; 460 current->thread.fp_regs.fpc=0;
465 asm volatile("sfpc %0,0" : : "d" (0)); 461 asm volatile("sfpc %0,0" : : "d" (0));
466 result = regs->gprs[2]; 462 rc = regs->gprs[2];
467out_putname:
468 putname(filename);
469out: 463out:
470 return result; 464 putname(filename);
471} 465 return rc;
472
473
474#ifdef CONFIG_MODULES
475
476asmlinkage long
477sys32_init_module(void __user *umod, unsigned long len,
478 const char __user *uargs)
479{
480 return sys_init_module(umod, len, uargs);
481}
482
483asmlinkage long
484sys32_delete_module(const char __user *name_user, unsigned int flags)
485{
486 return sys_delete_module(name_user, flags);
487}
488
489#else /* CONFIG_MODULES */
490
491asmlinkage long
492sys32_init_module(void __user *umod, unsigned long len,
493 const char __user *uargs)
494{
495 return -ENOSYS;
496} 466}
497 467
498asmlinkage long
499sys32_delete_module(const char __user *name_user, unsigned int flags)
500{
501 return -ENOSYS;
502}
503
504#endif /* CONFIG_MODULES */
505
506asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf, 468asmlinkage long sys32_pread64(unsigned int fd, char __user *ubuf,
507 size_t count, u32 poshi, u32 poslo) 469 size_t count, u32 poshi, u32 poslo)
508{ 470{
@@ -801,23 +763,6 @@ asmlinkage long sys32_write(unsigned int fd, char __user * buf, size_t count)
801 return sys_write(fd, buf, count); 763 return sys_write(fd, buf, count);
802} 764}
803 765
804asmlinkage long sys32_clone(void)
805{
806 struct pt_regs *regs = task_pt_regs(current);
807 unsigned long clone_flags;
808 unsigned long newsp;
809 int __user *parent_tidptr, *child_tidptr;
810
811 clone_flags = regs->gprs[3] & 0xffffffffUL;
812 newsp = regs->orig_gpr2 & 0x7fffffffUL;
813 parent_tidptr = compat_ptr(regs->gprs[4]);
814 child_tidptr = compat_ptr(regs->gprs[5]);
815 if (!newsp)
816 newsp = regs->gprs[15];
817 return do_fork(clone_flags, newsp, regs, 0,
818 parent_tidptr, child_tidptr);
819}
820
821/* 766/*
822 * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64. 767 * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.
823 * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE} 768 * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 836a28842900..c07f9ca05ade 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -198,7 +198,8 @@ long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
198 compat_sigset_t __user *oset, size_t sigsetsize); 198 compat_sigset_t __user *oset, size_t sigsetsize);
199long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize); 199long sys32_rt_sigpending(compat_sigset_t __user *set, size_t sigsetsize);
200long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo); 200long sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo);
201long sys32_execve(void); 201long sys32_execve(char __user *name, compat_uptr_t __user *argv,
202 compat_uptr_t __user *envp);
202long sys32_init_module(void __user *umod, unsigned long len, 203long sys32_init_module(void __user *umod, unsigned long len,
203 const char __user *uargs); 204 const char __user *uargs);
204long sys32_delete_module(const char __user *name_user, unsigned int flags); 205long sys32_delete_module(const char __user *name_user, unsigned int flags);
@@ -222,7 +223,6 @@ unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg);
222long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg); 223long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg);
223long sys32_read(unsigned int fd, char __user * buf, size_t count); 224long sys32_read(unsigned int fd, char __user * buf, size_t count);
224long sys32_write(unsigned int fd, char __user * buf, size_t count); 225long sys32_write(unsigned int fd, char __user * buf, size_t count);
225long sys32_clone(void);
226long sys32_fadvise64(int fd, loff_t offset, size_t len, int advise); 226long sys32_fadvise64(int fd, loff_t offset, size_t len, int advise);
227long sys32_fadvise64_64(struct fadvise64_64_args __user *args); 227long sys32_fadvise64_64(struct fadvise64_64_args __user *args);
228long sys32_sigaction(int sig, const struct old_sigaction32 __user *act, 228long sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 624790042d41..682fb69dba21 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -568,18 +568,18 @@ compat_sys_sigprocmask_wrapper:
568 llgtr %r4,%r4 # compat_old_sigset_t * 568 llgtr %r4,%r4 # compat_old_sigset_t *
569 jg compat_sys_sigprocmask # branch to system call 569 jg compat_sys_sigprocmask # branch to system call
570 570
571 .globl sys32_init_module_wrapper 571 .globl sys_init_module_wrapper
572sys32_init_module_wrapper: 572sys_init_module_wrapper:
573 llgtr %r2,%r2 # void * 573 llgtr %r2,%r2 # void *
574 llgfr %r3,%r3 # unsigned long 574 llgfr %r3,%r3 # unsigned long
575 llgtr %r4,%r4 # char * 575 llgtr %r4,%r4 # char *
576 jg sys32_init_module # branch to system call 576 jg sys_init_module # branch to system call
577 577
578 .globl sys32_delete_module_wrapper 578 .globl sys_delete_module_wrapper
579sys32_delete_module_wrapper: 579sys_delete_module_wrapper:
580 llgtr %r2,%r2 # const char * 580 llgtr %r2,%r2 # const char *
581 llgfr %r3,%r3 # unsigned int 581 llgfr %r3,%r3 # unsigned int
582 jg sys32_delete_module # branch to system call 582 jg sys_delete_module # branch to system call
583 583
584 .globl sys32_quotactl_wrapper 584 .globl sys32_quotactl_wrapper
585sys32_quotactl_wrapper: 585sys32_quotactl_wrapper:
@@ -1840,3 +1840,18 @@ sys_perf_event_open_wrapper:
1840 lgfr %r5,%r5 # int 1840 lgfr %r5,%r5 # int
1841 llgfr %r6,%r6 # unsigned long 1841 llgfr %r6,%r6 # unsigned long
1842 jg sys_perf_event_open # branch to system call 1842 jg sys_perf_event_open # branch to system call
1843
1844 .globl sys_clone_wrapper
1845sys_clone_wrapper:
1846 llgfr %r2,%r2 # unsigned long
1847 llgfr %r3,%r3 # unsigned long
1848 llgtr %r4,%r4 # int *
1849 llgtr %r5,%r5 # int *
1850 jg sys_clone # branch to system call
1851
1852 .globl sys32_execve_wrapper
1853sys32_execve_wrapper:
1854 llgtr %r2,%r2 # char *
1855 llgtr %r3,%r3 # compat_uptr_t *
1856 llgtr %r4,%r4 # compat_uptr_t *
1857 jg sys32_execve # branch to system call
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index 950c59c6688b..e1e5e767ab56 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -42,10 +42,12 @@ long sys_s390_fadvise64_64(struct fadvise64_64_args __user *args);
42long sys_s390_fallocate(int fd, int mode, loff_t offset, u32 len_high, 42long sys_s390_fallocate(int fd, int mode, loff_t offset, u32 len_high,
43 u32 len_low); 43 u32 len_low);
44long sys_fork(void); 44long sys_fork(void);
45long sys_clone(void); 45long sys_clone(unsigned long newsp, unsigned long clone_flags,
46 int __user *parent_tidptr, int __user *child_tidptr);
46long sys_vfork(void); 47long sys_vfork(void);
47void execve_tail(void); 48void execve_tail(void);
48long sys_execve(void); 49long sys_execve(char __user *name, char __user * __user *argv,
50 char __user * __user *envp);
49long sys_sigsuspend(int history0, int history1, old_sigset_t mask); 51long sys_sigsuspend(int history0, int history1, old_sigset_t mask);
50long sys_sigaction(int sig, const struct old_sigaction __user *act, 52long sys_sigaction(int sig, const struct old_sigaction __user *act,
51 struct old_sigaction __user *oact); 53 struct old_sigaction __user *oact);
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 5a43f27eec13..59fe6ecc6ed3 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -32,6 +32,7 @@
32#include <linux/elfcore.h> 32#include <linux/elfcore.h>
33#include <linux/kernel_stat.h> 33#include <linux/kernel_stat.h>
34#include <linux/syscalls.h> 34#include <linux/syscalls.h>
35#include <linux/compat.h>
35#include <asm/compat.h> 36#include <asm/compat.h>
36#include <asm/uaccess.h> 37#include <asm/uaccess.h>
37#include <asm/pgtable.h> 38#include <asm/pgtable.h>
@@ -230,17 +231,11 @@ SYSCALL_DEFINE0(fork)
230 return do_fork(SIGCHLD, regs->gprs[15], regs, 0, NULL, NULL); 231 return do_fork(SIGCHLD, regs->gprs[15], regs, 0, NULL, NULL);
231} 232}
232 233
233SYSCALL_DEFINE0(clone) 234SYSCALL_DEFINE4(clone, unsigned long, newsp, unsigned long, clone_flags,
235 int __user *, parent_tidptr, int __user *, child_tidptr)
234{ 236{
235 struct pt_regs *regs = task_pt_regs(current); 237 struct pt_regs *regs = task_pt_regs(current);
236 unsigned long clone_flags;
237 unsigned long newsp;
238 int __user *parent_tidptr, *child_tidptr;
239 238
240 clone_flags = regs->gprs[3];
241 newsp = regs->orig_gpr2;
242 parent_tidptr = (int __user *) regs->gprs[4];
243 child_tidptr = (int __user *) regs->gprs[5];
244 if (!newsp) 239 if (!newsp)
245 newsp = regs->gprs[15]; 240 newsp = regs->gprs[15];
246 return do_fork(clone_flags, newsp, regs, 0, 241 return do_fork(clone_flags, newsp, regs, 0,
@@ -274,30 +269,25 @@ asmlinkage void execve_tail(void)
274/* 269/*
275 * sys_execve() executes a new program. 270 * sys_execve() executes a new program.
276 */ 271 */
277SYSCALL_DEFINE0(execve) 272SYSCALL_DEFINE3(execve, char __user *, name, char __user * __user *, argv,
273 char __user * __user *, envp)
278{ 274{
279 struct pt_regs *regs = task_pt_regs(current); 275 struct pt_regs *regs = task_pt_regs(current);
280 char *filename; 276 char *filename;
281 unsigned long result; 277 long rc;
282 int rc;
283 278
284 filename = getname((char __user *) regs->orig_gpr2); 279 filename = getname(name);
285 if (IS_ERR(filename)) { 280 rc = PTR_ERR(filename);
286 result = PTR_ERR(filename); 281 if (IS_ERR(filename))
282 return rc;
283 rc = do_execve(filename, argv, envp, regs);
284 if (rc)
287 goto out; 285 goto out;
288 }
289 rc = do_execve(filename, (char __user * __user *) regs->gprs[3],
290 (char __user * __user *) regs->gprs[4], regs);
291 if (rc) {
292 result = rc;
293 goto out_putname;
294 }
295 execve_tail(); 286 execve_tail();
296 result = regs->gprs[2]; 287 rc = regs->gprs[2];
297out_putname:
298 putname(filename);
299out: 288out:
300 return result; 289 putname(filename);
290 return rc;
301} 291}
302 292
303/* 293/*
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index f3ddd7ac06c5..a8738676b26c 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -339,24 +339,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
339 int copied, ret; 339 int copied, ret;
340 340
341 switch (request) { 341 switch (request) {
342 case PTRACE_PEEKTEXT:
343 case PTRACE_PEEKDATA:
344 /* Remove high order bit from address (only for 31 bit). */
345 addr &= PSW_ADDR_INSN;
346 /* read word at location addr. */
347 return generic_ptrace_peekdata(child, addr, data);
348
349 case PTRACE_PEEKUSR: 342 case PTRACE_PEEKUSR:
350 /* read the word at location addr in the USER area. */ 343 /* read the word at location addr in the USER area. */
351 return peek_user(child, addr, data); 344 return peek_user(child, addr, data);
352 345
353 case PTRACE_POKETEXT:
354 case PTRACE_POKEDATA:
355 /* Remove high order bit from address (only for 31 bit). */
356 addr &= PSW_ADDR_INSN;
357 /* write the word at location addr. */
358 return generic_ptrace_pokedata(child, addr, data);
359
360 case PTRACE_POKEUSR: 346 case PTRACE_POKEUSR:
361 /* write the word at location addr in the USER area */ 347 /* write the word at location addr in the USER area */
362 return poke_user(child, addr, data); 348 return poke_user(child, addr, data);
@@ -386,8 +372,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
386 copied += sizeof(unsigned long); 372 copied += sizeof(unsigned long);
387 } 373 }
388 return 0; 374 return 0;
375 default:
376 /* Removing high order bit from addr (only for 31 bit). */
377 addr &= PSW_ADDR_INSN;
378 return ptrace_request(child, request, addr, data);
389 } 379 }
390 return ptrace_request(child, request, addr, data);
391} 380}
392 381
393#ifdef CONFIG_COMPAT 382#ifdef CONFIG_COMPAT
diff --git a/arch/s390/kernel/sclp.S b/arch/s390/kernel/sclp.S
index 20639dfe0c42..e27ca63076d1 100644
--- a/arch/s390/kernel/sclp.S
+++ b/arch/s390/kernel/sclp.S
@@ -24,8 +24,6 @@ LC_EXT_INT_CODE = 0x86 # addr of ext int code
24# R3 = external interruption parameter if R2=0 24# R3 = external interruption parameter if R2=0
25# 25#
26 26
27.section ".init.text","ax"
28
29_sclp_wait_int: 27_sclp_wait_int:
30 stm %r6,%r15,24(%r15) # save registers 28 stm %r6,%r15,24(%r15) # save registers
31 basr %r13,0 # get base register 29 basr %r13,0 # get base register
@@ -318,9 +316,8 @@ _sclp_print_early:
318 .long _sclp_work_area 316 .long _sclp_work_area
319.Lascebc: 317.Lascebc:
320 .long _ascebc 318 .long _ascebc
321.previous
322 319
323.section ".init.data","a" 320.section .data,"aw",@progbits
324 .balign 4096 321 .balign 4096
325_sclp_work_area: 322_sclp_work_area:
326 .fill 4096 323 .fill 4096
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 56c16876b919..b4b6396e6cf0 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -475,10 +475,8 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
475{ 475{
476 unsigned long async_stack, panic_stack; 476 unsigned long async_stack, panic_stack;
477 struct _lowcore *lowcore; 477 struct _lowcore *lowcore;
478 int lc_order;
479 478
480 lc_order = sizeof(long) == 8 ? 1 : 0; 479 lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
481 lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order);
482 if (!lowcore) 480 if (!lowcore)
483 return -ENOMEM; 481 return -ENOMEM;
484 async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); 482 async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
@@ -509,16 +507,14 @@ static int __cpuinit smp_alloc_lowcore(int cpu)
509out: 507out:
510 free_page(panic_stack); 508 free_page(panic_stack);
511 free_pages(async_stack, ASYNC_ORDER); 509 free_pages(async_stack, ASYNC_ORDER);
512 free_pages((unsigned long) lowcore, lc_order); 510 free_pages((unsigned long) lowcore, LC_ORDER);
513 return -ENOMEM; 511 return -ENOMEM;
514} 512}
515 513
516static void smp_free_lowcore(int cpu) 514static void smp_free_lowcore(int cpu)
517{ 515{
518 struct _lowcore *lowcore; 516 struct _lowcore *lowcore;
519 int lc_order;
520 517
521 lc_order = sizeof(long) == 8 ? 1 : 0;
522 lowcore = lowcore_ptr[cpu]; 518 lowcore = lowcore_ptr[cpu];
523#ifndef CONFIG_64BIT 519#ifndef CONFIG_64BIT
524 if (MACHINE_HAS_IEEE) 520 if (MACHINE_HAS_IEEE)
@@ -528,7 +524,7 @@ static void smp_free_lowcore(int cpu)
528#endif 524#endif
529 free_page(lowcore->panic_stack - PAGE_SIZE); 525 free_page(lowcore->panic_stack - PAGE_SIZE);
530 free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER); 526 free_pages(lowcore->async_stack - ASYNC_SIZE, ASYNC_ORDER);
531 free_pages((unsigned long) lowcore, lc_order); 527 free_pages((unsigned long) lowcore, LC_ORDER);
532 lowcore_ptr[cpu] = NULL; 528 lowcore_ptr[cpu] = NULL;
533} 529}
534 530
@@ -664,7 +660,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
664 unsigned long async_stack, panic_stack; 660 unsigned long async_stack, panic_stack;
665 struct _lowcore *lowcore; 661 struct _lowcore *lowcore;
666 unsigned int cpu; 662 unsigned int cpu;
667 int lc_order;
668 663
669 smp_detect_cpus(); 664 smp_detect_cpus();
670 665
@@ -674,8 +669,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
674 print_cpu_info(); 669 print_cpu_info();
675 670
676 /* Reallocate current lowcore, but keep its contents. */ 671 /* Reallocate current lowcore, but keep its contents. */
677 lc_order = sizeof(long) == 8 ? 1 : 0; 672 lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, LC_ORDER);
678 lowcore = (void *) __get_free_pages(GFP_KERNEL | GFP_DMA, lc_order);
679 panic_stack = __get_free_page(GFP_KERNEL); 673 panic_stack = __get_free_page(GFP_KERNEL);
680 async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER); 674 async_stack = __get_free_pages(GFP_KERNEL, ASYNC_ORDER);
681 BUG_ON(!lowcore || !panic_stack || !async_stack); 675 BUG_ON(!lowcore || !panic_stack || !async_stack);
@@ -1047,42 +1041,6 @@ out:
1047static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show, 1041static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show,
1048 dispatching_store); 1042 dispatching_store);
1049 1043
1050/*
1051 * If the resume kernel runs on another cpu than the suspended kernel,
1052 * we have to switch the cpu IDs in the logical map.
1053 */
1054void smp_switch_boot_cpu_in_resume(u32 resume_phys_cpu_id,
1055 struct _lowcore *suspend_lowcore)
1056{
1057 int cpu, suspend_cpu_id, resume_cpu_id;
1058 u32 suspend_phys_cpu_id;
1059
1060 suspend_phys_cpu_id = __cpu_logical_map[suspend_lowcore->cpu_nr];
1061 suspend_cpu_id = suspend_lowcore->cpu_nr;
1062
1063 for_each_present_cpu(cpu) {
1064 if (__cpu_logical_map[cpu] == resume_phys_cpu_id) {
1065 resume_cpu_id = cpu;
1066 goto found;
1067 }
1068 }
1069 panic("Could not find resume cpu in logical map.\n");
1070
1071found:
1072 printk("Resume cpu ID: %i/%i\n", resume_phys_cpu_id, resume_cpu_id);
1073 printk("Suspend cpu ID: %i/%i\n", suspend_phys_cpu_id, suspend_cpu_id);
1074
1075 __cpu_logical_map[resume_cpu_id] = suspend_phys_cpu_id;
1076 __cpu_logical_map[suspend_cpu_id] = resume_phys_cpu_id;
1077
1078 lowcore_ptr[suspend_cpu_id]->cpu_addr = resume_phys_cpu_id;
1079}
1080
1081u32 smp_get_phys_cpu_id(void)
1082{
1083 return __cpu_logical_map[smp_processor_id()];
1084}
1085
1086static int __init topology_init(void) 1044static int __init topology_init(void)
1087{ 1045{
1088 int cpu; 1046 int cpu;
diff --git a/arch/s390/kernel/suspend.c b/arch/s390/kernel/suspend.c
index 086bee970cae..cf9e5c6d5527 100644
--- a/arch/s390/kernel/suspend.c
+++ b/arch/s390/kernel/suspend.c
@@ -6,36 +6,26 @@
6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com> 6 * Author(s): Hans-Joachim Picht <hans@linux.vnet.ibm.com>
7 */ 7 */
8 8
9#include <linux/suspend.h>
10#include <linux/reboot.h>
11#include <linux/pfn.h> 9#include <linux/pfn.h>
12#include <linux/mm.h>
13#include <asm/sections.h>
14#include <asm/system.h> 10#include <asm/system.h>
15#include <asm/ipl.h>
16 11
17/* 12/*
18 * References to section boundaries 13 * References to section boundaries
19 */ 14 */
20extern const void __nosave_begin, __nosave_end; 15extern const void __nosave_begin, __nosave_end;
21 16
22/*
23 * check if given pfn is in the 'nosave' or in the read only NSS section
24 */
25int pfn_is_nosave(unsigned long pfn) 17int pfn_is_nosave(unsigned long pfn)
26{ 18{
27 unsigned long nosave_begin_pfn = __pa(&__nosave_begin) >> PAGE_SHIFT; 19 unsigned long nosave_begin_pfn = PFN_DOWN(__pa(&__nosave_begin));
28 unsigned long nosave_end_pfn = PAGE_ALIGN(__pa(&__nosave_end)) 20 unsigned long nosave_end_pfn = PFN_DOWN(__pa(&__nosave_end));
29 >> PAGE_SHIFT;
30 unsigned long eshared_pfn = PFN_DOWN(__pa(&_eshared)) - 1;
31 unsigned long stext_pfn = PFN_DOWN(__pa(&_stext));
32 21
22 /* Always save lowcore pages (LC protection might be enabled). */
23 if (pfn <= LC_PAGES)
24 return 0;
33 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn) 25 if (pfn >= nosave_begin_pfn && pfn < nosave_end_pfn)
34 return 1; 26 return 1;
35 if (pfn >= stext_pfn && pfn <= eshared_pfn) { 27 /* Skip memory holes and read-only pages (NSS, DCSS, ...). */
36 if (ipl_info.type == IPL_TYPE_NSS) 28 if (tprot(PFN_PHYS(pfn)))
37 return 1;
38 } else if ((tprot(pfn * PAGE_SIZE) && pfn > 0))
39 return 1; 29 return 1;
40 return 0; 30 return 0;
41} 31}
diff --git a/arch/s390/kernel/swsusp_asm64.S b/arch/s390/kernel/swsusp_asm64.S
index 7cd6b096f0d1..fe927d0bc20b 100644
--- a/arch/s390/kernel/swsusp_asm64.S
+++ b/arch/s390/kernel/swsusp_asm64.S
@@ -9,6 +9,7 @@
9 9
10#include <asm/page.h> 10#include <asm/page.h>
11#include <asm/ptrace.h> 11#include <asm/ptrace.h>
12#include <asm/thread_info.h>
12#include <asm/asm-offsets.h> 13#include <asm/asm-offsets.h>
13 14
14/* 15/*
@@ -41,6 +42,9 @@ swsusp_arch_suspend:
41 /* Get pointer to save area */ 42 /* Get pointer to save area */
42 lghi %r1,0x1000 43 lghi %r1,0x1000
43 44
45 /* Save CPU address */
46 stap __LC_CPU_ADDRESS(%r1)
47
44 /* Store registers */ 48 /* Store registers */
45 mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */ 49 mvc 0x318(4,%r1),__SF_EMPTY(%r15) /* move prefix to lowcore */
46 stfpc 0x31c(%r1) /* store fpu control */ 50 stfpc 0x31c(%r1) /* store fpu control */
@@ -102,11 +106,10 @@ swsusp_arch_resume:
102 aghi %r15,-STACK_FRAME_OVERHEAD 106 aghi %r15,-STACK_FRAME_OVERHEAD
103 stg %r1,__SF_BACKCHAIN(%r15) 107 stg %r1,__SF_BACKCHAIN(%r15)
104 108
105#ifdef CONFIG_SMP 109 /* Make all free pages stable */
106 /* Save boot cpu number */ 110 lghi %r2,1
107 brasl %r14,smp_get_phys_cpu_id 111 brasl %r14,arch_set_page_states
108 lgr %r10,%r2 112
109#endif
110 /* Deactivate DAT */ 113 /* Deactivate DAT */
111 stnsm __SF_EMPTY(%r15),0xfb 114 stnsm __SF_EMPTY(%r15),0xfb
112 115
@@ -133,6 +136,69 @@ swsusp_arch_resume:
1332: 1362:
134 ptlb /* flush tlb */ 137 ptlb /* flush tlb */
135 138
139 /* Reset System */
140 larl %r1,restart_entry
141 larl %r2,.Lrestart_diag308_psw
142 og %r1,0(%r2)
143 stg %r1,0(%r0)
144 larl %r1,.Lnew_pgm_check_psw
145 epsw %r2,%r3
146 stm %r2,%r3,0(%r1)
147 mvc __LC_PGM_NEW_PSW(16,%r0),0(%r1)
148 lghi %r0,0
149 diag %r0,%r0,0x308
150restart_entry:
151 lhi %r1,1
152 sigp %r1,%r0,0x12
153 sam64
154 larl %r1,.Lnew_pgm_check_psw
155 lpswe 0(%r1)
156pgm_check_entry:
157
158 /* Switch to original suspend CPU */
159 larl %r1,.Lresume_cpu /* Resume CPU address: r2 */
160 stap 0(%r1)
161 llgh %r2,0(%r1)
162 lghi %r3,0x1000
163 llgh %r1,__LC_CPU_ADDRESS(%r3) /* Suspend CPU address: r1 */
164 cgr %r1,%r2
165 je restore_registers /* r1 = r2 -> nothing to do */
166 larl %r4,.Lrestart_suspend_psw /* Set new restart PSW */
167 mvc __LC_RESTART_PSW(16,%r0),0(%r4)
1683:
169 sigp %r9,%r1,__SIGP_INITIAL_CPU_RESET
170 brc 8,4f /* accepted */
171 brc 2,3b /* busy, try again */
172
173 /* Suspend CPU not available -> panic */
174 larl %r15,init_thread_union
175 ahi %r15,1<<(PAGE_SHIFT+THREAD_ORDER)
176 larl %r2,.Lpanic_string
177 larl %r3,_sclp_print_early
178 lghi %r1,0
179 sam31
180 sigp %r1,%r0,0x12
181 basr %r14,%r3
182 larl %r3,.Ldisabled_wait_31
183 lpsw 0(%r3)
1844:
185 /* Switch to suspend CPU */
186 sigp %r9,%r1,__SIGP_RESTART /* start suspend CPU */
187 brc 2,4b /* busy, try again */
1885:
189 sigp %r9,%r2,__SIGP_STOP /* stop resume (current) CPU */
1906: j 6b
191
192restart_suspend:
193 larl %r1,.Lresume_cpu
194 llgh %r2,0(%r1)
1957:
196 sigp %r9,%r2,__SIGP_SENSE /* Wait for resume CPU */
197 brc 2,7b /* busy, try again */
198 tmll %r9,0x40 /* Test if resume CPU is stopped */
199 jz 7b
200
201restore_registers:
136 /* Restore registers */ 202 /* Restore registers */
137 lghi %r13,0x1000 /* %r1 = pointer to save arae */ 203 lghi %r13,0x1000 /* %r1 = pointer to save arae */
138 204
@@ -166,19 +232,33 @@ swsusp_arch_resume:
166 /* Pointer to save area */ 232 /* Pointer to save area */
167 lghi %r13,0x1000 233 lghi %r13,0x1000
168 234
169#ifdef CONFIG_SMP
170 /* Switch CPUs */
171 lgr %r2,%r10 /* get cpu id */
172 llgf %r3,0x318(%r13)
173 brasl %r14,smp_switch_boot_cpu_in_resume
174#endif
175 /* Restore prefix register */ 235 /* Restore prefix register */
176 spx 0x318(%r13) 236 spx 0x318(%r13)
177 237
178 /* Activate DAT */ 238 /* Activate DAT */
179 stosm __SF_EMPTY(%r15),0x04 239 stosm __SF_EMPTY(%r15),0x04
180 240
241 /* Make all free pages unstable */
242 lghi %r2,0
243 brasl %r14,arch_set_page_states
244
181 /* Return 0 */ 245 /* Return 0 */
182 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15) 246 lmg %r6,%r15,STACK_FRAME_OVERHEAD + __SF_GPRS(%r15)
183 lghi %r2,0 247 lghi %r2,0
184 br %r14 248 br %r14
249
250 .section .data.nosave,"aw",@progbits
251 .align 8
252.Ldisabled_wait_31:
253 .long 0x000a0000,0x00000000
254.Lpanic_string:
255 .asciz "Resume not possible because suspend CPU is no longer available"
256 .align 8
257.Lrestart_diag308_psw:
258 .long 0x00080000,0x80000000
259.Lrestart_suspend_psw:
260 .quad 0x0000000180000000,restart_suspend
261.Lnew_pgm_check_psw:
262 .quad 0,pgm_check_entry
263.Lresume_cpu:
264 .byte 0,0
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 0b5083681e77..30eca070d426 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -19,7 +19,7 @@ SYSCALL(sys_restart_syscall,sys_restart_syscall,sys_restart_syscall)
19SYSCALL(sys_creat,sys_creat,sys32_creat_wrapper) 19SYSCALL(sys_creat,sys_creat,sys32_creat_wrapper)
20SYSCALL(sys_link,sys_link,sys32_link_wrapper) 20SYSCALL(sys_link,sys_link,sys32_link_wrapper)
21SYSCALL(sys_unlink,sys_unlink,sys32_unlink_wrapper) /* 10 */ 21SYSCALL(sys_unlink,sys_unlink,sys32_unlink_wrapper) /* 10 */
22SYSCALL(sys_execve,sys_execve,sys32_execve) 22SYSCALL(sys_execve,sys_execve,sys32_execve_wrapper)
23SYSCALL(sys_chdir,sys_chdir,sys32_chdir_wrapper) 23SYSCALL(sys_chdir,sys_chdir,sys32_chdir_wrapper)
24SYSCALL(sys_time,sys_ni_syscall,sys32_time_wrapper) /* old time syscall */ 24SYSCALL(sys_time,sys_ni_syscall,sys32_time_wrapper) /* old time syscall */
25SYSCALL(sys_mknod,sys_mknod,sys32_mknod_wrapper) 25SYSCALL(sys_mknod,sys_mknod,sys32_mknod_wrapper)
@@ -128,7 +128,7 @@ SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper)
128SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper) 128SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper)
129SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper) 129SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper)
130SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn) 130SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn)
131SYSCALL(sys_clone,sys_clone,sys32_clone) /* 120 */ 131SYSCALL(sys_clone,sys_clone,sys_clone_wrapper) /* 120 */
132SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper) 132SYSCALL(sys_setdomainname,sys_setdomainname,sys32_setdomainname_wrapper)
133SYSCALL(sys_newuname,sys_s390_newuname,sys32_newuname_wrapper) 133SYSCALL(sys_newuname,sys_s390_newuname,sys32_newuname_wrapper)
134NI_SYSCALL /* modify_ldt for i386 */ 134NI_SYSCALL /* modify_ldt for i386 */
@@ -136,8 +136,8 @@ SYSCALL(sys_adjtimex,sys_adjtimex,compat_sys_adjtimex_wrapper)
136SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */ 136SYSCALL(sys_mprotect,sys_mprotect,sys32_mprotect_wrapper) /* 125 */
137SYSCALL(sys_sigprocmask,sys_sigprocmask,compat_sys_sigprocmask_wrapper) 137SYSCALL(sys_sigprocmask,sys_sigprocmask,compat_sys_sigprocmask_wrapper)
138NI_SYSCALL /* old "create module" */ 138NI_SYSCALL /* old "create module" */
139SYSCALL(sys_init_module,sys_init_module,sys32_init_module_wrapper) 139SYSCALL(sys_init_module,sys_init_module,sys_init_module_wrapper)
140SYSCALL(sys_delete_module,sys_delete_module,sys32_delete_module_wrapper) 140SYSCALL(sys_delete_module,sys_delete_module,sys_delete_module_wrapper)
141NI_SYSCALL /* 130: old get_kernel_syms */ 141NI_SYSCALL /* 130: old get_kernel_syms */
142SYSCALL(sys_quotactl,sys_quotactl,sys32_quotactl_wrapper) 142SYSCALL(sys_quotactl,sys_quotactl,sys32_quotactl_wrapper)
143SYSCALL(sys_getpgid,sys_getpgid,sys32_getpgid_wrapper) 143SYSCALL(sys_getpgid,sys_getpgid,sys32_getpgid_wrapper)
diff --git a/arch/s390/mm/page-states.c b/arch/s390/mm/page-states.c
index f92ec203ad92..098923ae458f 100644
--- a/arch/s390/mm/page-states.c
+++ b/arch/s390/mm/page-states.c
@@ -50,28 +50,64 @@ void __init cmma_init(void)
50 cmma_flag = 0; 50 cmma_flag = 0;
51} 51}
52 52
53void arch_free_page(struct page *page, int order) 53static inline void set_page_unstable(struct page *page, int order)
54{ 54{
55 int i, rc; 55 int i, rc;
56 56
57 if (!cmma_flag)
58 return;
59 for (i = 0; i < (1 << order); i++) 57 for (i = 0; i < (1 << order); i++)
60 asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" 58 asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
61 : "=&d" (rc) 59 : "=&d" (rc)
62 : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), 60 : "a" (page_to_phys(page + i)),
63 "i" (ESSA_SET_UNUSED)); 61 "i" (ESSA_SET_UNUSED));
64} 62}
65 63
66void arch_alloc_page(struct page *page, int order) 64void arch_free_page(struct page *page, int order)
67{ 65{
68 int i, rc;
69
70 if (!cmma_flag) 66 if (!cmma_flag)
71 return; 67 return;
68 set_page_unstable(page, order);
69}
70
71static inline void set_page_stable(struct page *page, int order)
72{
73 int i, rc;
74
72 for (i = 0; i < (1 << order); i++) 75 for (i = 0; i < (1 << order); i++)
73 asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0" 76 asm volatile(".insn rrf,0xb9ab0000,%0,%1,%2,0"
74 : "=&d" (rc) 77 : "=&d" (rc)
75 : "a" ((page_to_pfn(page) + i) << PAGE_SHIFT), 78 : "a" (page_to_phys(page + i)),
76 "i" (ESSA_SET_STABLE)); 79 "i" (ESSA_SET_STABLE));
77} 80}
81
82void arch_alloc_page(struct page *page, int order)
83{
84 if (!cmma_flag)
85 return;
86 set_page_stable(page, order);
87}
88
89void arch_set_page_states(int make_stable)
90{
91 unsigned long flags, order, t;
92 struct list_head *l;
93 struct page *page;
94 struct zone *zone;
95
96 if (!cmma_flag)
97 return;
98 if (make_stable)
99 drain_local_pages(NULL);
100 for_each_populated_zone(zone) {
101 spin_lock_irqsave(&zone->lock, flags);
102 for_each_migratetype_order(order, t) {
103 list_for_each(l, &zone->free_area[order].free_list[t]) {
104 page = list_entry(l, struct page, lru);
105 if (make_stable)
106 set_page_stable(page, order);
107 else
108 set_page_unstable(page, order);
109 }
110 }
111 spin_unlock_irqrestore(&zone->lock, flags);
112 }
113}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index c70215247071..c60bfb309ce6 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -314,21 +314,18 @@ int s390_enable_sie(void)
314} 314}
315EXPORT_SYMBOL_GPL(s390_enable_sie); 315EXPORT_SYMBOL_GPL(s390_enable_sie);
316 316
317#ifdef CONFIG_DEBUG_PAGEALLOC 317#if defined(CONFIG_DEBUG_PAGEALLOC) && defined(CONFIG_HIBERNATION)
318#ifdef CONFIG_HIBERNATION
319bool kernel_page_present(struct page *page) 318bool kernel_page_present(struct page *page)
320{ 319{
321 unsigned long addr; 320 unsigned long addr;
322 int cc; 321 int cc;
323 322
324 addr = page_to_phys(page); 323 addr = page_to_phys(page);
325 asm("lra %1,0(%1)\n" 324 asm volatile(
326 "ipm %0\n" 325 " lra %1,0(%1)\n"
327 "srl %0,28" 326 " ipm %0\n"
328 :"=d"(cc),"+a"(addr)::"cc"); 327 " srl %0,28"
328 : "=d" (cc), "+a" (addr) : : "cc");
329 return cc == 0; 329 return cc == 0;
330} 330}
331 331#endif /* CONFIG_HIBERNATION && CONFIG_DEBUG_PAGEALLOC */
332#endif /* CONFIG_HIBERNATION */
333#endif /* CONFIG_DEBUG_PAGEALLOC */
334
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index bd9fe2e36dce..ab3521755588 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -935,6 +935,7 @@ static int dasd_eckd_read_features(struct dasd_device *device)
935 struct dasd_eckd_private *private; 935 struct dasd_eckd_private *private;
936 936
937 private = (struct dasd_eckd_private *) device->private; 937 private = (struct dasd_eckd_private *) device->private;
938 memset(&private->features, 0, sizeof(struct dasd_rssd_features));
938 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */, 939 cqr = dasd_smalloc_request(DASD_ECKD_MAGIC, 1 /* PSF */ + 1 /* RSSD */,
939 (sizeof(struct dasd_psf_prssd_data) + 940 (sizeof(struct dasd_psf_prssd_data) +
940 sizeof(struct dasd_rssd_features)), 941 sizeof(struct dasd_rssd_features)),
@@ -982,7 +983,9 @@ static int dasd_eckd_read_features(struct dasd_device *device)
982 features = (struct dasd_rssd_features *) (prssdp + 1); 983 features = (struct dasd_rssd_features *) (prssdp + 1);
983 memcpy(&private->features, features, 984 memcpy(&private->features, features,
984 sizeof(struct dasd_rssd_features)); 985 sizeof(struct dasd_rssd_features));
985 } 986 } else
987 dev_warn(&device->cdev->dev, "Reading device feature codes"
988 " failed with rc=%d\n", rc);
986 dasd_sfree_request(cqr, cqr->memdev); 989 dasd_sfree_request(cqr, cqr->memdev);
987 return rc; 990 return rc;
988} 991}
@@ -1144,9 +1147,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device)
1144 } 1147 }
1145 1148
1146 /* Read Feature Codes */ 1149 /* Read Feature Codes */
1147 rc = dasd_eckd_read_features(device); 1150 dasd_eckd_read_features(device);
1148 if (rc)
1149 goto out_err3;
1150 1151
1151 /* Read Device Characteristics */ 1152 /* Read Device Characteristics */
1152 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC, 1153 rc = dasd_generic_read_dev_chars(device, DASD_ECKD_MAGIC,
@@ -3241,9 +3242,7 @@ int dasd_eckd_restore_device(struct dasd_device *device)
3241 } 3242 }
3242 3243
3243 /* Read Feature Codes */ 3244 /* Read Feature Codes */
3244 rc = dasd_eckd_read_features(device); 3245 dasd_eckd_read_features(device);
3245 if (rc)
3246 goto out_err;
3247 3246
3248 /* Read Device Characteristics */ 3247 /* Read Device Characteristics */
3249 memset(&private->rdc_data, 0, sizeof(private->rdc_data)); 3248 memset(&private->rdc_data, 0, sizeof(private->rdc_data));
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c
index 393c73c47f87..91c25706fa83 100644
--- a/drivers/s390/cio/css.c
+++ b/drivers/s390/cio/css.c
@@ -31,8 +31,7 @@
31#include "chp.h" 31#include "chp.h"
32 32
33int css_init_done = 0; 33int css_init_done = 0;
34static int need_reprobe = 0; 34int max_ssid;
35static int max_ssid = 0;
36 35
37struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1]; 36struct channel_subsystem *channel_subsystems[__MAX_CSSID + 1];
38 37
@@ -315,12 +314,18 @@ int css_probe_device(struct subchannel_id schid)
315 int ret; 314 int ret;
316 struct subchannel *sch; 315 struct subchannel *sch;
317 316
318 sch = css_alloc_subchannel(schid); 317 if (cio_is_console(schid))
319 if (IS_ERR(sch)) 318 sch = cio_get_console_subchannel();
320 return PTR_ERR(sch); 319 else {
320 sch = css_alloc_subchannel(schid);
321 if (IS_ERR(sch))
322 return PTR_ERR(sch);
323 }
321 ret = css_register_subchannel(sch); 324 ret = css_register_subchannel(sch);
322 if (ret) 325 if (ret) {
323 put_device(&sch->dev); 326 if (!cio_is_console(schid))
327 put_device(&sch->dev);
328 }
324 return ret; 329 return ret;
325} 330}
326 331
@@ -409,10 +414,14 @@ static void css_evaluate_subchannel(struct subchannel_id schid, int slow)
409 414
410static struct idset *slow_subchannel_set; 415static struct idset *slow_subchannel_set;
411static spinlock_t slow_subchannel_lock; 416static spinlock_t slow_subchannel_lock;
417static wait_queue_head_t css_eval_wq;
418static atomic_t css_eval_scheduled;
412 419
413static int __init slow_subchannel_init(void) 420static int __init slow_subchannel_init(void)
414{ 421{
415 spin_lock_init(&slow_subchannel_lock); 422 spin_lock_init(&slow_subchannel_lock);
423 atomic_set(&css_eval_scheduled, 0);
424 init_waitqueue_head(&css_eval_wq);
416 slow_subchannel_set = idset_sch_new(); 425 slow_subchannel_set = idset_sch_new();
417 if (!slow_subchannel_set) { 426 if (!slow_subchannel_set) {
418 CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n"); 427 CIO_MSG_EVENT(0, "could not allocate slow subchannel set\n");
@@ -468,9 +477,17 @@ static int slow_eval_unknown_fn(struct subchannel_id schid, void *data)
468 477
469static void css_slow_path_func(struct work_struct *unused) 478static void css_slow_path_func(struct work_struct *unused)
470{ 479{
480 unsigned long flags;
481
471 CIO_TRACE_EVENT(4, "slowpath"); 482 CIO_TRACE_EVENT(4, "slowpath");
472 for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn, 483 for_each_subchannel_staged(slow_eval_known_fn, slow_eval_unknown_fn,
473 NULL); 484 NULL);
485 spin_lock_irqsave(&slow_subchannel_lock, flags);
486 if (idset_is_empty(slow_subchannel_set)) {
487 atomic_set(&css_eval_scheduled, 0);
488 wake_up(&css_eval_wq);
489 }
490 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
474} 491}
475 492
476static DECLARE_WORK(slow_path_work, css_slow_path_func); 493static DECLARE_WORK(slow_path_work, css_slow_path_func);
@@ -482,6 +499,7 @@ void css_schedule_eval(struct subchannel_id schid)
482 499
483 spin_lock_irqsave(&slow_subchannel_lock, flags); 500 spin_lock_irqsave(&slow_subchannel_lock, flags);
484 idset_sch_add(slow_subchannel_set, schid); 501 idset_sch_add(slow_subchannel_set, schid);
502 atomic_set(&css_eval_scheduled, 1);
485 queue_work(slow_path_wq, &slow_path_work); 503 queue_work(slow_path_wq, &slow_path_work);
486 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 504 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
487} 505}
@@ -492,80 +510,53 @@ void css_schedule_eval_all(void)
492 510
493 spin_lock_irqsave(&slow_subchannel_lock, flags); 511 spin_lock_irqsave(&slow_subchannel_lock, flags);
494 idset_fill(slow_subchannel_set); 512 idset_fill(slow_subchannel_set);
513 atomic_set(&css_eval_scheduled, 1);
495 queue_work(slow_path_wq, &slow_path_work); 514 queue_work(slow_path_wq, &slow_path_work);
496 spin_unlock_irqrestore(&slow_subchannel_lock, flags); 515 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
497} 516}
498 517
499void css_wait_for_slow_path(void) 518static int __unset_registered(struct device *dev, void *data)
500{ 519{
501 flush_workqueue(slow_path_wq); 520 struct idset *set = data;
502} 521 struct subchannel *sch = to_subchannel(dev);
503
504/* Reprobe subchannel if unregistered. */
505static int reprobe_subchannel(struct subchannel_id schid, void *data)
506{
507 int ret;
508
509 CIO_MSG_EVENT(6, "cio: reprobe 0.%x.%04x\n",
510 schid.ssid, schid.sch_no);
511 if (need_reprobe)
512 return -EAGAIN;
513
514 ret = css_probe_device(schid);
515 switch (ret) {
516 case 0:
517 break;
518 case -ENXIO:
519 case -ENOMEM:
520 case -EIO:
521 /* These should abort looping */
522 break;
523 default:
524 ret = 0;
525 }
526
527 return ret;
528}
529 522
530static void reprobe_after_idle(struct work_struct *unused) 523 idset_sch_del(set, sch->schid);
531{ 524 return 0;
532 /* Make sure initial subchannel scan is done. */
533 wait_event(ccw_device_init_wq,
534 atomic_read(&ccw_device_init_count) == 0);
535 if (need_reprobe)
536 css_schedule_reprobe();
537} 525}
538 526
539static DECLARE_WORK(reprobe_idle_work, reprobe_after_idle); 527void css_schedule_eval_all_unreg(void)
540
541/* Work function used to reprobe all unregistered subchannels. */
542static void reprobe_all(struct work_struct *unused)
543{ 528{
544 int ret; 529 unsigned long flags;
545 530 struct idset *unreg_set;
546 CIO_MSG_EVENT(4, "reprobe start\n");
547 531
548 /* Make sure initial subchannel scan is done. */ 532 /* Find unregistered subchannels. */
549 if (atomic_read(&ccw_device_init_count) != 0) { 533 unreg_set = idset_sch_new();
550 queue_work(ccw_device_work, &reprobe_idle_work); 534 if (!unreg_set) {
535 /* Fallback. */
536 css_schedule_eval_all();
551 return; 537 return;
552 } 538 }
553 need_reprobe = 0; 539 idset_fill(unreg_set);
554 ret = for_each_subchannel_staged(NULL, reprobe_subchannel, NULL); 540 bus_for_each_dev(&css_bus_type, NULL, unreg_set, __unset_registered);
555 541 /* Apply to slow_subchannel_set. */
556 CIO_MSG_EVENT(4, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, 542 spin_lock_irqsave(&slow_subchannel_lock, flags);
557 need_reprobe); 543 idset_add_set(slow_subchannel_set, unreg_set);
544 atomic_set(&css_eval_scheduled, 1);
545 queue_work(slow_path_wq, &slow_path_work);
546 spin_unlock_irqrestore(&slow_subchannel_lock, flags);
547 idset_free(unreg_set);
558} 548}
559 549
560static DECLARE_WORK(css_reprobe_work, reprobe_all); 550void css_wait_for_slow_path(void)
551{
552 flush_workqueue(slow_path_wq);
553}
561 554
562/* Schedule reprobing of all unregistered subchannels. */ 555/* Schedule reprobing of all unregistered subchannels. */
563void css_schedule_reprobe(void) 556void css_schedule_reprobe(void)
564{ 557{
565 need_reprobe = 1; 558 css_schedule_eval_all_unreg();
566 queue_work(slow_path_wq, &css_reprobe_work);
567} 559}
568
569EXPORT_SYMBOL_GPL(css_schedule_reprobe); 560EXPORT_SYMBOL_GPL(css_schedule_reprobe);
570 561
571/* 562/*
@@ -601,49 +592,6 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow)
601 css_evaluate_subchannel(mchk_schid, 0); 592 css_evaluate_subchannel(mchk_schid, 0);
602} 593}
603 594
604static int __init
605__init_channel_subsystem(struct subchannel_id schid, void *data)
606{
607 struct subchannel *sch;
608 int ret;
609
610 if (cio_is_console(schid))
611 sch = cio_get_console_subchannel();
612 else {
613 sch = css_alloc_subchannel(schid);
614 if (IS_ERR(sch))
615 ret = PTR_ERR(sch);
616 else
617 ret = 0;
618 switch (ret) {
619 case 0:
620 break;
621 case -ENOMEM:
622 panic("Out of memory in init_channel_subsystem\n");
623 /* -ENXIO: no more subchannels. */
624 case -ENXIO:
625 return ret;
626 /* -EIO: this subchannel set not supported. */
627 case -EIO:
628 return ret;
629 default:
630 return 0;
631 }
632 }
633 /*
634 * We register ALL valid subchannels in ioinfo, even those
635 * that have been present before init_channel_subsystem.
636 * These subchannels can't have been registered yet (kmalloc
637 * not working) so we do it now. This is true e.g. for the
638 * console subchannel.
639 */
640 if (css_register_subchannel(sch)) {
641 if (!cio_is_console(schid))
642 put_device(&sch->dev);
643 }
644 return 0;
645}
646
647static void __init 595static void __init
648css_generate_pgid(struct channel_subsystem *css, u32 tod_high) 596css_generate_pgid(struct channel_subsystem *css, u32 tod_high)
649{ 597{
@@ -854,19 +802,30 @@ static struct notifier_block css_power_notifier = {
854 * The struct subchannel's are created during probing (except for the 802 * The struct subchannel's are created during probing (except for the
855 * static console subchannel). 803 * static console subchannel).
856 */ 804 */
857static int __init 805static int __init css_bus_init(void)
858init_channel_subsystem (void)
859{ 806{
860 int ret, i; 807 int ret, i;
861 808
862 ret = chsc_determine_css_characteristics(); 809 ret = chsc_determine_css_characteristics();
863 if (ret == -ENOMEM) 810 if (ret == -ENOMEM)
864 goto out; /* No need to continue. */ 811 goto out;
865 812
866 ret = chsc_alloc_sei_area(); 813 ret = chsc_alloc_sei_area();
867 if (ret) 814 if (ret)
868 goto out; 815 goto out;
869 816
817 /* Try to enable MSS. */
818 ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
819 switch (ret) {
820 case 0: /* Success. */
821 max_ssid = __MAX_SSID;
822 break;
823 case -ENOMEM:
824 goto out;
825 default:
826 max_ssid = 0;
827 }
828
870 ret = slow_subchannel_init(); 829 ret = slow_subchannel_init();
871 if (ret) 830 if (ret)
872 goto out; 831 goto out;
@@ -878,17 +837,6 @@ init_channel_subsystem (void)
878 if ((ret = bus_register(&css_bus_type))) 837 if ((ret = bus_register(&css_bus_type)))
879 goto out; 838 goto out;
880 839
881 /* Try to enable MSS. */
882 ret = chsc_enable_facility(CHSC_SDA_OC_MSS);
883 switch (ret) {
884 case 0: /* Success. */
885 max_ssid = __MAX_SSID;
886 break;
887 case -ENOMEM:
888 goto out_bus;
889 default:
890 max_ssid = 0;
891 }
892 /* Setup css structure. */ 840 /* Setup css structure. */
893 for (i = 0; i <= __MAX_CSSID; i++) { 841 for (i = 0; i <= __MAX_CSSID; i++) {
894 struct channel_subsystem *css; 842 struct channel_subsystem *css;
@@ -934,7 +882,6 @@ init_channel_subsystem (void)
934 /* Enable default isc for I/O subchannels. */ 882 /* Enable default isc for I/O subchannels. */
935 isc_register(IO_SCH_ISC); 883 isc_register(IO_SCH_ISC);
936 884
937 for_each_subchannel(__init_channel_subsystem, NULL);
938 return 0; 885 return 0;
939out_file: 886out_file:
940 if (css_chsc_characteristics.secm) 887 if (css_chsc_characteristics.secm)
@@ -955,17 +902,76 @@ out_unregister:
955 &dev_attr_cm_enable); 902 &dev_attr_cm_enable);
956 device_unregister(&css->device); 903 device_unregister(&css->device);
957 } 904 }
958out_bus:
959 bus_unregister(&css_bus_type); 905 bus_unregister(&css_bus_type);
960out: 906out:
961 crw_unregister_handler(CRW_RSC_CSS); 907 crw_unregister_handler(CRW_RSC_CSS);
962 chsc_free_sei_area(); 908 chsc_free_sei_area();
963 kfree(slow_subchannel_set); 909 idset_free(slow_subchannel_set);
964 pr_alert("The CSS device driver initialization failed with " 910 pr_alert("The CSS device driver initialization failed with "
965 "errno=%d\n", ret); 911 "errno=%d\n", ret);
966 return ret; 912 return ret;
967} 913}
968 914
915static void __init css_bus_cleanup(void)
916{
917 struct channel_subsystem *css;
918 int i;
919
920 for (i = 0; i <= __MAX_CSSID; i++) {
921 css = channel_subsystems[i];
922 device_unregister(&css->pseudo_subchannel->dev);
923 css->pseudo_subchannel = NULL;
924 if (css_chsc_characteristics.secm)
925 device_remove_file(&css->device, &dev_attr_cm_enable);
926 device_unregister(&css->device);
927 }
928 bus_unregister(&css_bus_type);
929 crw_unregister_handler(CRW_RSC_CSS);
930 chsc_free_sei_area();
931 idset_free(slow_subchannel_set);
932 isc_unregister(IO_SCH_ISC);
933}
934
935static int __init channel_subsystem_init(void)
936{
937 int ret;
938
939 ret = css_bus_init();
940 if (ret)
941 return ret;
942
943 ret = io_subchannel_init();
944 if (ret)
945 css_bus_cleanup();
946
947 return ret;
948}
949subsys_initcall(channel_subsystem_init);
950
951static int css_settle(struct device_driver *drv, void *unused)
952{
953 struct css_driver *cssdrv = to_cssdriver(drv);
954
955 if (cssdrv->settle)
956 cssdrv->settle();
957 return 0;
958}
959
960/*
961 * Wait for the initialization of devices to finish, to make sure we are
962 * done with our setup if the search for the root device starts.
963 */
964static int __init channel_subsystem_init_sync(void)
965{
966 /* Start initial subchannel evaluation. */
967 css_schedule_eval_all();
968 /* Wait for the evaluation of subchannels to finish. */
969 wait_event(css_eval_wq, atomic_read(&css_eval_scheduled) == 0);
970 /* Wait for the subchannel type specific initialization to finish */
971 return bus_for_each_drv(&css_bus_type, NULL, NULL, css_settle);
972}
973subsys_initcall_sync(channel_subsystem_init_sync);
974
969int sch_is_pseudo_sch(struct subchannel *sch) 975int sch_is_pseudo_sch(struct subchannel *sch)
970{ 976{
971 return sch == to_css(sch->dev.parent)->pseudo_subchannel; 977 return sch == to_css(sch->dev.parent)->pseudo_subchannel;
@@ -1135,7 +1141,5 @@ void css_driver_unregister(struct css_driver *cdrv)
1135} 1141}
1136EXPORT_SYMBOL_GPL(css_driver_unregister); 1142EXPORT_SYMBOL_GPL(css_driver_unregister);
1137 1143
1138subsys_initcall(init_channel_subsystem);
1139
1140MODULE_LICENSE("GPL"); 1144MODULE_LICENSE("GPL");
1141EXPORT_SYMBOL(css_bus_type); 1145EXPORT_SYMBOL(css_bus_type);
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 9763eeec7458..68d6b0bf151c 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -75,6 +75,7 @@ struct chp_link;
75 * @freeze: callback for freezing during hibernation snapshotting 75 * @freeze: callback for freezing during hibernation snapshotting
76 * @thaw: undo work done in @freeze 76 * @thaw: undo work done in @freeze
77 * @restore: callback for restoring after hibernation 77 * @restore: callback for restoring after hibernation
78 * @settle: wait for asynchronous work to finish
78 * @name: name of the device driver 79 * @name: name of the device driver
79 */ 80 */
80struct css_driver { 81struct css_driver {
@@ -92,6 +93,7 @@ struct css_driver {
92 int (*freeze)(struct subchannel *); 93 int (*freeze)(struct subchannel *);
93 int (*thaw) (struct subchannel *); 94 int (*thaw) (struct subchannel *);
94 int (*restore)(struct subchannel *); 95 int (*restore)(struct subchannel *);
96 void (*settle)(void);
95 const char *name; 97 const char *name;
96}; 98};
97 99
@@ -109,6 +111,7 @@ extern void css_sch_device_unregister(struct subchannel *);
109extern int css_probe_device(struct subchannel_id); 111extern int css_probe_device(struct subchannel_id);
110extern struct subchannel *get_subchannel_by_schid(struct subchannel_id); 112extern struct subchannel *get_subchannel_by_schid(struct subchannel_id);
111extern int css_init_done; 113extern int css_init_done;
114extern int max_ssid;
112int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *), 115int for_each_subchannel_staged(int (*fn_known)(struct subchannel *, void *),
113 int (*fn_unknown)(struct subchannel_id, 116 int (*fn_unknown)(struct subchannel_id,
114 void *), void *data); 117 void *), void *data);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 6527f3f34493..f780bdd3a04e 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -131,6 +131,10 @@ static void io_subchannel_shutdown(struct subchannel *);
131static int io_subchannel_sch_event(struct subchannel *, int); 131static int io_subchannel_sch_event(struct subchannel *, int);
132static int io_subchannel_chp_event(struct subchannel *, struct chp_link *, 132static int io_subchannel_chp_event(struct subchannel *, struct chp_link *,
133 int); 133 int);
134static void recovery_func(unsigned long data);
135struct workqueue_struct *ccw_device_work;
136wait_queue_head_t ccw_device_init_wq;
137atomic_t ccw_device_init_count;
134 138
135static struct css_device_id io_subchannel_ids[] = { 139static struct css_device_id io_subchannel_ids[] = {
136 { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, }, 140 { .match_flags = 0x1, .type = SUBCHANNEL_TYPE_IO, },
@@ -151,6 +155,13 @@ static int io_subchannel_prepare(struct subchannel *sch)
151 return 0; 155 return 0;
152} 156}
153 157
158static void io_subchannel_settle(void)
159{
160 wait_event(ccw_device_init_wq,
161 atomic_read(&ccw_device_init_count) == 0);
162 flush_workqueue(ccw_device_work);
163}
164
154static struct css_driver io_subchannel_driver = { 165static struct css_driver io_subchannel_driver = {
155 .owner = THIS_MODULE, 166 .owner = THIS_MODULE,
156 .subchannel_type = io_subchannel_ids, 167 .subchannel_type = io_subchannel_ids,
@@ -162,16 +173,10 @@ static struct css_driver io_subchannel_driver = {
162 .remove = io_subchannel_remove, 173 .remove = io_subchannel_remove,
163 .shutdown = io_subchannel_shutdown, 174 .shutdown = io_subchannel_shutdown,
164 .prepare = io_subchannel_prepare, 175 .prepare = io_subchannel_prepare,
176 .settle = io_subchannel_settle,
165}; 177};
166 178
167struct workqueue_struct *ccw_device_work; 179int __init io_subchannel_init(void)
168wait_queue_head_t ccw_device_init_wq;
169atomic_t ccw_device_init_count;
170
171static void recovery_func(unsigned long data);
172
173static int __init
174init_ccw_bus_type (void)
175{ 180{
176 int ret; 181 int ret;
177 182
@@ -181,10 +186,10 @@ init_ccw_bus_type (void)
181 186
182 ccw_device_work = create_singlethread_workqueue("cio"); 187 ccw_device_work = create_singlethread_workqueue("cio");
183 if (!ccw_device_work) 188 if (!ccw_device_work)
184 return -ENOMEM; /* FIXME: better errno ? */ 189 return -ENOMEM;
185 slow_path_wq = create_singlethread_workqueue("kslowcrw"); 190 slow_path_wq = create_singlethread_workqueue("kslowcrw");
186 if (!slow_path_wq) { 191 if (!slow_path_wq) {
187 ret = -ENOMEM; /* FIXME: better errno ? */ 192 ret = -ENOMEM;
188 goto out_err; 193 goto out_err;
189 } 194 }
190 if ((ret = bus_register (&ccw_bus_type))) 195 if ((ret = bus_register (&ccw_bus_type)))
@@ -194,9 +199,6 @@ init_ccw_bus_type (void)
194 if (ret) 199 if (ret)
195 goto out_err; 200 goto out_err;
196 201
197 wait_event(ccw_device_init_wq,
198 atomic_read(&ccw_device_init_count) == 0);
199 flush_workqueue(ccw_device_work);
200 return 0; 202 return 0;
201out_err: 203out_err:
202 if (ccw_device_work) 204 if (ccw_device_work)
@@ -206,16 +208,6 @@ out_err:
206 return ret; 208 return ret;
207} 209}
208 210
209static void __exit
210cleanup_ccw_bus_type (void)
211{
212 css_driver_unregister(&io_subchannel_driver);
213 bus_unregister(&ccw_bus_type);
214 destroy_workqueue(ccw_device_work);
215}
216
217subsys_initcall(init_ccw_bus_type);
218module_exit(cleanup_ccw_bus_type);
219 211
220/************************ device handling **************************/ 212/************************ device handling **************************/
221 213
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index e3975107a578..ed39a2caaf47 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -74,6 +74,7 @@ dev_fsm_final_state(struct ccw_device *cdev)
74extern struct workqueue_struct *ccw_device_work; 74extern struct workqueue_struct *ccw_device_work;
75extern wait_queue_head_t ccw_device_init_wq; 75extern wait_queue_head_t ccw_device_init_wq;
76extern atomic_t ccw_device_init_count; 76extern atomic_t ccw_device_init_count;
77int __init io_subchannel_init(void);
77 78
78void io_subchannel_recog_done(struct ccw_device *cdev); 79void io_subchannel_recog_done(struct ccw_device *cdev);
79void io_subchannel_init_config(struct subchannel *sch); 80void io_subchannel_init_config(struct subchannel *sch);
diff --git a/drivers/s390/cio/idset.c b/drivers/s390/cio/idset.c
index cf8f24a4b5eb..4d10981c7cc1 100644
--- a/drivers/s390/cio/idset.c
+++ b/drivers/s390/cio/idset.c
@@ -78,7 +78,7 @@ static inline int idset_get_first(struct idset *set, int *ssid, int *id)
78 78
79struct idset *idset_sch_new(void) 79struct idset *idset_sch_new(void)
80{ 80{
81 return idset_new(__MAX_SSID + 1, __MAX_SUBCHANNEL + 1); 81 return idset_new(max_ssid + 1, __MAX_SUBCHANNEL + 1);
82} 82}
83 83
84void idset_sch_add(struct idset *set, struct subchannel_id schid) 84void idset_sch_add(struct idset *set, struct subchannel_id schid)
@@ -110,3 +110,23 @@ int idset_sch_get_first(struct idset *set, struct subchannel_id *schid)
110 } 110 }
111 return rc; 111 return rc;
112} 112}
113
114int idset_is_empty(struct idset *set)
115{
116 int bitnum;
117
118 bitnum = find_first_bit(set->bitmap, set->num_ssid * set->num_id);
119 if (bitnum >= set->num_ssid * set->num_id)
120 return 1;
121 return 0;
122}
123
124void idset_add_set(struct idset *to, struct idset *from)
125{
126 unsigned long i, len;
127
128 len = min(__BITOPS_WORDS(to->num_ssid * to->num_id),
129 __BITOPS_WORDS(from->num_ssid * from->num_id));
130 for (i = 0; i < len ; i++)
131 to->bitmap[i] |= from->bitmap[i];
132}
diff --git a/drivers/s390/cio/idset.h b/drivers/s390/cio/idset.h
index 528065cb5021..7543da4529f9 100644
--- a/drivers/s390/cio/idset.h
+++ b/drivers/s390/cio/idset.h
@@ -21,5 +21,7 @@ void idset_sch_add(struct idset *set, struct subchannel_id id);
21void idset_sch_del(struct idset *set, struct subchannel_id id); 21void idset_sch_del(struct idset *set, struct subchannel_id id);
22int idset_sch_contains(struct idset *set, struct subchannel_id id); 22int idset_sch_contains(struct idset *set, struct subchannel_id id);
23int idset_sch_get_first(struct idset *set, struct subchannel_id *id); 23int idset_sch_get_first(struct idset *set, struct subchannel_id *id);
24int idset_is_empty(struct idset *set);
25void idset_add_set(struct idset *to, struct idset *from);
24 26
25#endif /* S390_IDSET_H */ 27#endif /* S390_IDSET_H */
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 9aef402a5f1b..4be6e84b9599 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -401,7 +401,7 @@ static void announce_buffer_error(struct qdio_q *q, int count)
401 if ((!q->is_input_q && 401 if ((!q->is_input_q &&
402 (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) { 402 (q->sbal[q->first_to_check]->element[15].flags & 0xff) == 0x10)) {
403 qdio_perf_stat_inc(&perf_stats.outbound_target_full); 403 qdio_perf_stat_inc(&perf_stats.outbound_target_full);
404 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%3d", 404 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x",
405 q->first_to_check); 405 q->first_to_check);
406 return; 406 return;
407 } 407 }
@@ -418,7 +418,7 @@ static inline void inbound_primed(struct qdio_q *q, int count)
418{ 418{
419 int new; 419 int new;
420 420
421 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim: %3d", count); 421 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in prim: %02x", count);
422 422
423 /* for QEBSM the ACK was already set by EQBS */ 423 /* for QEBSM the ACK was already set by EQBS */
424 if (is_qebsm(q)) { 424 if (is_qebsm(q)) {
@@ -455,6 +455,8 @@ static inline void inbound_primed(struct qdio_q *q, int count)
455 count--; 455 count--;
456 if (!count) 456 if (!count)
457 return; 457 return;
458 /* need to change ALL buffers to get more interrupts */
459 set_buf_states(q, q->first_to_check, SLSB_P_INPUT_NOT_INIT, count);
458} 460}
459 461
460static int get_inbound_buffer_frontier(struct qdio_q *q) 462static int get_inbound_buffer_frontier(struct qdio_q *q)
@@ -545,7 +547,7 @@ static inline int qdio_inbound_q_done(struct qdio_q *q)
545 * has (probably) not moved (see qdio_inbound_processing). 547 * has (probably) not moved (see qdio_inbound_processing).
546 */ 548 */
547 if (get_usecs() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) { 549 if (get_usecs() > q->u.in.timestamp + QDIO_INPUT_THRESHOLD) {
548 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in done:%3d", 550 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in done:%02x",
549 q->first_to_check); 551 q->first_to_check);
550 return 1; 552 return 1;
551 } else 553 } else
@@ -565,11 +567,10 @@ static void qdio_kick_handler(struct qdio_q *q)
565 567
566 if (q->is_input_q) { 568 if (q->is_input_q) {
567 qdio_perf_stat_inc(&perf_stats.inbound_handler); 569 qdio_perf_stat_inc(&perf_stats.inbound_handler);
568 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%3d c:%3d", start, count); 570 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "kih s:%02x c:%02x", start, count);
569 } else { 571 } else
570 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: nr:%1d", q->nr); 572 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
571 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "s:%3d c:%3d", start, count); 573 start, count);
572 }
573 574
574 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count, 575 q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr, start, count,
575 q->irq_ptr->int_parm); 576 q->irq_ptr->int_parm);
@@ -633,7 +634,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
633 switch (state) { 634 switch (state) {
634 case SLSB_P_OUTPUT_EMPTY: 635 case SLSB_P_OUTPUT_EMPTY:
635 /* the adapter got it */ 636 /* the adapter got it */
636 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out empty:%1d %3d", q->nr, count); 637 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out empty:%1d %02x", q->nr, count);
637 638
638 atomic_sub(count, &q->nr_buf_used); 639 atomic_sub(count, &q->nr_buf_used);
639 q->first_to_check = add_buf(q->first_to_check, count); 640 q->first_to_check = add_buf(q->first_to_check, count);
@@ -1481,10 +1482,9 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
1481 get_buf_state(q, prev_buf(bufnr), &state, 0); 1482 get_buf_state(q, prev_buf(bufnr), &state, 0);
1482 if (state != SLSB_CU_OUTPUT_PRIMED) 1483 if (state != SLSB_CU_OUTPUT_PRIMED)
1483 rc = qdio_kick_outbound_q(q); 1484 rc = qdio_kick_outbound_q(q);
1484 else { 1485 else
1485 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "fast-req");
1486 qdio_perf_stat_inc(&perf_stats.fast_requeue); 1486 qdio_perf_stat_inc(&perf_stats.fast_requeue);
1487 } 1487
1488out: 1488out:
1489 tasklet_schedule(&q->tasklet); 1489 tasklet_schedule(&q->tasklet);
1490 return rc; 1490 return rc;
@@ -1510,12 +1510,8 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1510 if (!irq_ptr) 1510 if (!irq_ptr)
1511 return -ENODEV; 1511 return -ENODEV;
1512 1512
1513 if (callflags & QDIO_FLAG_SYNC_INPUT) 1513 DBF_DEV_EVENT(DBF_INFO, irq_ptr,
1514 DBF_DEV_EVENT(DBF_INFO, irq_ptr, "doQDIO input"); 1514 "do%02x b:%02x c:%02x", callflags, bufnr, count);
1515 else
1516 DBF_DEV_EVENT(DBF_INFO, irq_ptr, "doQDIO output");
1517 DBF_DEV_EVENT(DBF_INFO, irq_ptr, "q:%1d flag:%4x", q_nr, callflags);
1518 DBF_DEV_EVENT(DBF_INFO, irq_ptr, "buf:%2d cnt:%3d", bufnr, count);
1519 1515
1520 if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) 1516 if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
1521 return -EBUSY; 1517 return -EBUSY;
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 090b32a339c6..1294876bf7b4 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -60,6 +60,7 @@ static int ap_device_probe(struct device *dev);
60static void ap_interrupt_handler(void *unused1, void *unused2); 60static void ap_interrupt_handler(void *unused1, void *unused2);
61static void ap_reset(struct ap_device *ap_dev); 61static void ap_reset(struct ap_device *ap_dev);
62static void ap_config_timeout(unsigned long ptr); 62static void ap_config_timeout(unsigned long ptr);
63static int ap_select_domain(void);
63 64
64/* 65/*
65 * Module description. 66 * Module description.
@@ -109,6 +110,10 @@ static unsigned long long poll_timeout = 250000;
109 110
110/* Suspend flag */ 111/* Suspend flag */
111static int ap_suspend_flag; 112static int ap_suspend_flag;
113/* Flag to check if domain was set through module parameter domain=. This is
114 * important when supsend and resume is done in a z/VM environment where the
115 * domain might change. */
116static int user_set_domain = 0;
112static struct bus_type ap_bus_type; 117static struct bus_type ap_bus_type;
113 118
114/** 119/**
@@ -643,6 +648,7 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state)
643 destroy_workqueue(ap_work_queue); 648 destroy_workqueue(ap_work_queue);
644 ap_work_queue = NULL; 649 ap_work_queue = NULL;
645 } 650 }
651
646 tasklet_disable(&ap_tasklet); 652 tasklet_disable(&ap_tasklet);
647 } 653 }
648 /* Poll on the device until all requests are finished. */ 654 /* Poll on the device until all requests are finished. */
@@ -653,7 +659,10 @@ static int ap_bus_suspend(struct device *dev, pm_message_t state)
653 spin_unlock_bh(&ap_dev->lock); 659 spin_unlock_bh(&ap_dev->lock);
654 } while ((flags & 1) || (flags & 2)); 660 } while ((flags & 1) || (flags & 2));
655 661
656 ap_device_remove(dev); 662 spin_lock_bh(&ap_dev->lock);
663 ap_dev->unregistered = 1;
664 spin_unlock_bh(&ap_dev->lock);
665
657 return 0; 666 return 0;
658} 667}
659 668
@@ -666,11 +675,10 @@ static int ap_bus_resume(struct device *dev)
666 ap_suspend_flag = 0; 675 ap_suspend_flag = 0;
667 if (!ap_interrupts_available()) 676 if (!ap_interrupts_available())
668 ap_interrupt_indicator = NULL; 677 ap_interrupt_indicator = NULL;
669 ap_device_probe(dev); 678 if (!user_set_domain) {
670 ap_reset(ap_dev); 679 ap_domain_index = -1;
671 setup_timer(&ap_dev->timeout, ap_request_timeout, 680 ap_select_domain();
672 (unsigned long) ap_dev); 681 }
673 ap_scan_bus(NULL);
674 init_timer(&ap_config_timer); 682 init_timer(&ap_config_timer);
675 ap_config_timer.function = ap_config_timeout; 683 ap_config_timer.function = ap_config_timeout;
676 ap_config_timer.data = 0; 684 ap_config_timer.data = 0;
@@ -686,12 +694,14 @@ static int ap_bus_resume(struct device *dev)
686 tasklet_schedule(&ap_tasklet); 694 tasklet_schedule(&ap_tasklet);
687 if (ap_thread_flag) 695 if (ap_thread_flag)
688 rc = ap_poll_thread_start(); 696 rc = ap_poll_thread_start();
689 } else {
690 ap_device_probe(dev);
691 ap_reset(ap_dev);
692 setup_timer(&ap_dev->timeout, ap_request_timeout,
693 (unsigned long) ap_dev);
694 } 697 }
698 if (AP_QID_QUEUE(ap_dev->qid) != ap_domain_index) {
699 spin_lock_bh(&ap_dev->lock);
700 ap_dev->qid = AP_MKQID(AP_QID_DEVICE(ap_dev->qid),
701 ap_domain_index);
702 spin_unlock_bh(&ap_dev->lock);
703 }
704 queue_work(ap_work_queue, &ap_config_work);
695 705
696 return rc; 706 return rc;
697} 707}
@@ -1079,6 +1089,8 @@ static void ap_scan_bus(struct work_struct *unused)
1079 spin_lock_bh(&ap_dev->lock); 1089 spin_lock_bh(&ap_dev->lock);
1080 if (rc || ap_dev->unregistered) { 1090 if (rc || ap_dev->unregistered) {
1081 spin_unlock_bh(&ap_dev->lock); 1091 spin_unlock_bh(&ap_dev->lock);
1092 if (ap_dev->unregistered)
1093 i--;
1082 device_unregister(dev); 1094 device_unregister(dev);
1083 put_device(dev); 1095 put_device(dev);
1084 continue; 1096 continue;
@@ -1586,6 +1598,12 @@ int __init ap_module_init(void)
1586 ap_domain_index); 1598 ap_domain_index);
1587 return -EINVAL; 1599 return -EINVAL;
1588 } 1600 }
1601 /* In resume callback we need to know if the user had set the domain.
1602 * If so, we can not just reset it.
1603 */
1604 if (ap_domain_index >= 0)
1605 user_set_domain = 1;
1606
1589 if (ap_instructions_available() != 0) { 1607 if (ap_instructions_available() != 0) {
1590 pr_warning("The hardware system does not support " 1608 pr_warning("The hardware system does not support "
1591 "AP instructions\n"); 1609 "AP instructions\n");