aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2008-03-03 01:44:06 -0500
committerPaul Mackerras <paulus@samba.org>2008-03-03 01:44:06 -0500
commitb9c64498f53e0f4d90eec03048f73ac215bb6f79 (patch)
tree554842d2405f6e5aa749d3f907e3ab5977781c05 /arch/powerpc
parent35d77ef1c05bc3760427954dafaee3ca550542f3 (diff)
parent2a58aa33daef37134c8a43dca0b7578c3fa7f993 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jk/spufs into merge
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c16
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c12
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/sputrace.c7
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c6
6 files changed, 38 insertions, 12 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 87eb07f94c5f..712001f6b7da 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -81,9 +81,12 @@ struct spu_slb {
81void spu_invalidate_slbs(struct spu *spu) 81void spu_invalidate_slbs(struct spu *spu)
82{ 82{
83 struct spu_priv2 __iomem *priv2 = spu->priv2; 83 struct spu_priv2 __iomem *priv2 = spu->priv2;
84 unsigned long flags;
84 85
86 spin_lock_irqsave(&spu->register_lock, flags);
85 if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) 87 if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK)
86 out_be64(&priv2->slb_invalidate_all_W, 0UL); 88 out_be64(&priv2->slb_invalidate_all_W, 0UL);
89 spin_unlock_irqrestore(&spu->register_lock, flags);
87} 90}
88EXPORT_SYMBOL_GPL(spu_invalidate_slbs); 91EXPORT_SYMBOL_GPL(spu_invalidate_slbs);
89 92
@@ -148,7 +151,11 @@ static inline void spu_load_slb(struct spu *spu, int slbe, struct spu_slb *slb)
148 __func__, slbe, slb->vsid, slb->esid); 151 __func__, slbe, slb->vsid, slb->esid);
149 152
150 out_be64(&priv2->slb_index_W, slbe); 153 out_be64(&priv2->slb_index_W, slbe);
154 /* set invalid before writing vsid */
155 out_be64(&priv2->slb_esid_RW, 0);
156 /* now it's safe to write the vsid */
151 out_be64(&priv2->slb_vsid_RW, slb->vsid); 157 out_be64(&priv2->slb_vsid_RW, slb->vsid);
158 /* setting the new esid makes the entry valid again */
152 out_be64(&priv2->slb_esid_RW, slb->esid); 159 out_be64(&priv2->slb_esid_RW, slb->esid);
153} 160}
154 161
@@ -290,9 +297,11 @@ void spu_setup_kernel_slbs(struct spu *spu, struct spu_lscsa *lscsa,
290 nr_slbs++; 297 nr_slbs++;
291 } 298 }
292 299
300 spin_lock_irq(&spu->register_lock);
293 /* Add the set of SLBs */ 301 /* Add the set of SLBs */
294 for (i = 0; i < nr_slbs; i++) 302 for (i = 0; i < nr_slbs; i++)
295 spu_load_slb(spu, i, &slbs[i]); 303 spu_load_slb(spu, i, &slbs[i]);
304 spin_unlock_irq(&spu->register_lock);
296} 305}
297EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs); 306EXPORT_SYMBOL_GPL(spu_setup_kernel_slbs);
298 307
@@ -337,13 +346,14 @@ spu_irq_class_1(int irq, void *data)
337 if (stat & CLASS1_STORAGE_FAULT_INTR) 346 if (stat & CLASS1_STORAGE_FAULT_INTR)
338 spu_mfc_dsisr_set(spu, 0ul); 347 spu_mfc_dsisr_set(spu, 0ul);
339 spu_int_stat_clear(spu, 1, stat); 348 spu_int_stat_clear(spu, 1, stat);
340 spin_unlock(&spu->register_lock);
341 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
342 dar, dsisr);
343 349
344 if (stat & CLASS1_SEGMENT_FAULT_INTR) 350 if (stat & CLASS1_SEGMENT_FAULT_INTR)
345 __spu_trap_data_seg(spu, dar); 351 __spu_trap_data_seg(spu, dar);
346 352
353 spin_unlock(&spu->register_lock);
354 pr_debug("%s: %lx %lx %lx %lx\n", __FUNCTION__, mask, stat,
355 dar, dsisr);
356
347 if (stat & CLASS1_STORAGE_FAULT_INTR) 357 if (stat & CLASS1_STORAGE_FAULT_INTR)
348 __spu_trap_data_map(spu, dar, dsisr); 358 __spu_trap_data_map(spu, dar, dsisr);
349 359
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 133995ed5cc7..cf6c2c89211d 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -109,13 +109,12 @@ void spu_forget(struct spu_context *ctx)
109 109
110 /* 110 /*
111 * This is basically an open-coded spu_acquire_saved, except that 111 * This is basically an open-coded spu_acquire_saved, except that
112 * we don't acquire the state mutex interruptible. 112 * we don't acquire the state mutex interruptible, and we don't
113 * want this context to be rescheduled on release.
113 */ 114 */
114 mutex_lock(&ctx->state_mutex); 115 mutex_lock(&ctx->state_mutex);
115 if (ctx->state != SPU_STATE_SAVED) { 116 if (ctx->state != SPU_STATE_SAVED)
116 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
117 spu_deactivate(ctx); 117 spu_deactivate(ctx);
118 }
119 118
120 mm = ctx->owner; 119 mm = ctx->owner;
121 ctx->owner = NULL; 120 ctx->owner = NULL;
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index c66c3756970d..f7a7e8635fb6 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -367,6 +367,13 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
367 return NOPFN_SIGBUS; 367 return NOPFN_SIGBUS;
368 368
369 /* 369 /*
370 * Because we release the mmap_sem, the context may be destroyed while
371 * we're in spu_wait. Grab an extra reference so it isn't destroyed
372 * in the meantime.
373 */
374 get_spu_context(ctx);
375
376 /*
370 * We have to wait for context to be loaded before we have 377 * We have to wait for context to be loaded before we have
371 * pages to hand out to the user, but we don't want to wait 378 * pages to hand out to the user, but we don't want to wait
372 * with the mmap_sem held. 379 * with the mmap_sem held.
@@ -375,7 +382,7 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
375 * hanged. 382 * hanged.
376 */ 383 */
377 if (spu_acquire(ctx)) 384 if (spu_acquire(ctx))
378 return NOPFN_REFAULT; 385 goto refault;
379 386
380 if (ctx->state == SPU_STATE_SAVED) { 387 if (ctx->state == SPU_STATE_SAVED) {
381 up_read(&current->mm->mmap_sem); 388 up_read(&current->mm->mmap_sem);
@@ -391,6 +398,9 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
391 398
392 if (!ret) 399 if (!ret)
393 spu_release(ctx); 400 spu_release(ctx);
401
402refault:
403 put_spu_context(ctx);
394 return NOPFN_REFAULT; 404 return NOPFN_REFAULT;
395} 405}
396 406
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 3a5972117de7..5d5f680cd0b8 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -246,7 +246,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx)
246 spu_switch_notify(spu, ctx); 246 spu_switch_notify(spu, ctx);
247 ctx->state = SPU_STATE_RUNNABLE; 247 ctx->state = SPU_STATE_RUNNABLE;
248 248
249 spuctx_switch_state(ctx, SPU_UTIL_IDLE_LOADED); 249 spuctx_switch_state(ctx, SPU_UTIL_USER);
250} 250}
251 251
252/* 252/*
diff --git a/arch/powerpc/platforms/cell/spufs/sputrace.c b/arch/powerpc/platforms/cell/spufs/sputrace.c
index 01974f7776e1..79aa773f3c99 100644
--- a/arch/powerpc/platforms/cell/spufs/sputrace.c
+++ b/arch/powerpc/platforms/cell/spufs/sputrace.c
@@ -58,12 +58,12 @@ static int sputrace_sprint(char *tbuf, int n)
58 ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start)); 58 ktime_to_timespec(ktime_sub(t->tstamp, sputrace_start));
59 59
60 return snprintf(tbuf, n, 60 return snprintf(tbuf, n,
61 "[%lu.%09lu] %d: %s (thread = %d, spu = %d)\n", 61 "[%lu.%09lu] %d: %s (ctxthread = %d, spu = %d)\n",
62 (unsigned long) tv.tv_sec, 62 (unsigned long) tv.tv_sec,
63 (unsigned long) tv.tv_nsec, 63 (unsigned long) tv.tv_nsec,
64 t->owner_tid,
65 t->name,
66 t->curr_tid, 64 t->curr_tid,
65 t->name,
66 t->owner_tid,
67 t->number); 67 t->number);
68} 68}
69 69
@@ -188,6 +188,7 @@ struct spu_probe spu_probes[] = {
188 { "spufs_ps_nopfn__insert", "%p %p", spu_context_event }, 188 { "spufs_ps_nopfn__insert", "%p %p", spu_context_event },
189 { "spu_acquire_saved__enter", "%p", spu_context_nospu_event }, 189 { "spu_acquire_saved__enter", "%p", spu_context_nospu_event },
190 { "destroy_spu_context__enter", "%p", spu_context_nospu_event }, 190 { "destroy_spu_context__enter", "%p", spu_context_nospu_event },
191 { "spufs_stop_callback__enter", "%p %p", spu_context_event },
191}; 192};
192 193
193static int __init sputrace_init(void) 194static int __init sputrace_init(void)
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 6f5886c7b1f9..e9dc7a55d1b9 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -34,6 +34,7 @@
34 34
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <linux/hardirq.h>
37#include <linux/sched.h> 38#include <linux/sched.h>
38#include <linux/kernel.h> 39#include <linux/kernel.h>
39#include <linux/mm.h> 40#include <linux/mm.h>
@@ -117,6 +118,8 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
117 * Write INT_MASK_class1 with value of 0. 118 * Write INT_MASK_class1 with value of 0.
118 * Save INT_Mask_class2 in CSA. 119 * Save INT_Mask_class2 in CSA.
119 * Write INT_MASK_class2 with value of 0. 120 * Write INT_MASK_class2 with value of 0.
121 * Synchronize all three interrupts to be sure
122 * we no longer execute a handler on another CPU.
120 */ 123 */
121 spin_lock_irq(&spu->register_lock); 124 spin_lock_irq(&spu->register_lock);
122 if (csa) { 125 if (csa) {
@@ -129,6 +132,9 @@ static inline void disable_interrupts(struct spu_state *csa, struct spu *spu)
129 spu_int_mask_set(spu, 2, 0ul); 132 spu_int_mask_set(spu, 2, 0ul);
130 eieio(); 133 eieio();
131 spin_unlock_irq(&spu->register_lock); 134 spin_unlock_irq(&spu->register_lock);
135 synchronize_irq(spu->irqs[0]);
136 synchronize_irq(spu->irqs[1]);
137 synchronize_irq(spu->irqs[2]);
132} 138}
133 139
134static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu) 140static inline void set_watchdog_timer(struct spu_state *csa, struct spu *spu)