aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-s390
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2005-06-25 17:55:30 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-25 19:24:37 -0400
commit77fa22450de00d535de2cc8be653983560828000 (patch)
tree61644edb2263c3d0db3ea9e9518c6f76a60039e0 /include/asm-s390
parentf901e5d1e06b3326c100c5d0df43656311befb81 (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 'include/asm-s390')
-rw-r--r--include/asm-s390/lowcore.h7
-rw-r--r--include/asm-s390/processor.h52
-rw-r--r--include/asm-s390/ptrace.h2
-rw-r--r--include/asm-s390/system.h21
-rw-r--r--include/asm-s390/thread_info.h2
5 files changed, 44 insertions, 40 deletions
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index df5172fc589d..76b5b19c0ae2 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -109,10 +109,14 @@
109 109
110#ifndef __s390x__ 110#ifndef __s390x__
111#define __LC_PFAULT_INTPARM 0x080 111#define __LC_PFAULT_INTPARM 0x080
112#define __LC_CPU_TIMER_SAVE_AREA 0x0D8
112#define __LC_AREGS_SAVE_AREA 0x120 113#define __LC_AREGS_SAVE_AREA 0x120
114#define __LC_GPREGS_SAVE_AREA 0x180
113#define __LC_CREGS_SAVE_AREA 0x1C0 115#define __LC_CREGS_SAVE_AREA 0x1C0
114#else /* __s390x__ */ 116#else /* __s390x__ */
115#define __LC_PFAULT_INTPARM 0x11B8 117#define __LC_PFAULT_INTPARM 0x11B8
118#define __LC_GPREGS_SAVE_AREA 0x1280
119#define __LC_CPU_TIMER_SAVE_AREA 0x1328
116#define __LC_AREGS_SAVE_AREA 0x1340 120#define __LC_AREGS_SAVE_AREA 0x1340
117#define __LC_CREGS_SAVE_AREA 0x1380 121#define __LC_CREGS_SAVE_AREA 0x1380
118#endif /* __s390x__ */ 122#endif /* __s390x__ */
@@ -167,7 +171,8 @@ struct _lowcore
167 __u16 subchannel_nr; /* 0x0ba */ 171 __u16 subchannel_nr; /* 0x0ba */
168 __u32 io_int_parm; /* 0x0bc */ 172 __u32 io_int_parm; /* 0x0bc */
169 __u32 io_int_word; /* 0x0c0 */ 173 __u32 io_int_word; /* 0x0c0 */
170 __u8 pad3[0xD8-0xC4]; /* 0x0c4 */ 174 __u8 pad3[0xD4-0xC4]; /* 0x0c4 */
175 __u32 extended_save_area_addr; /* 0x0d4 */
171 __u32 cpu_timer_save_area[2]; /* 0x0d8 */ 176 __u32 cpu_timer_save_area[2]; /* 0x0d8 */
172 __u32 clock_comp_save_area[2]; /* 0x0e0 */ 177 __u32 clock_comp_save_area[2]; /* 0x0e0 */
173 __u32 mcck_interruption_code[2]; /* 0x0e8 */ 178 __u32 mcck_interruption_code[2]; /* 0x0e8 */
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h
index fb46e9090b50..8bd14de69e35 100644
--- a/include/asm-s390/processor.h
+++ b/include/asm-s390/processor.h
@@ -207,6 +207,18 @@ unsigned long get_wchan(struct task_struct *p);
207#endif /* __s390x__ */ 207#endif /* __s390x__ */
208 208
209/* 209/*
210 * Set PSW to specified value.
211 */
212static inline void __load_psw(psw_t psw)
213{
214#ifndef __s390x__
215 asm volatile ("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
216#else
217 asm volatile ("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
218#endif
219}
220
221/*
210 * Set PSW mask to specified value, while leaving the 222 * Set PSW mask to specified value, while leaving the
211 * PSW addr pointing to the next instruction. 223 * PSW addr pointing to the next instruction.
212 */ 224 */
@@ -214,8 +226,8 @@ unsigned long get_wchan(struct task_struct *p);
214static inline void __load_psw_mask (unsigned long mask) 226static inline void __load_psw_mask (unsigned long mask)
215{ 227{
216 unsigned long addr; 228 unsigned long addr;
217
218 psw_t psw; 229 psw_t psw;
230
219 psw.mask = mask; 231 psw.mask = mask;
220 232
221#ifndef __s390x__ 233#ifndef __s390x__
@@ -241,30 +253,8 @@ static inline void __load_psw_mask (unsigned long mask)
241 */ 253 */
242static inline void enabled_wait(void) 254static inline void enabled_wait(void)
243{ 255{
244 unsigned long reg; 256 __load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
245 psw_t wait_psw; 257 PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY);
246
247 wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT |
248 PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY;
249#ifndef __s390x__
250 asm volatile (
251 " basr %0,0\n"
252 "0: la %0,1f-0b(%0)\n"
253 " st %0,4(%1)\n"
254 " oi 4(%1),0x80\n"
255 " lpsw 0(%1)\n"
256 "1:"
257 : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw)
258 : "memory", "cc" );
259#else /* __s390x__ */
260 asm volatile (
261 " larl %0,0f\n"
262 " stg %0,8(%1)\n"
263 " lpswe 0(%1)\n"
264 "0:"
265 : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw)
266 : "memory", "cc" );
267#endif /* __s390x__ */
268} 258}
269 259
270/* 260/*
@@ -273,13 +263,11 @@ static inline void enabled_wait(void)
273 263
274static inline void disabled_wait(unsigned long code) 264static inline void disabled_wait(unsigned long code)
275{ 265{
276 char psw_buffer[2*sizeof(psw_t)];
277 unsigned long ctl_buf; 266 unsigned long ctl_buf;
278 psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1) 267 psw_t dw_psw;
279 & -sizeof(psw_t));
280 268
281 dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT; 269 dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
282 dw_psw->addr = code; 270 dw_psw.addr = code;
283 /* 271 /*
284 * Store status and then load disabled wait psw, 272 * Store status and then load disabled wait psw,
285 * the processor is dead afterwards 273 * the processor is dead afterwards
@@ -301,7 +289,7 @@ static inline void disabled_wait(unsigned long code)
301 " oi 0x1c0,0x10\n" /* fake protection bit */ 289 " oi 0x1c0,0x10\n" /* fake protection bit */
302 " lpsw 0(%1)" 290 " lpsw 0(%1)"
303 : "=m" (ctl_buf) 291 : "=m" (ctl_buf)
304 : "a" (dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); 292 : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" );
305#else /* __s390x__ */ 293#else /* __s390x__ */
306 asm volatile (" stctg 0,0,0(%2)\n" 294 asm volatile (" stctg 0,0,0(%2)\n"
307 " ni 4(%2),0xef\n" /* switch off protection */ 295 " ni 4(%2),0xef\n" /* switch off protection */
@@ -333,7 +321,7 @@ static inline void disabled_wait(unsigned long code)
333 " oi 0x384(1),0x10\n" /* fake protection bit */ 321 " oi 0x384(1),0x10\n" /* fake protection bit */
334 " lpswe 0(%1)" 322 " lpswe 0(%1)"
335 : "=m" (ctl_buf) 323 : "=m" (ctl_buf)
336 : "a" (dw_psw), "a" (&ctl_buf), 324 : "a" (&dw_psw), "a" (&ctl_buf),
337 "m" (dw_psw) : "cc", "0", "1"); 325 "m" (dw_psw) : "cc", "0", "1");
338#endif /* __s390x__ */ 326#endif /* __s390x__ */
339} 327}
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h
index 4eff8f2e3bf1..fc7c96edc697 100644
--- a/include/asm-s390/ptrace.h
+++ b/include/asm-s390/ptrace.h
@@ -276,7 +276,7 @@ typedef struct
276#endif /* __s390x__ */ 276#endif /* __s390x__ */
277 277
278#define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \ 278#define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY | \
279 PSW_DEFAULT_KEY) 279 PSW_MASK_MCHECK | PSW_DEFAULT_KEY)
280#define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ 280#define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \
281 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ 281 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \
282 PSW_MASK_PSTATE | PSW_DEFAULT_KEY) 282 PSW_MASK_PSTATE | PSW_DEFAULT_KEY)
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index 81514d76edcf..e3cb3ce1d24a 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -16,6 +16,7 @@
16#include <asm/types.h> 16#include <asm/types.h>
17#include <asm/ptrace.h> 17#include <asm/ptrace.h>
18#include <asm/setup.h> 18#include <asm/setup.h>
19#include <asm/processor.h>
19 20
20#ifdef __KERNEL__ 21#ifdef __KERNEL__
21 22
@@ -331,9 +332,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
331 332
332#ifdef __s390x__ 333#ifdef __s390x__
333 334
334#define __load_psw(psw) \
335 __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" );
336
337#define __ctl_load(array, low, high) ({ \ 335#define __ctl_load(array, low, high) ({ \
338 typedef struct { char _[sizeof(array)]; } addrtype; \ 336 typedef struct { char _[sizeof(array)]; } addrtype; \
339 __asm__ __volatile__ ( \ 337 __asm__ __volatile__ ( \
@@ -390,9 +388,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
390 388
391#else /* __s390x__ */ 389#else /* __s390x__ */
392 390
393#define __load_psw(psw) \
394 __asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" );
395
396#define __ctl_load(array, low, high) ({ \ 391#define __ctl_load(array, low, high) ({ \
397 typedef struct { char _[sizeof(array)]; } addrtype; \ 392 typedef struct { char _[sizeof(array)]; } addrtype; \
398 __asm__ __volatile__ ( \ 393 __asm__ __volatile__ ( \
@@ -451,6 +446,20 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
451/* For spinlocks etc */ 446/* For spinlocks etc */
452#define local_irq_save(x) ((x) = local_irq_disable()) 447#define local_irq_save(x) ((x) = local_irq_disable())
453 448
449/*
450 * Use to set psw mask except for the first byte which
451 * won't be changed by this function.
452 */
453static inline void
454__set_psw_mask(unsigned long mask)
455{
456 local_save_flags(mask);
457 __load_psw_mask(mask);
458}
459
460#define local_mcck_enable() __set_psw_mask(PSW_KERNEL_BITS)
461#define local_mcck_disable() __set_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK)
462
454#ifdef CONFIG_SMP 463#ifdef CONFIG_SMP
455 464
456extern void smp_ctl_set_bit(int cr, int bit); 465extern void smp_ctl_set_bit(int cr, int bit);
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h
index fe101d41e849..6c18a3f24316 100644
--- a/include/asm-s390/thread_info.h
+++ b/include/asm-s390/thread_info.h
@@ -96,6 +96,7 @@ static inline struct thread_info *current_thread_info(void)
96#define TIF_RESTART_SVC 4 /* restart svc with new svc number */ 96#define TIF_RESTART_SVC 4 /* restart svc with new svc number */
97#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ 97#define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */
98#define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */ 98#define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */
99#define TIF_MCCK_PENDING 7 /* machine check handling is pending */
99#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ 100#define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */
100#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling 101#define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling
101 TIF_NEED_RESCHED */ 102 TIF_NEED_RESCHED */
@@ -109,6 +110,7 @@ static inline struct thread_info *current_thread_info(void)
109#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) 110#define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC)
110#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) 111#define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT)
111#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) 112#define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP)
113#define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING)
112#define _TIF_USEDFPU (1<<TIF_USEDFPU) 114#define _TIF_USEDFPU (1<<TIF_USEDFPU)
113#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) 115#define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG)
114#define _TIF_31BIT (1<<TIF_31BIT) 116#define _TIF_31BIT (1<<TIF_31BIT)