diff options
Diffstat (limited to 'arch/s390/kernel/irq.c')
-rw-r--r-- | arch/s390/kernel/irq.c | 52 |
1 files changed, 21 insertions, 31 deletions
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c index 8ac2097f13d4..bb27a262c44a 100644 --- a/arch/s390/kernel/irq.c +++ b/arch/s390/kernel/irq.c | |||
@@ -157,39 +157,29 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
157 | /* | 157 | /* |
158 | * Switch to the asynchronous interrupt stack for softirq execution. | 158 | * Switch to the asynchronous interrupt stack for softirq execution. |
159 | */ | 159 | */ |
160 | asmlinkage void do_softirq(void) | 160 | void do_softirq_own_stack(void) |
161 | { | 161 | { |
162 | unsigned long flags, old, new; | 162 | unsigned long old, new; |
163 | 163 | ||
164 | if (in_interrupt()) | 164 | /* Get current stack pointer. */ |
165 | return; | 165 | asm volatile("la %0,0(15)" : "=a" (old)); |
166 | 166 | /* Check against async. stack address range. */ | |
167 | local_irq_save(flags); | 167 | new = S390_lowcore.async_stack; |
168 | 168 | if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) { | |
169 | if (local_softirq_pending()) { | 169 | /* Need to switch to the async. stack. */ |
170 | /* Get current stack pointer. */ | 170 | new -= STACK_FRAME_OVERHEAD; |
171 | asm volatile("la %0,0(15)" : "=a" (old)); | 171 | ((struct stack_frame *) new)->back_chain = old; |
172 | /* Check against async. stack address range. */ | 172 | asm volatile(" la 15,0(%0)\n" |
173 | new = S390_lowcore.async_stack; | 173 | " basr 14,%2\n" |
174 | if (((new - old) >> (PAGE_SHIFT + THREAD_ORDER)) != 0) { | 174 | " la 15,0(%1)\n" |
175 | /* Need to switch to the async. stack. */ | 175 | : : "a" (new), "a" (old), |
176 | new -= STACK_FRAME_OVERHEAD; | 176 | "a" (__do_softirq) |
177 | ((struct stack_frame *) new)->back_chain = old; | 177 | : "0", "1", "2", "3", "4", "5", "14", |
178 | 178 | "cc", "memory" ); | |
179 | asm volatile(" la 15,0(%0)\n" | 179 | } else { |
180 | " basr 14,%2\n" | 180 | /* We are already on the async stack. */ |
181 | " la 15,0(%1)\n" | 181 | __do_softirq(); |
182 | : : "a" (new), "a" (old), | ||
183 | "a" (__do_softirq) | ||
184 | : "0", "1", "2", "3", "4", "5", "14", | ||
185 | "cc", "memory" ); | ||
186 | } else { | ||
187 | /* We are already on the async stack. */ | ||
188 | __do_softirq(); | ||
189 | } | ||
190 | } | 182 | } |
191 | |||
192 | local_irq_restore(flags); | ||
193 | } | 183 | } |
194 | 184 | ||
195 | /* | 185 | /* |