diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-08-23 08:45:58 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2013-08-28 03:19:23 -0400 |
commit | 0587d409ec53312f735d2004d5f47f8effee1ea9 (patch) | |
tree | 7ab956aaf3d7d238f8bd40a8f50d60302cb3363a /arch/s390 | |
parent | 6b169ac9b4342ff3a1499bdeb7596aa4f1bc401b (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.S | 4 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 1 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 1 | ||||
-rw-r--r-- | arch/s390/lib/delay.c | 2 |
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 |
892 | cleanup_idle_insn: | 892 | cleanup_idle_insn: |
893 | .long psw_idle_lpsw + 0x80000000 | 893 | .long psw_idle_lpsw + 0x80000000 |
894 | cleanup_idle_wait: | 894 | cleanup_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 |
935 | cleanup_idle_insn: | 935 | cleanup_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 | ||
76 | void arch_cpu_idle_exit(void) | 77 | void 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); |