aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/s390/Kconfig.debug4
-rw-r--r--arch/s390/kernel/entry.S29
-rw-r--r--arch/s390/kernel/entry64.S21
-rw-r--r--arch/s390/kernel/irq.c2
-rw-r--r--arch/s390/kernel/process.c1
-rw-r--r--drivers/s390/char/sclp.c10
-rw-r--r--drivers/s390/cio/cio.c2
-rw-r--r--include/asm-s390/irqflags.h50
-rw-r--r--include/asm-s390/system.h32
9 files changed, 113 insertions, 38 deletions
diff --git a/arch/s390/Kconfig.debug b/arch/s390/Kconfig.debug
index f53b6d5300e5..2283933a9a93 100644
--- a/arch/s390/Kconfig.debug
+++ b/arch/s390/Kconfig.debug
@@ -1,5 +1,9 @@
1menu "Kernel hacking" 1menu "Kernel hacking"
2 2
3config TRACE_IRQFLAGS_SUPPORT
4 bool
5 default y
6
3source "lib/Kconfig.debug" 7source "lib/Kconfig.debug"
4 8
5endmenu 9endmenu
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index d8948c342caf..5b5799ac8f83 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -58,6 +58,21 @@ STACK_SIZE = 1 << STACK_SHIFT
58 58
59#define BASED(name) name-system_call(%r13) 59#define BASED(name) name-system_call(%r13)
60 60
61#ifdef CONFIG_TRACE_IRQFLAGS
62 .macro TRACE_IRQS_ON
63 l %r1,BASED(.Ltrace_irq_on)
64 basr %r14,%r1
65 .endm
66
67 .macro TRACE_IRQS_OFF
68 l %r1,BASED(.Ltrace_irq_off)
69 basr %r14,%r1
70 .endm
71#else
72#define TRACE_IRQS_ON
73#define TRACE_IRQS_OFF
74#endif
75
61/* 76/*
62 * Register usage in interrupt handlers: 77 * Register usage in interrupt handlers:
63 * R9 - pointer to current task structure 78 * R9 - pointer to current task structure
@@ -361,6 +376,7 @@ ret_from_fork:
361 st %r15,SP_R15(%r15) # store stack pointer for new kthread 376 st %r15,SP_R15(%r15) # store stack pointer for new kthread
3620: l %r1,BASED(.Lschedtail) 3770: l %r1,BASED(.Lschedtail)
363 basr %r14,%r1 378 basr %r14,%r1
379 TRACE_IRQS_ON
364 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 380 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
365 b BASED(sysc_return) 381 b BASED(sysc_return)
366 382
@@ -516,6 +532,7 @@ pgm_no_vtime3:
516 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS 532 mvc __THREAD_per+__PER_address(4,%r1),__LC_PER_ADDRESS
517 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 533 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
518 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 534 oi __TI_flags+3(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
535 TRACE_IRQS_ON
519 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 536 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
520 b BASED(sysc_do_svc) 537 b BASED(sysc_do_svc)
521 538
@@ -539,9 +556,11 @@ io_int_handler:
539io_no_vtime: 556io_no_vtime:
540#endif 557#endif
541 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 558 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
559 TRACE_IRQS_OFF
542 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 560 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
543 la %r2,SP_PTREGS(%r15) # address of register-save area 561 la %r2,SP_PTREGS(%r15) # address of register-save area
544 basr %r14,%r1 # branch to standard irq handler 562 basr %r14,%r1 # branch to standard irq handler
563 TRACE_IRQS_ON
545 564
546io_return: 565io_return:
547 tm SP_PSW+1(%r15),0x01 # returning to user ? 566 tm SP_PSW+1(%r15),0x01 # returning to user ?
@@ -651,10 +670,12 @@ ext_int_handler:
651ext_no_vtime: 670ext_no_vtime:
652#endif 671#endif
653 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct 672 l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
673 TRACE_IRQS_OFF
654 la %r2,SP_PTREGS(%r15) # address of register-save area 674 la %r2,SP_PTREGS(%r15) # address of register-save area
655 lh %r3,__LC_EXT_INT_CODE # get interruption code 675 lh %r3,__LC_EXT_INT_CODE # get interruption code
656 l %r1,BASED(.Ldo_extint) 676 l %r1,BASED(.Ldo_extint)
657 basr %r14,%r1 677 basr %r14,%r1
678 TRACE_IRQS_ON
658 b BASED(io_return) 679 b BASED(io_return)
659 680
660__critical_end: 681__critical_end:
@@ -731,8 +752,10 @@ mcck_no_vtime:
731 stosm __SF_EMPTY(%r15),0x04 # turn dat on 752 stosm __SF_EMPTY(%r15),0x04 # turn dat on
732 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING 753 tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
733 bno BASED(mcck_return) 754 bno BASED(mcck_return)
755 TRACE_IRQS_OFF
734 l %r1,BASED(.Ls390_handle_mcck) 756 l %r1,BASED(.Ls390_handle_mcck)
735 basr %r14,%r1 # call machine check handler 757 basr %r14,%r1 # call machine check handler
758 TRACE_IRQS_ON
736mcck_return: 759mcck_return:
737 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW 760 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW
738 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 761 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
@@ -1012,7 +1035,11 @@ cleanup_io_leave_insn:
1012.Lvfork: .long sys_vfork 1035.Lvfork: .long sys_vfork
1013.Lschedtail: .long schedule_tail 1036.Lschedtail: .long schedule_tail
1014.Lsysc_table: .long sys_call_table 1037.Lsysc_table: .long sys_call_table
1015 1038#ifdef CONFIG_TRACE_IRQFLAGS
1039.Ltrace_irq_on:.long trace_hardirqs_on
1040.Ltrace_irq_off:
1041 .long trace_hardirqs_off
1042#endif
1016.Lcritical_start: 1043.Lcritical_start:
1017 .long __critical_start + 0x80000000 1044 .long __critical_start + 0x80000000
1018.Lcritical_end: 1045.Lcritical_end:
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 1ca499fa54b4..56f5f613b868 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -58,6 +58,19 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
58 58
59#define BASED(name) name-system_call(%r13) 59#define BASED(name) name-system_call(%r13)
60 60
61#ifdef CONFIG_TRACE_IRQFLAGS
62 .macro TRACE_IRQS_ON
63 brasl %r14,trace_hardirqs_on
64 .endm
65
66 .macro TRACE_IRQS_OFF
67 brasl %r14,trace_hardirqs_off
68 .endm
69#else
70#define TRACE_IRQS_ON
71#define TRACE_IRQS_OFF
72#endif
73
61 .macro STORE_TIMER lc_offset 74 .macro STORE_TIMER lc_offset
62#ifdef CONFIG_VIRT_CPU_ACCOUNTING 75#ifdef CONFIG_VIRT_CPU_ACCOUNTING
63 stpt \lc_offset 76 stpt \lc_offset
@@ -354,6 +367,7 @@ ret_from_fork:
354 jo 0f 367 jo 0f
355 stg %r15,SP_R15(%r15) # store stack pointer for new kthread 368 stg %r15,SP_R15(%r15) # store stack pointer for new kthread
3560: brasl %r14,schedule_tail 3690: brasl %r14,schedule_tail
370 TRACE_IRQS_ON
357 stosm 24(%r15),0x03 # reenable interrupts 371 stosm 24(%r15),0x03 # reenable interrupts
358 j sysc_return 372 j sysc_return
359 373
@@ -535,6 +549,7 @@ pgm_no_vtime3:
535 mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS 549 mvc __THREAD_per+__PER_address(8,%r1),__LC_PER_ADDRESS
536 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID 550 mvc __THREAD_per+__PER_access_id(1,%r1),__LC_PER_ACCESS_ID
537 oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP 551 oi __TI_flags+7(%r9),_TIF_SINGLE_STEP # set TIF_SINGLE_STEP
552 TRACE_IRQS_ON
538 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 553 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
539 j sysc_do_svc 554 j sysc_do_svc
540 555
@@ -557,8 +572,10 @@ io_int_handler:
557io_no_vtime: 572io_no_vtime:
558#endif 573#endif
559 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 574 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
575 TRACE_IRQS_OFF
560 la %r2,SP_PTREGS(%r15) # address of register-save area 576 la %r2,SP_PTREGS(%r15) # address of register-save area
561 brasl %r14,do_IRQ # call standard irq handler 577 brasl %r14,do_IRQ # call standard irq handler
578 TRACE_IRQS_ON
562 579
563io_return: 580io_return:
564 tm SP_PSW+1(%r15),0x01 # returning to user ? 581 tm SP_PSW+1(%r15),0x01 # returning to user ?
@@ -665,9 +682,11 @@ ext_int_handler:
665ext_no_vtime: 682ext_no_vtime:
666#endif 683#endif
667 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct 684 lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
685 TRACE_IRQS_OFF
668 la %r2,SP_PTREGS(%r15) # address of register-save area 686 la %r2,SP_PTREGS(%r15) # address of register-save area
669 llgh %r3,__LC_EXT_INT_CODE # get interruption code 687 llgh %r3,__LC_EXT_INT_CODE # get interruption code
670 brasl %r14,do_extint 688 brasl %r14,do_extint
689 TRACE_IRQS_ON
671 j io_return 690 j io_return
672 691
673__critical_end: 692__critical_end:
@@ -743,7 +762,9 @@ mcck_no_vtime:
743 stosm __SF_EMPTY(%r15),0x04 # turn dat on 762 stosm __SF_EMPTY(%r15),0x04 # turn dat on
744 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING 763 tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
745 jno mcck_return 764 jno mcck_return
765 TRACE_IRQS_OFF
746 brasl %r14,s390_handle_mcck 766 brasl %r14,s390_handle_mcck
767 TRACE_IRQS_ON
747mcck_return: 768mcck_return:
748 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW 769 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW
749 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 770 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 480b6a5fef3a..e347190d9aea 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -97,7 +97,7 @@ asmlinkage void do_softirq(void)
97 97
98 account_system_vtime(current); 98 account_system_vtime(current);
99 99
100 __local_bh_enable(); 100 _local_bh_enable();
101 101
102 local_irq_restore(flags); 102 local_irq_restore(flags);
103} 103}
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 1f9399191794..78c8e5548caf 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -142,6 +142,7 @@ static void default_idle(void)
142 return; 142 return;
143 } 143 }
144 144
145 trace_hardirqs_on();
145 /* Wait for external, I/O or machine check interrupt. */ 146 /* Wait for external, I/O or machine check interrupt. */
146 __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT | 147 __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT |
147 PSW_MASK_IO | PSW_MASK_EXT); 148 PSW_MASK_IO | PSW_MASK_EXT);
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 4138564402b8..985d1613baaa 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -383,6 +383,7 @@ void
383sclp_sync_wait(void) 383sclp_sync_wait(void)
384{ 384{
385 unsigned long psw_mask; 385 unsigned long psw_mask;
386 unsigned long flags;
386 unsigned long cr0, cr0_sync; 387 unsigned long cr0, cr0_sync;
387 u64 timeout; 388 u64 timeout;
388 389
@@ -395,9 +396,11 @@ sclp_sync_wait(void)
395 sclp_tod_from_jiffies(sclp_request_timer.expires - 396 sclp_tod_from_jiffies(sclp_request_timer.expires -
396 jiffies); 397 jiffies);
397 } 398 }
399 local_irq_save(flags);
398 /* Prevent bottom half from executing once we force interrupts open */ 400 /* Prevent bottom half from executing once we force interrupts open */
399 local_bh_disable(); 401 local_bh_disable();
400 /* Enable service-signal interruption, disable timer interrupts */ 402 /* Enable service-signal interruption, disable timer interrupts */
403 trace_hardirqs_on();
401 __ctl_store(cr0, 0, 0); 404 __ctl_store(cr0, 0, 0);
402 cr0_sync = cr0; 405 cr0_sync = cr0;
403 cr0_sync |= 0x00000200; 406 cr0_sync |= 0x00000200;
@@ -415,11 +418,10 @@ sclp_sync_wait(void)
415 barrier(); 418 barrier();
416 cpu_relax(); 419 cpu_relax();
417 } 420 }
418 /* Restore interrupt settings */ 421 local_irq_disable();
419 asm volatile ("SSM 0(%0)"
420 : : "a" (&psw_mask) : "memory");
421 __ctl_load(cr0, 0, 0); 422 __ctl_load(cr0, 0, 0);
422 __local_bh_enable(); 423 _local_bh_enable();
424 local_irq_restore(flags);
423} 425}
424 426
425EXPORT_SYMBOL(sclp_sync_wait); 427EXPORT_SYMBOL(sclp_sync_wait);
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index a3423267467f..6fec90eab00e 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -147,7 +147,7 @@ cio_tpi(void)
147 sch->driver->irq(&sch->dev); 147 sch->driver->irq(&sch->dev);
148 spin_unlock(&sch->lock); 148 spin_unlock(&sch->lock);
149 irq_exit (); 149 irq_exit ();
150 __local_bh_enable(); 150 _local_bh_enable();
151 return 1; 151 return 1;
152} 152}
153 153
diff --git a/include/asm-s390/irqflags.h b/include/asm-s390/irqflags.h
new file mode 100644
index 000000000000..65f4db627e7a
--- /dev/null
+++ b/include/asm-s390/irqflags.h
@@ -0,0 +1,50 @@
1/*
2 * include/asm-s390/irqflags.h
3 *
4 * Copyright (C) IBM Corp. 2006
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 */
7
8#ifndef __ASM_IRQFLAGS_H
9#define __ASM_IRQFLAGS_H
10
11#ifdef __KERNEL__
12
13/* interrupt control.. */
14#define raw_local_irq_enable() ({ \
15 unsigned long __dummy; \
16 __asm__ __volatile__ ( \
17 "stosm 0(%1),0x03" \
18 : "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
19 })
20
21#define raw_local_irq_disable() ({ \
22 unsigned long __flags; \
23 __asm__ __volatile__ ( \
24 "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
25 __flags; \
26 })
27
28#define raw_local_save_flags(x) \
29 __asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) )
30
31#define raw_local_irq_restore(x) \
32 __asm__ __volatile__("ssm 0(%0)" : : "a" (&x), "m" (x) : "memory")
33
34#define raw_irqs_disabled() \
35({ \
36 unsigned long flags; \
37 local_save_flags(flags); \
38 !((flags >> __FLAG_SHIFT) & 3); \
39})
40
41static inline int raw_irqs_disabled_flags(unsigned long flags)
42{
43 return !((flags >> __FLAG_SHIFT) & 3);
44}
45
46/* For spinlocks etc */
47#define raw_local_irq_save(x) ((x) = raw_local_irq_disable())
48
49#endif /* __KERNEL__ */
50#endif /* __ASM_IRQFLAGS_H */
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index 71a0732cd518..9ab186ffde23 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -301,34 +301,6 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
301#define set_mb(var, value) do { var = value; mb(); } while (0) 301#define set_mb(var, value) do { var = value; mb(); } while (0)
302#define set_wmb(var, value) do { var = value; wmb(); } while (0) 302#define set_wmb(var, value) do { var = value; wmb(); } while (0)
303 303
304/* interrupt control.. */
305#define local_irq_enable() ({ \
306 unsigned long __dummy; \
307 __asm__ __volatile__ ( \
308 "stosm 0(%1),0x03" \
309 : "=m" (__dummy) : "a" (&__dummy) : "memory" ); \
310 })
311
312#define local_irq_disable() ({ \
313 unsigned long __flags; \
314 __asm__ __volatile__ ( \
315 "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \
316 __flags; \
317 })
318
319#define local_save_flags(x) \
320 __asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) )
321
322#define local_irq_restore(x) \
323 __asm__ __volatile__("ssm 0(%0)" : : "a" (&x), "m" (x) : "memory")
324
325#define irqs_disabled() \
326({ \
327 unsigned long flags; \
328 local_save_flags(flags); \
329 !((flags >> __FLAG_SHIFT) & 3); \
330})
331
332#ifdef __s390x__ 304#ifdef __s390x__
333 305
334#define __ctl_load(array, low, high) ({ \ 306#define __ctl_load(array, low, high) ({ \
@@ -442,8 +414,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
442 }) 414 })
443#endif /* __s390x__ */ 415#endif /* __s390x__ */
444 416
445/* For spinlocks etc */ 417#include <linux/irqflags.h>
446#define local_irq_save(x) ((x) = local_irq_disable())
447 418
448/* 419/*
449 * Use to set psw mask except for the first byte which 420 * Use to set psw mask except for the first byte which
@@ -482,4 +453,3 @@ extern void (*_machine_power_off)(void);
482#endif /* __KERNEL__ */ 453#endif /* __KERNEL__ */
483 454
484#endif 455#endif
485