aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2009-07-24 06:39:50 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-07-24 06:41:00 -0400
commitc63b196afcf22405527abe4c2c57926a5bbd6fc9 (patch)
tree6c8f0705fe19e1fcb3678c9e2bd46a915cde5f65 /arch
parent5f954c3426190f7ae432a09abd62164d5d14c709 (diff)
[S390] hibernation: fix register corruption on machine checks
swsusp_arch_suspend() actually saves all cpu register contents on hibernation. Machine checks must be disabled since swsusp_arch_suspend() stores register contents to their lowcore save areas. That's the same place where register contents on machine checks would be saved. To avoid register corruption disable machine checks. We must also disable machine checks in the new psw mask for program checks, since swsusp_arch_suspend() may generate program checks. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/s390/power/swsusp.c36
-rw-r--r--arch/s390/power/swsusp_asm64.S22
2 files changed, 25 insertions, 33 deletions
diff --git a/arch/s390/power/swsusp.c b/arch/s390/power/swsusp.c
index e6a4fe9f5f24..bd1f5c6b0b8c 100644
--- a/arch/s390/power/swsusp.c
+++ b/arch/s390/power/swsusp.c
@@ -7,24 +7,36 @@
7 * 7 *
8 */ 8 */
9 9
10#include <asm/system.h>
10 11
11/*
12 * save CPU registers before creating a hibernation image and before
13 * restoring the memory state from it
14 */
15void save_processor_state(void) 12void save_processor_state(void)
16{ 13{
17 /* implentation contained in the 14 /* swsusp_arch_suspend() actually saves all cpu register contents.
18 * swsusp_arch_suspend function 15 * Machine checks must be disabled since swsusp_arch_suspend() stores
16 * register contents to their lowcore save areas. That's the same
17 * place where register contents on machine checks would be saved.
18 * To avoid register corruption disable machine checks.
19 * We must also disable machine checks in the new psw mask for
20 * program checks, since swsusp_arch_suspend() may generate program
21 * checks. Disabling machine checks for all other new psw masks is
22 * just paranoia.
19 */ 23 */
24 local_mcck_disable();
25 /* Disable lowcore protection */
26 __ctl_clear_bit(0,28);
27 S390_lowcore.external_new_psw.mask &= ~PSW_MASK_MCHECK;
28 S390_lowcore.svc_new_psw.mask &= ~PSW_MASK_MCHECK;
29 S390_lowcore.io_new_psw.mask &= ~PSW_MASK_MCHECK;
30 S390_lowcore.program_new_psw.mask &= ~PSW_MASK_MCHECK;
20} 31}
21 32
22/*
23 * restore the contents of CPU registers
24 */
25void restore_processor_state(void) 33void restore_processor_state(void)
26{ 34{
27 /* implentation contained in the 35 S390_lowcore.external_new_psw.mask |= PSW_MASK_MCHECK;
28 * swsusp_arch_resume function 36 S390_lowcore.svc_new_psw.mask |= PSW_MASK_MCHECK;
29 */ 37 S390_lowcore.io_new_psw.mask |= PSW_MASK_MCHECK;
38 S390_lowcore.program_new_psw.mask |= PSW_MASK_MCHECK;
39 /* Enable lowcore protection */
40 __ctl_set_bit(0,28);
41 local_mcck_enable();
30} 42}
diff --git a/arch/s390/power/swsusp_asm64.S b/arch/s390/power/swsusp_asm64.S
index e27bd3164897..b26df5c5933e 100644
--- a/arch/s390/power/swsusp_asm64.S
+++ b/arch/s390/power/swsusp_asm64.S
@@ -32,11 +32,6 @@ swsusp_arch_suspend:
32 /* Deactivate DAT */ 32 /* Deactivate DAT */
33 stnsm __SF_EMPTY(%r15),0xfb 33 stnsm __SF_EMPTY(%r15),0xfb
34 34
35 /* Switch off lowcore protection */
36 stctg %c0,%c0,__SF_EMPTY(%r15)
37 ni __SF_EMPTY+4(%r15),0xef
38 lctlg %c0,%c0,__SF_EMPTY(%r15)
39
40 /* Store prefix register on stack */ 35 /* Store prefix register on stack */
41 stpx __SF_EMPTY(%r15) 36 stpx __SF_EMPTY(%r15)
42 37
@@ -88,11 +83,6 @@ swsusp_arch_suspend:
88 /* Save image */ 83 /* Save image */
89 brasl %r14,swsusp_save 84 brasl %r14,swsusp_save
90 85
91 /* Switch on lowcore protection */
92 stctg %c0,%c0,__SF_EMPTY(%r15)
93 oi __SF_EMPTY+4(%r15),0x10
94 lctlg %c0,%c0,__SF_EMPTY(%r15)
95
96 /* Restore prefix register and return */ 86 /* Restore prefix register and return */
97 lghi %r1,0x1000 87 lghi %r1,0x1000
98 spx 0x318(%r1) 88 spx 0x318(%r1)
@@ -120,11 +110,6 @@ swsusp_arch_resume:
120 /* Deactivate DAT */ 110 /* Deactivate DAT */
121 stnsm __SF_EMPTY(%r15),0xfb 111 stnsm __SF_EMPTY(%r15),0xfb
122 112
123 /* Switch off lowcore protection */
124 stctg %c0,%c0,__SF_EMPTY(%r15)
125 ni __SF_EMPTY+4(%r15),0xef
126 lctlg %c0,%c0,__SF_EMPTY(%r15)
127
128 /* Set prefix page to zero */ 113 /* Set prefix page to zero */
129 xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15) 114 xc __SF_EMPTY(4,%r15),__SF_EMPTY(%r15)
130 spx __SF_EMPTY(%r15) 115 spx __SF_EMPTY(%r15)
@@ -178,7 +163,7 @@ swsusp_arch_resume:
178 /* Load old stack */ 163 /* Load old stack */
179 lg %r15,0x2f8(%r13) 164 lg %r15,0x2f8(%r13)
180 165
181 /* Pointer to save arae */ 166 /* Pointer to save area */
182 lghi %r13,0x1000 167 lghi %r13,0x1000
183 168
184#ifdef CONFIG_SMP 169#ifdef CONFIG_SMP
@@ -190,11 +175,6 @@ swsusp_arch_resume:
190 /* Restore prefix register */ 175 /* Restore prefix register */
191 spx 0x318(%r13) 176 spx 0x318(%r13)
192 177
193 /* Switch on lowcore protection */
194 stctg %c0,%c0,__SF_EMPTY(%r15)
195 oi __SF_EMPTY+4(%r15),0x10
196 lctlg %c0,%c0,__SF_EMPTY(%r15)
197
198 /* Activate DAT */ 178 /* Activate DAT */
199 stosm __SF_EMPTY(%r15),0x04 179 stosm __SF_EMPTY(%r15),0x04
200 180