aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/irq.c
diff options
context:
space:
mode:
authorKumar Gala <galak@kernel.crashing.org>2008-04-28 02:21:22 -0400
committerPaul Mackerras <paulus@samba.org>2008-04-29 01:57:34 -0400
commit85218827cc4ca900867807f19345418164ffc108 (patch)
tree1813b7fadb7c077acd0ef62f57385b7424ca0121 /arch/powerpc/kernel/irq.c
parentdd18434ff0b7d9b9ad3d596985fc84b329d2f9a8 (diff)
[POWERPC] Add IRQSTACKS support on ppc32
This makes it possible to use separate stacks for hard and soft IRQs on 32-bit powerpc as well as on 64-bit. The code for 32-bit is just the 32-bit analog of the 64-bit code. * Added allocation and initialization of the irq stacks. We limit the stacks to be in lowmem for ppc32. * Implemented ppc32 versions of call_do_softirq() and call_handle_irq() to switch the stack pointers * Reworked how we do stack overflow detection. We now keep around the limit of the stack in the thread_struct and compare against the limit to see if we've overflowed. We can now use this on ppc64 if desired. [ paulus@samba.org: Fixed bug on 6xx where we need to reload r9 with the thread_info pointer. ] Signed-off-by: Kumar Gala <galak@kernel.crashing.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/irq.c')
-rw-r--r--arch/powerpc/kernel/irq.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 425616f92d18..2f73f705d564 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -307,6 +307,7 @@ void do_IRQ(struct pt_regs *regs)
307 if (curtp != irqtp) { 307 if (curtp != irqtp) {
308 struct irq_desc *desc = irq_desc + irq; 308 struct irq_desc *desc = irq_desc + irq;
309 void *handler = desc->handle_irq; 309 void *handler = desc->handle_irq;
310 unsigned long saved_sp_limit = current->thread.ksp_limit;
310 if (handler == NULL) 311 if (handler == NULL)
311 handler = &__do_IRQ; 312 handler = &__do_IRQ;
312 irqtp->task = curtp->task; 313 irqtp->task = curtp->task;
@@ -319,7 +320,10 @@ void do_IRQ(struct pt_regs *regs)
319 (irqtp->preempt_count & ~SOFTIRQ_MASK) | 320 (irqtp->preempt_count & ~SOFTIRQ_MASK) |
320 (curtp->preempt_count & SOFTIRQ_MASK); 321 (curtp->preempt_count & SOFTIRQ_MASK);
321 322
323 current->thread.ksp_limit = (unsigned long)irqtp +
324 _ALIGN_UP(sizeof(struct thread_info), 16);
322 call_handle_irq(irq, desc, irqtp, handler); 325 call_handle_irq(irq, desc, irqtp, handler);
326 current->thread.ksp_limit = saved_sp_limit;
323 irqtp->task = NULL; 327 irqtp->task = NULL;
324 328
325 329
@@ -352,9 +356,7 @@ void __init init_IRQ(void)
352{ 356{
353 if (ppc_md.init_IRQ) 357 if (ppc_md.init_IRQ)
354 ppc_md.init_IRQ(); 358 ppc_md.init_IRQ();
355#ifdef CONFIG_PPC64
356 irq_ctx_init(); 359 irq_ctx_init();
357#endif
358} 360}
359 361
360 362
@@ -383,11 +385,15 @@ void irq_ctx_init(void)
383static inline void do_softirq_onstack(void) 385static inline void do_softirq_onstack(void)
384{ 386{
385 struct thread_info *curtp, *irqtp; 387 struct thread_info *curtp, *irqtp;
388 unsigned long saved_sp_limit = current->thread.ksp_limit;
386 389
387 curtp = current_thread_info(); 390 curtp = current_thread_info();
388 irqtp = softirq_ctx[smp_processor_id()]; 391 irqtp = softirq_ctx[smp_processor_id()];
389 irqtp->task = curtp->task; 392 irqtp->task = curtp->task;
393 current->thread.ksp_limit = (unsigned long)irqtp +
394 _ALIGN_UP(sizeof(struct thread_info), 16);
390 call_do_softirq(irqtp); 395 call_do_softirq(irqtp);
396 current->thread.ksp_limit = saved_sp_limit;
391 irqtp->task = NULL; 397 irqtp->task = NULL;
392} 398}
393 399