diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2005-06-25 17:55:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-06-25 19:24:37 -0400 |
commit | 77fa22450de00d535de2cc8be653983560828000 (patch) | |
tree | 61644edb2263c3d0db3ea9e9518c6f76a60039e0 /arch/s390/kernel/process.c | |
parent | f901e5d1e06b3326c100c5d0df43656311befb81 (diff) |
[PATCH] s390: improved machine check handling
Improved machine check handling. Kernel is now able to receive machine checks
while in kernel mode (system call, interrupt and program check handling).
Also register validation is now performed.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/s390/kernel/process.c')
-rw-r--r-- | arch/s390/kernel/process.c | 46 |
1 files changed, 12 insertions, 34 deletions
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 7aea25d6e300..9f3dff6c0b72 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -91,13 +91,12 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code) | |||
91 | (void *)(long) smp_processor_id()); | 91 | (void *)(long) smp_processor_id()); |
92 | } | 92 | } |
93 | 93 | ||
94 | extern void s390_handle_mcck(void); | ||
94 | /* | 95 | /* |
95 | * The idle loop on a S390... | 96 | * The idle loop on a S390... |
96 | */ | 97 | */ |
97 | void default_idle(void) | 98 | void default_idle(void) |
98 | { | 99 | { |
99 | psw_t wait_psw; | ||
100 | unsigned long reg; | ||
101 | int cpu, rc; | 100 | int cpu, rc; |
102 | 101 | ||
103 | local_irq_disable(); | 102 | local_irq_disable(); |
@@ -125,38 +124,17 @@ void default_idle(void) | |||
125 | cpu_die(); | 124 | cpu_die(); |
126 | #endif | 125 | #endif |
127 | 126 | ||
128 | /* | 127 | local_mcck_disable(); |
129 | * Wait for external, I/O or machine check interrupt and | 128 | if (test_thread_flag(TIF_MCCK_PENDING)) { |
130 | * switch off machine check bit after the wait has ended. | 129 | local_mcck_enable(); |
131 | */ | 130 | local_irq_enable(); |
132 | wait_psw.mask = PSW_KERNEL_BITS | PSW_MASK_MCHECK | PSW_MASK_WAIT | | 131 | s390_handle_mcck(); |
133 | PSW_MASK_IO | PSW_MASK_EXT; | 132 | return; |
134 | #ifndef CONFIG_ARCH_S390X | 133 | } |
135 | asm volatile ( | 134 | |
136 | " basr %0,0\n" | 135 | /* Wait for external, I/O or machine check interrupt. */ |
137 | "0: la %0,1f-0b(%0)\n" | 136 | __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT | |
138 | " st %0,4(%1)\n" | 137 | PSW_MASK_IO | PSW_MASK_EXT); |
139 | " oi 4(%1),0x80\n" | ||
140 | " lpsw 0(%1)\n" | ||
141 | "1: la %0,2f-1b(%0)\n" | ||
142 | " st %0,4(%1)\n" | ||
143 | " oi 4(%1),0x80\n" | ||
144 | " ni 1(%1),0xf9\n" | ||
145 | " lpsw 0(%1)\n" | ||
146 | "2:" | ||
147 | : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); | ||
148 | #else /* CONFIG_ARCH_S390X */ | ||
149 | asm volatile ( | ||
150 | " larl %0,0f\n" | ||
151 | " stg %0,8(%1)\n" | ||
152 | " lpswe 0(%1)\n" | ||
153 | "0: larl %0,1f\n" | ||
154 | " stg %0,8(%1)\n" | ||
155 | " ni 1(%1),0xf9\n" | ||
156 | " lpswe 0(%1)\n" | ||
157 | "1:" | ||
158 | : "=&a" (reg) : "a" (&wait_psw) : "memory", "cc" ); | ||
159 | #endif /* CONFIG_ARCH_S390X */ | ||
160 | } | 138 | } |
161 | 139 | ||
162 | void cpu_idle(void) | 140 | void cpu_idle(void) |