diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-12 18:13:45 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-12 18:13:45 -0700 |
commit | 8b9909ded6922c33c221b105b26917780cfa497d (patch) | |
tree | ed90419e17baf41974a6a46611ceb0db0f55692b /arch/powerpc/platforms/cell/spufs | |
parent | 44a5085162f3d3231b359784319a207032e09523 (diff) | |
parent | 7b3c384db1ff0f336b59d5062617915e216eaec1 (diff) |
Merge branch 'merge' of master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of master.kernel.org:/pub/scm/linux/kernel/git/paulus/powerpc:
[POWERPC] sys_move_pages should be callable from an SPU
[POWERPC] Wire up sys_epoll_pwait
[POWERPC] Allocate syscall number for sys_getcpu
[POWERPC] update cell_defconfig
[POWERPC] ps3: always make sure were running on a PS3
[POWERPC] Fix spu SLB invalidations
[POWERPC] avoid SPU_ACTIVATE_NOWAKE optimization
[POWERPC] spufs: fix possible memory corruption is spufs_mem_write
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 24 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/run.c | 4 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/sched.c | 20 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 6 | ||||
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/switch.c | 62 |
5 files changed, 25 insertions, 91 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index b00653d69c0..505266a568d 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -63,8 +63,8 @@ static ssize_t spufs_mem_read(struct file *file, char __user *buffer, size_t size, loff_t *pos) { - int ret; struct spu_context *ctx = file->private_data; + ssize_t ret; spu_acquire(ctx); ret = __spufs_mem_read(ctx, buffer, size, pos); @@ -74,25 +74,29 @@ spufs_mem_read(struct file *file, char __user *buffer, static ssize_t spufs_mem_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) + size_t size, loff_t *ppos) { struct spu_context *ctx = file->private_data; char *local_store; + loff_t pos = *ppos; int ret; - size = min_t(ssize_t, LS_SIZE - *pos, size); - if (size <= 0) + if (pos < 0) + return -EINVAL; + if (pos > LS_SIZE) return -EFBIG; - *pos += size; + if (size > LS_SIZE - pos) + size = LS_SIZE - pos; spu_acquire(ctx); - local_store = ctx->ops->get_ls(ctx); - ret = copy_from_user(local_store + *pos - size, - buffer, size) ? -EFAULT : size; - + ret = copy_from_user(local_store + pos, buffer, size); spu_release(ctx); - return ret; + + if (ret) + return -EFAULT; + *ppos = pos + size; + return size; } static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 353a8fa07ab..f95a611ca36 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -143,7 +143,7 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc) int ret; unsigned long runcntl = SPU_RUNCNTL_RUNNABLE; - ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE); + ret = spu_acquire_runnable(ctx, 0); if (ret) return ret; @@ -155,7 +155,7 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc) spu_release(ctx); ret = spu_setup_isolated(ctx); if (!ret) - ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE); + ret = spu_acquire_runnable(ctx, 0); } /* if userspace has set the runcntrl register (eg, to issue an diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 2f25e68b4ba..39823cec084 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -127,14 +127,6 @@ static void spu_remove_from_active_list(struct spu *spu) mutex_unlock(&spu_prio->active_mutex[node]); } -static inline void mm_needs_global_tlbie(struct mm_struct *mm) -{ - int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1; - - /* Global TLBIE broadcast required with SPEs. */ - __cpus_setall(&mm->cpu_vm_mask, nr); -} - static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); static void spu_switch_notify(struct spu *spu, struct spu_context *ctx) @@ -167,8 +159,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) ctx->spu = spu; ctx->ops = &spu_hw_ops; spu->pid = current->pid; - spu->mm = ctx->owner; - mm_needs_global_tlbie(spu->mm); + spu_associate_mm(spu, ctx->owner); spu->ibox_callback = spufs_ibox_callback; spu->wbox_callback = spufs_wbox_callback; spu->stop_callback = spufs_stop_callback; @@ -205,7 +196,7 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) spu->stop_callback = NULL; spu->mfc_callback = NULL; spu->dma_callback = NULL; - spu->mm = NULL; + spu_associate_mm(spu, NULL); spu->pid = 0; ctx->ops = &spu_backing_ops; ctx->spu = NULL; @@ -263,7 +254,6 @@ static void spu_prio_wait(struct spu_context *ctx) { DEFINE_WAIT(wait); - set_bit(SPU_SCHED_WAKE, &ctx->sched_flags); prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE); if (!signal_pending(current)) { mutex_unlock(&ctx->state_mutex); @@ -272,7 +262,6 @@ static void spu_prio_wait(struct spu_context *ctx) } __set_current_state(TASK_RUNNING); remove_wait_queue(&ctx->stop_wq, &wait); - clear_bit(SPU_SCHED_WAKE, &ctx->sched_flags); } /** @@ -292,7 +281,7 @@ static void spu_reschedule(struct spu *spu) best = sched_find_first_bit(spu_prio->bitmap); if (best < MAX_PRIO) { struct spu_context *ctx = spu_grab_context(best); - if (ctx && test_bit(SPU_SCHED_WAKE, &ctx->sched_flags)) + if (ctx) wake_up(&ctx->stop_wq); } spin_unlock(&spu_prio->runq_lock); @@ -414,8 +403,7 @@ int spu_activate(struct spu_context *ctx, unsigned long flags) } spu_add_to_rq(ctx); - if (!(flags & SPU_ACTIVATE_NOWAKE)) - spu_prio_wait(ctx); + spu_prio_wait(ctx); spu_del_from_rq(ctx); } while (!signal_pending(current)); diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 0c437891dfd..5c4e47d69d7 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -41,7 +41,7 @@ struct spu_gang; /* ctx->sched_flags */ enum { - SPU_SCHED_WAKE = 0, + SPU_SCHED_WAKE = 0, /* currently unused */ }; struct spu_context { @@ -191,9 +191,7 @@ void spu_forget(struct spu_context *ctx); int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags); void spu_acquire_saved(struct spu_context *ctx); int spu_acquire_exclusive(struct spu_context *ctx); -enum { - SPU_ACTIVATE_NOWAKE = 1, -}; + int spu_activate(struct spu_context *ctx, unsigned long flags); void spu_deactivate(struct spu_context *ctx); void spu_yield(struct spu_context *ctx); diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index c08981ff7fc..fd91c73de34 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -468,26 +468,6 @@ static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) MFC_CNTL_PURGE_DMA_COMPLETE); } -static inline void save_mfc_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Save, Step 29: - * If MFC_SR1[R]='1', save SLBs in CSA. - */ - if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) { - csa->priv2.slb_index_W = in_be64(&priv2->slb_index_W); - for (i = 0; i < 8; i++) { - out_be64(&priv2->slb_index_W, i); - eieio(); - csa->slb_esid_RW[i] = in_be64(&priv2->slb_esid_RW); - csa->slb_vsid_RW[i] = in_be64(&priv2->slb_vsid_RW); - eieio(); - } - } -} - static inline void setup_mfc_sr1(struct spu_state *csa, struct spu *spu) { /* Save, Step 30: @@ -708,20 +688,6 @@ static inline void resume_mfc_queue(struct spu_state *csa, struct spu *spu) out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE); } -static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 45: - * Restore, Step 19: - * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All. - */ - if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) { - out_be64(&priv2->slb_invalidate_all_W, 0UL); - eieio(); - } -} - static inline void get_kernel_slb(u64 ea, u64 slb[2]) { u64 llp; @@ -765,7 +731,7 @@ static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu) * MFC_SR1[R]=1 (in other words, assume that * translation is desired by OS environment). */ - invalidate_slbs(csa, spu); + spu_invalidate_slbs(spu); get_kernel_slb((unsigned long)&spu_save_code[0], code_slb); get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb); load_mfc_slb(spu, code_slb, 0); @@ -1718,27 +1684,6 @@ static inline void check_ppuint_mb_stat(struct spu_state *csa, struct spu *spu) } } -static inline void restore_mfc_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Restore, Step 68: - * If MFC_SR1[R]='1', restore SLBs from CSA. - */ - if (csa->priv1.mfc_sr1_RW & MFC_STATE1_RELOCATE_MASK) { - for (i = 0; i < 8; i++) { - out_be64(&priv2->slb_index_W, i); - eieio(); - out_be64(&priv2->slb_esid_RW, csa->slb_esid_RW[i]); - out_be64(&priv2->slb_vsid_RW, csa->slb_vsid_RW[i]); - eieio(); - } - out_be64(&priv2->slb_index_W, csa->priv2.slb_index_W); - eieio(); - } -} - static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu) { /* Restore, Step 69: @@ -1875,7 +1820,6 @@ static void save_csa(struct spu_state *prev, struct spu *spu) set_mfc_tclass_id(prev, spu); /* Step 26. */ purge_mfc_queue(prev, spu); /* Step 27. */ wait_purge_complete(prev, spu); /* Step 28. */ - save_mfc_slbs(prev, spu); /* Step 29. */ setup_mfc_sr1(prev, spu); /* Step 30. */ save_spu_npc(prev, spu); /* Step 31. */ save_spu_privcntl(prev, spu); /* Step 32. */ @@ -1987,7 +1931,7 @@ static void harvest(struct spu_state *prev, struct spu *spu) reset_spu_privcntl(prev, spu); /* Step 16. */ reset_spu_lslr(prev, spu); /* Step 17. */ setup_mfc_sr1(prev, spu); /* Step 18. */ - invalidate_slbs(prev, spu); /* Step 19. */ + spu_invalidate_slbs(spu); /* Step 19. */ reset_ch_part1(prev, spu); /* Step 20. */ reset_ch_part2(prev, spu); /* Step 21. */ enable_interrupts(prev, spu); /* Step 22. */ @@ -2055,7 +1999,7 @@ static void restore_csa(struct spu_state *next, struct spu *spu) restore_spu_mb(next, spu); /* Step 65. */ check_ppu_mb_stat(next, spu); /* Step 66. */ check_ppuint_mb_stat(next, spu); /* Step 67. */ - restore_mfc_slbs(next, spu); /* Step 68. */ + spu_invalidate_slbs(spu); /* Modified Step 68. */ restore_mfc_sr1(next, spu); /* Step 69. */ restore_other_spu_access(next, spu); /* Step 70. */ restore_spu_runcntl(next, spu); /* Step 71. */ |