aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-08-23 08:45:58 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-08-28 03:19:23 -0400
commit0587d409ec53312f735d2004d5f47f8effee1ea9 (patch)
tree7ab956aaf3d7d238f8bd40a8f50d60302cb3363a /arch/s390
parent6b169ac9b4342ff3a1499bdeb7596aa4f1bc401b (diff)
s390/time: return with irqs disabled from psw_idle
Modify the psw_idle waiting logic in entry[64].S to return with interrupts disabled. This avoids potential issues with udelay and interrupt loops as interrupts are not reenabled after clock comparator interrupts. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kernel/entry.S4
-rw-r--r--arch/s390/kernel/entry64.S2
-rw-r--r--arch/s390/kernel/process.c1
-rw-r--r--arch/s390/kernel/time.c1
-rw-r--r--arch/s390/lib/delay.c2
5 files changed, 4 insertions, 6 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 5ca70b4b72cb..cc30d1fb000c 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -886,13 +886,13 @@ cleanup_idle:
886 stm %r9,%r10,__LC_SYSTEM_TIMER 886 stm %r9,%r10,__LC_SYSTEM_TIMER
887 mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) 887 mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
888 # prepare return psw 888 # prepare return psw
889 n %r8,BASED(cleanup_idle_wait) # clear wait state bit 889 n %r8,BASED(cleanup_idle_wait) # clear irq & wait state bits
890 l %r9,24(%r11) # return from psw_idle 890 l %r9,24(%r11) # return from psw_idle
891 br %r14 891 br %r14
892cleanup_idle_insn: 892cleanup_idle_insn:
893 .long psw_idle_lpsw + 0x80000000 893 .long psw_idle_lpsw + 0x80000000
894cleanup_idle_wait: 894cleanup_idle_wait:
895 .long 0xfffdffff 895 .long 0xfcfdffff
896 896
897/* 897/*
898 * Integer constants 898 * Integer constants
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 980c7aa1cc5c..2b2188b97c6a 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -929,7 +929,7 @@ cleanup_idle:
929 stg %r9,__LC_SYSTEM_TIMER 929 stg %r9,__LC_SYSTEM_TIMER
930 mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) 930 mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
931 # prepare return psw 931 # prepare return psw
932 nihh %r8,0xfffd # clear wait state bit 932 nihh %r8,0xfcfd # clear irq & wait state bits
933 lg %r9,48(%r11) # return from psw_idle 933 lg %r9,48(%r11) # return from psw_idle
934 br %r14 934 br %r14
935cleanup_idle_insn: 935cleanup_idle_insn:
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 2bc3eddae34a..c5dbb335716d 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -71,6 +71,7 @@ void arch_cpu_idle(void)
71 } 71 }
72 /* Halt the cpu and keep track of cpu time accounting. */ 72 /* Halt the cpu and keep track of cpu time accounting. */
73 vtime_stop_cpu(); 73 vtime_stop_cpu();
74 local_irq_enable();
74} 75}
75 76
76void arch_cpu_idle_exit(void) 77void arch_cpu_idle_exit(void)
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 876546b9cfa1..064c3082ab33 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -92,7 +92,6 @@ void clock_comparator_work(void)
92 struct clock_event_device *cd; 92 struct clock_event_device *cd;
93 93
94 S390_lowcore.clock_comparator = -1ULL; 94 S390_lowcore.clock_comparator = -1ULL;
95 set_clock_comparator(S390_lowcore.clock_comparator);
96 cd = &__get_cpu_var(comparators); 95 cd = &__get_cpu_var(comparators);
97 cd->event_handler(cd); 96 cd->event_handler(cd);
98} 97}
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c
index c61b9fad43cc..57c87d7d7ede 100644
--- a/arch/s390/lib/delay.c
+++ b/arch/s390/lib/delay.c
@@ -44,7 +44,6 @@ static void __udelay_disabled(unsigned long long usecs)
44 do { 44 do {
45 set_clock_comparator(end); 45 set_clock_comparator(end);
46 vtime_stop_cpu(); 46 vtime_stop_cpu();
47 local_irq_disable();
48 } while (get_tod_clock() < end); 47 } while (get_tod_clock() < end);
49 lockdep_on(); 48 lockdep_on();
50 __ctl_load(cr0, 0, 0); 49 __ctl_load(cr0, 0, 0);
@@ -64,7 +63,6 @@ static void __udelay_enabled(unsigned long long usecs)
64 set_clock_comparator(end); 63 set_clock_comparator(end);
65 } 64 }
66 vtime_stop_cpu(); 65 vtime_stop_cpu();
67 local_irq_disable();
68 if (clock_saved) 66 if (clock_saved)
69 local_tick_enable(clock_saved); 67 local_tick_enable(clock_saved);
70 } while (get_tod_clock() < end); 68 } while (get_tod_clock() < end);