diff options
author | Michael Holzheu <holzheu@de.ibm.com> | 2006-12-15 11:18:22 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-12-15 11:18:22 -0500 |
commit | a45e14148fb34175cba042df8979e7982758635f (patch) | |
tree | 10add976d1291f4172e95aea60e2c44594b9813d /arch/s390/kernel/ipl.c | |
parent | b3c14d0bfd1739b930f26df90552a4d8cdcca0a6 (diff) |
[S390] Fix reboot hang on LPARs
Reboot hangs on LPARs without diag308 support. The reason for this is,
that before the reboot is done, the channel subsystem is shut down.
During the reset on each possible subchannel a "store subchannel" is
done. This operation can end in a program check interruption, if the
specified subchannel set is not implemented by the hardware. During
the reset, currently we do not have a program check handler, which
leads to the described kernel bug. We install now a new program check
handler for the reboot code to fix this problem.
Signed-off-by: Michael Holzheu <holzheu@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel/ipl.c')
-rw-r--r-- | arch/s390/kernel/ipl.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c index a36bea1188d9..d2e6a0a56ade 100644 --- a/arch/s390/kernel/ipl.c +++ b/arch/s390/kernel/ipl.c | |||
@@ -1037,13 +1037,15 @@ static void do_reset_calls(void) | |||
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | extern void reset_mcck_handler(void); | 1039 | extern void reset_mcck_handler(void); |
1040 | extern void reset_pgm_handler(void); | ||
1040 | 1041 | ||
1041 | void s390_reset_system(void) | 1042 | void s390_reset_system(void) |
1042 | { | 1043 | { |
1043 | struct _lowcore *lc; | 1044 | struct _lowcore *lc; |
1044 | 1045 | ||
1045 | /* Stack for interrupt/machine check handler */ | ||
1046 | lc = (struct _lowcore *)(unsigned long) store_prefix(); | 1046 | lc = (struct _lowcore *)(unsigned long) store_prefix(); |
1047 | |||
1048 | /* Stack for interrupt/machine check handler */ | ||
1047 | lc->panic_stack = S390_lowcore.panic_stack; | 1049 | lc->panic_stack = S390_lowcore.panic_stack; |
1048 | 1050 | ||
1049 | /* Disable prefixing */ | 1051 | /* Disable prefixing */ |
@@ -1056,5 +1058,11 @@ void s390_reset_system(void) | |||
1056 | S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; | 1058 | S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; |
1057 | S390_lowcore.mcck_new_psw.addr = | 1059 | S390_lowcore.mcck_new_psw.addr = |
1058 | PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler; | 1060 | PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler; |
1061 | |||
1062 | /* Set new program check handler */ | ||
1063 | S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; | ||
1064 | S390_lowcore.program_new_psw.addr = | ||
1065 | PSW_ADDR_AMODE | (unsigned long) &reset_pgm_handler; | ||
1066 | |||
1059 | do_reset_calls(); | 1067 | do_reset_calls(); |
1060 | } | 1068 | } |