aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2006-04-28 20:40:21 -0400
committerPaul Mackerras <paulus@samba.org>2006-04-29 01:11:25 -0400
commitf807221dedbd30726c5dffcd5b5d22ce0ea683cb (patch)
tree7cc1f027c09c6265887711969b728d4cbf1dfe6d
parent03054d51a70e8c273df5d9bc31fea6c843eaa1c3 (diff)
[PATCH] spufs: Disable local interrupts for SPE hash_page calls.
This patch disables and saves local interrupts during hash_page processing for SPE contexts. We have to do it explicitly in the spu_irq_class_1_bottom function. For the interrupt handlers, we get the behaviour implicitly by using SA_INTERRUPT to disable interrupts while in the handler. Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 269dda4fd0b4..ef47a6239d48 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -306,19 +306,19 @@ spu_request_irqs(struct spu *spu)
306 306
307 snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number); 307 snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number);
308 ret = request_irq(irq_base + spu->isrc, 308 ret = request_irq(irq_base + spu->isrc,
309 spu_irq_class_0, 0, spu->irq_c0, spu); 309 spu_irq_class_0, SA_INTERRUPT, spu->irq_c0, spu);
310 if (ret) 310 if (ret)
311 goto out; 311 goto out;
312 312
313 snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number); 313 snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number);
314 ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc, 314 ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc,
315 spu_irq_class_1, 0, spu->irq_c1, spu); 315 spu_irq_class_1, SA_INTERRUPT, spu->irq_c1, spu);
316 if (ret) 316 if (ret)
317 goto out1; 317 goto out1;
318 318
319 snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number); 319 snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number);
320 ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc, 320 ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc,
321 spu_irq_class_2, 0, spu->irq_c2, spu); 321 spu_irq_class_2, SA_INTERRUPT, spu->irq_c2, spu);
322 if (ret) 322 if (ret)
323 goto out2; 323 goto out2;
324 goto out; 324 goto out;
@@ -487,10 +487,14 @@ int spu_irq_class_1_bottom(struct spu *spu)
487 ea = spu->dar; 487 ea = spu->dar;
488 dsisr = spu->dsisr; 488 dsisr = spu->dsisr;
489 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) { 489 if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) {
490 u64 flags;
491
490 access = (_PAGE_PRESENT | _PAGE_USER); 492 access = (_PAGE_PRESENT | _PAGE_USER);
491 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL; 493 access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
494 local_irq_save(flags);
492 if (hash_page(ea, access, 0x300) != 0) 495 if (hash_page(ea, access, 0x300) != 0)
493 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR; 496 error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
497 local_irq_restore(flags);
494 } 498 }
495 if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) { 499 if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) {
496 if ((ret = spu_handle_mm_fault(spu)) != 0) 500 if ((ret = spu_handle_mm_fault(spu)) != 0)