aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c23
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c8
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c12
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c209
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c11
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c11
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h10
7 files changed, 219 insertions, 65 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 290b10e45105..237e152d31dc 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -106,7 +106,17 @@ int put_spu_context(struct spu_context *ctx)
106void spu_forget(struct spu_context *ctx) 106void spu_forget(struct spu_context *ctx)
107{ 107{
108 struct mm_struct *mm; 108 struct mm_struct *mm;
109 spu_acquire_saved(ctx); 109
110 /*
111 * This is basically an open-coded spu_acquire_saved, except that
112 * we don't acquire the state mutex interruptible.
113 */
114 mutex_lock(&ctx->state_mutex);
115 if (ctx->state != SPU_STATE_SAVED) {
116 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
117 spu_deactivate(ctx);
118 }
119
110 mm = ctx->owner; 120 mm = ctx->owner;
111 ctx->owner = NULL; 121 ctx->owner = NULL;
112 mmput(mm); 122 mmput(mm);
@@ -137,13 +147,20 @@ void spu_unmap_mappings(struct spu_context *ctx)
137 * spu_acquire_saved - lock spu contex and make sure it is in saved state 147 * spu_acquire_saved - lock spu contex and make sure it is in saved state
138 * @ctx: spu contex to lock 148 * @ctx: spu contex to lock
139 */ 149 */
140void spu_acquire_saved(struct spu_context *ctx) 150int spu_acquire_saved(struct spu_context *ctx)
141{ 151{
142 spu_acquire(ctx); 152 int ret;
153
154 ret = spu_acquire(ctx);
155 if (ret)
156 return ret;
157
143 if (ctx->state != SPU_STATE_SAVED) { 158 if (ctx->state != SPU_STATE_SAVED) {
144 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags); 159 set_bit(SPU_SCHED_WAS_ACTIVE, &ctx->sched_flags);
145 spu_deactivate(ctx); 160 spu_deactivate(ctx);
146 } 161 }
162
163 return 0;
147} 164}
148 165
149/** 166/**
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 80f62363e1ce..0c6a96b82b2d 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -148,7 +148,9 @@ int spufs_coredump_extra_notes_size(void)
148 148
149 fd = 0; 149 fd = 0;
150 while ((ctx = coredump_next_context(&fd)) != NULL) { 150 while ((ctx = coredump_next_context(&fd)) != NULL) {
151 spu_acquire_saved(ctx); 151 rc = spu_acquire_saved(ctx);
152 if (rc)
153 break;
152 rc = spufs_ctx_note_size(ctx, fd); 154 rc = spufs_ctx_note_size(ctx, fd);
153 spu_release_saved(ctx); 155 spu_release_saved(ctx);
154 if (rc < 0) 156 if (rc < 0)
@@ -224,7 +226,9 @@ int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset)
224 226
225 fd = 0; 227 fd = 0;
226 while ((ctx = coredump_next_context(&fd)) != NULL) { 228 while ((ctx = coredump_next_context(&fd)) != NULL) {
227 spu_acquire_saved(ctx); 229 rc = spu_acquire_saved(ctx);
230 if (rc)
231 return rc;
228 232
229 for (j = 0; spufs_coredump_read[j].name != NULL; j++) { 233 for (j = 0; spufs_coredump_read[j].name != NULL; j++) {
230 rc = spufs_arch_write_note(ctx, j, file, fd, foffset); 234 rc = spufs_arch_write_note(ctx, j, file, fd, foffset);
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 720e111f1f6a..825001c2b095 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -107,7 +107,7 @@ int spufs_handle_class1(struct spu_context *ctx)
107 u64 ea, dsisr, access; 107 u64 ea, dsisr, access;
108 unsigned long flags; 108 unsigned long flags;
109 unsigned flt = 0; 109 unsigned flt = 0;
110 int ret; 110 int ret, ret2;
111 111
112 /* 112 /*
113 * dar and dsisr get passed from the registers 113 * dar and dsisr get passed from the registers
@@ -146,7 +146,14 @@ int spufs_handle_class1(struct spu_context *ctx)
146 if (ret) 146 if (ret)
147 ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt); 147 ret = spu_handle_mm_fault(current->mm, ea, dsisr, &flt);
148 148
149 spu_acquire(ctx); 149 /*
150 * If spu_acquire fails due to a pending signal we just want to return
151 * EINTR to userspace even if that means missing the dma restart or
152 * updating the page fault statistics.
153 */
154 ret2 = spu_acquire(ctx);
155 if (ret2)
156 goto out;
150 157
151 /* 158 /*
152 * Clear dsisr under ctxt lock after handling the fault, so that 159 * Clear dsisr under ctxt lock after handling the fault, so that
@@ -177,6 +184,7 @@ int spufs_handle_class1(struct spu_context *ctx)
177 } else 184 } else
178 spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); 185 spufs_handle_event(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
179 186
187 out:
180 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM); 188 spuctx_switch_state(ctx, SPU_UTIL_SYSTEM);
181 return ret; 189 return ret;
182} 190}
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 510adc57af90..ba6101ae73a2 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -198,9 +198,12 @@ spufs_mem_read(struct file *file, char __user *buffer,
198 struct spu_context *ctx = file->private_data; 198 struct spu_context *ctx = file->private_data;
199 ssize_t ret; 199 ssize_t ret;
200 200
201 spu_acquire(ctx); 201 ret = spu_acquire(ctx);
202 if (ret)
203 return ret;
202 ret = __spufs_mem_read(ctx, buffer, size, pos); 204 ret = __spufs_mem_read(ctx, buffer, size, pos);
203 spu_release(ctx); 205 spu_release(ctx);
206
204 return ret; 207 return ret;
205} 208}
206 209
@@ -220,7 +223,10 @@ spufs_mem_write(struct file *file, const char __user *buffer,
220 if (size > LS_SIZE - pos) 223 if (size > LS_SIZE - pos)
221 size = LS_SIZE - pos; 224 size = LS_SIZE - pos;
222 225
223 spu_acquire(ctx); 226 ret = spu_acquire(ctx);
227 if (ret)
228 return ret;
229
224 local_store = ctx->ops->get_ls(ctx); 230 local_store = ctx->ops->get_ls(ctx);
225 ret = copy_from_user(local_store + pos, buffer, size); 231 ret = copy_from_user(local_store + pos, buffer, size);
226 spu_release(ctx); 232 spu_release(ctx);
@@ -260,7 +266,8 @@ static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma,
260 pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n", 266 pr_debug("spufs_mem_mmap_nopfn address=0x%lx -> 0x%lx, offset=0x%lx\n",
261 addr0, address, offset); 267 addr0, address, offset);
262 268
263 spu_acquire(ctx); 269 if (spu_acquire(ctx))
270 return NOPFN_REFAULT;
264 271
265 if (ctx->state == SPU_STATE_SAVED) { 272 if (ctx->state == SPU_STATE_SAVED) {
266 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 273 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
@@ -363,20 +370,19 @@ static unsigned long spufs_ps_nopfn(struct vm_area_struct *vma,
363 * to return NOPFN_REFAULT because the mappings may have 370 * to return NOPFN_REFAULT because the mappings may have
364 * hanged. 371 * hanged.
365 */ 372 */
366 spu_acquire(ctx); 373 if (spu_acquire(ctx))
374 return NOPFN_REFAULT;
375
367 if (ctx->state == SPU_STATE_SAVED) { 376 if (ctx->state == SPU_STATE_SAVED) {
368 up_read(&current->mm->mmap_sem); 377 up_read(&current->mm->mmap_sem);
369 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); 378 spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
370 down_read(&current->mm->mmap_sem); 379 down_read(&current->mm->mmap_sem);
371 goto out; 380 } else {
381 area = ctx->spu->problem_phys + ps_offs;
382 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
372 } 383 }
373 384
374 area = ctx->spu->problem_phys + ps_offs;
375 vm_insert_pfn(vma, address, (area + offset) >> PAGE_SHIFT);
376
377out:
378 spu_release(ctx); 385 spu_release(ctx);
379
380 return NOPFN_REFAULT; 386 return NOPFN_REFAULT;
381} 387}
382 388
@@ -413,8 +419,11 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
413static int spufs_cntl_get(void *data, u64 *val) 419static int spufs_cntl_get(void *data, u64 *val)
414{ 420{
415 struct spu_context *ctx = data; 421 struct spu_context *ctx = data;
422 int ret;
416 423
417 spu_acquire(ctx); 424 ret = spu_acquire(ctx);
425 if (ret)
426 return ret;
418 *val = ctx->ops->status_read(ctx); 427 *val = ctx->ops->status_read(ctx);
419 spu_release(ctx); 428 spu_release(ctx);
420 429
@@ -424,8 +433,11 @@ static int spufs_cntl_get(void *data, u64 *val)
424static int spufs_cntl_set(void *data, u64 val) 433static int spufs_cntl_set(void *data, u64 val)
425{ 434{
426 struct spu_context *ctx = data; 435 struct spu_context *ctx = data;
436 int ret;
427 437
428 spu_acquire(ctx); 438 ret = spu_acquire(ctx);
439 if (ret)
440 return ret;
429 ctx->ops->runcntl_write(ctx, val); 441 ctx->ops->runcntl_write(ctx, val);
430 spu_release(ctx); 442 spu_release(ctx);
431 443
@@ -493,7 +505,9 @@ spufs_regs_read(struct file *file, char __user *buffer,
493 int ret; 505 int ret;
494 struct spu_context *ctx = file->private_data; 506 struct spu_context *ctx = file->private_data;
495 507
496 spu_acquire_saved(ctx); 508 ret = spu_acquire_saved(ctx);
509 if (ret)
510 return ret;
497 ret = __spufs_regs_read(ctx, buffer, size, pos); 511 ret = __spufs_regs_read(ctx, buffer, size, pos);
498 spu_release_saved(ctx); 512 spu_release_saved(ctx);
499 return ret; 513 return ret;
@@ -512,7 +526,9 @@ spufs_regs_write(struct file *file, const char __user *buffer,
512 return -EFBIG; 526 return -EFBIG;
513 *pos += size; 527 *pos += size;
514 528
515 spu_acquire_saved(ctx); 529 ret = spu_acquire_saved(ctx);
530 if (ret)
531 return ret;
516 532
517 ret = copy_from_user(lscsa->gprs + *pos - size, 533 ret = copy_from_user(lscsa->gprs + *pos - size,
518 buffer, size) ? -EFAULT : size; 534 buffer, size) ? -EFAULT : size;
@@ -544,7 +560,9 @@ spufs_fpcr_read(struct file *file, char __user * buffer,
544 int ret; 560 int ret;
545 struct spu_context *ctx = file->private_data; 561 struct spu_context *ctx = file->private_data;
546 562
547 spu_acquire_saved(ctx); 563 ret = spu_acquire_saved(ctx);
564 if (ret)
565 return ret;
548 ret = __spufs_fpcr_read(ctx, buffer, size, pos); 566 ret = __spufs_fpcr_read(ctx, buffer, size, pos);
549 spu_release_saved(ctx); 567 spu_release_saved(ctx);
550 return ret; 568 return ret;
@@ -561,10 +579,12 @@ spufs_fpcr_write(struct file *file, const char __user * buffer,
561 size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size); 579 size = min_t(ssize_t, sizeof(lscsa->fpcr) - *pos, size);
562 if (size <= 0) 580 if (size <= 0)
563 return -EFBIG; 581 return -EFBIG;
564 *pos += size;
565 582
566 spu_acquire_saved(ctx); 583 ret = spu_acquire_saved(ctx);
584 if (ret)
585 return ret;
567 586
587 *pos += size;
568 ret = copy_from_user((char *)&lscsa->fpcr + *pos - size, 588 ret = copy_from_user((char *)&lscsa->fpcr + *pos - size,
569 buffer, size) ? -EFAULT : size; 589 buffer, size) ? -EFAULT : size;
570 590
@@ -611,7 +631,10 @@ static ssize_t spufs_mbox_read(struct file *file, char __user *buf,
611 631
612 udata = (void __user *)buf; 632 udata = (void __user *)buf;
613 633
614 spu_acquire(ctx); 634 count = spu_acquire(ctx);
635 if (count)
636 return count;
637
615 for (count = 0; (count + 4) <= len; count += 4, udata++) { 638 for (count = 0; (count + 4) <= len; count += 4, udata++) {
616 int ret; 639 int ret;
617 ret = ctx->ops->mbox_read(ctx, &mbox_data); 640 ret = ctx->ops->mbox_read(ctx, &mbox_data);
@@ -647,12 +670,15 @@ static ssize_t spufs_mbox_stat_read(struct file *file, char __user *buf,
647 size_t len, loff_t *pos) 670 size_t len, loff_t *pos)
648{ 671{
649 struct spu_context *ctx = file->private_data; 672 struct spu_context *ctx = file->private_data;
673 ssize_t ret;
650 u32 mbox_stat; 674 u32 mbox_stat;
651 675
652 if (len < 4) 676 if (len < 4)
653 return -EINVAL; 677 return -EINVAL;
654 678
655 spu_acquire(ctx); 679 ret = spu_acquire(ctx);
680 if (ret)
681 return ret;
656 682
657 mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff; 683 mbox_stat = ctx->ops->mbox_stat_read(ctx) & 0xff;
658 684
@@ -721,7 +747,9 @@ static ssize_t spufs_ibox_read(struct file *file, char __user *buf,
721 747
722 udata = (void __user *)buf; 748 udata = (void __user *)buf;
723 749
724 spu_acquire(ctx); 750 count = spu_acquire(ctx);
751 if (count)
752 return count;
725 753
726 /* wait only for the first element */ 754 /* wait only for the first element */
727 count = 0; 755 count = 0;
@@ -767,7 +795,11 @@ static unsigned int spufs_ibox_poll(struct file *file, poll_table *wait)
767 795
768 poll_wait(file, &ctx->ibox_wq, wait); 796 poll_wait(file, &ctx->ibox_wq, wait);
769 797
770 spu_acquire(ctx); 798 /*
799 * For now keep this uninterruptible and also ignore the rule
800 * that poll should not sleep. Will be fixed later.
801 */
802 mutex_lock(&ctx->state_mutex);
771 mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM); 803 mask = ctx->ops->mbox_stat_poll(ctx, POLLIN | POLLRDNORM);
772 spu_release(ctx); 804 spu_release(ctx);
773 805
@@ -785,12 +817,15 @@ static ssize_t spufs_ibox_stat_read(struct file *file, char __user *buf,
785 size_t len, loff_t *pos) 817 size_t len, loff_t *pos)
786{ 818{
787 struct spu_context *ctx = file->private_data; 819 struct spu_context *ctx = file->private_data;
820 ssize_t ret;
788 u32 ibox_stat; 821 u32 ibox_stat;
789 822
790 if (len < 4) 823 if (len < 4)
791 return -EINVAL; 824 return -EINVAL;
792 825
793 spu_acquire(ctx); 826 ret = spu_acquire(ctx);
827 if (ret)
828 return ret;
794 ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff; 829 ibox_stat = (ctx->ops->mbox_stat_read(ctx) >> 16) & 0xff;
795 spu_release(ctx); 830 spu_release(ctx);
796 831
@@ -862,7 +897,9 @@ static ssize_t spufs_wbox_write(struct file *file, const char __user *buf,
862 if (__get_user(wbox_data, udata)) 897 if (__get_user(wbox_data, udata))
863 return -EFAULT; 898 return -EFAULT;
864 899
865 spu_acquire(ctx); 900 count = spu_acquire(ctx);
901 if (count)
902 return count;
866 903
867 /* 904 /*
868 * make sure we can at least write one element, by waiting 905 * make sure we can at least write one element, by waiting
@@ -903,7 +940,11 @@ static unsigned int spufs_wbox_poll(struct file *file, poll_table *wait)
903 940
904 poll_wait(file, &ctx->wbox_wq, wait); 941 poll_wait(file, &ctx->wbox_wq, wait);
905 942
906 spu_acquire(ctx); 943 /*
944 * For now keep this uninterruptible and also ignore the rule
945 * that poll should not sleep. Will be fixed later.
946 */
947 mutex_lock(&ctx->state_mutex);
907 mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM); 948 mask = ctx->ops->mbox_stat_poll(ctx, POLLOUT | POLLWRNORM);
908 spu_release(ctx); 949 spu_release(ctx);
909 950
@@ -921,12 +962,15 @@ static ssize_t spufs_wbox_stat_read(struct file *file, char __user *buf,
921 size_t len, loff_t *pos) 962 size_t len, loff_t *pos)
922{ 963{
923 struct spu_context *ctx = file->private_data; 964 struct spu_context *ctx = file->private_data;
965 ssize_t ret;
924 u32 wbox_stat; 966 u32 wbox_stat;
925 967
926 if (len < 4) 968 if (len < 4)
927 return -EINVAL; 969 return -EINVAL;
928 970
929 spu_acquire(ctx); 971 ret = spu_acquire(ctx);
972 if (ret)
973 return ret;
930 wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff; 974 wbox_stat = (ctx->ops->mbox_stat_read(ctx) >> 8) & 0xff;
931 spu_release(ctx); 975 spu_release(ctx);
932 976
@@ -997,7 +1041,9 @@ static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
997 int ret; 1041 int ret;
998 struct spu_context *ctx = file->private_data; 1042 struct spu_context *ctx = file->private_data;
999 1043
1000 spu_acquire_saved(ctx); 1044 ret = spu_acquire_saved(ctx);
1045 if (ret)
1046 return ret;
1001 ret = __spufs_signal1_read(ctx, buf, len, pos); 1047 ret = __spufs_signal1_read(ctx, buf, len, pos);
1002 spu_release_saved(ctx); 1048 spu_release_saved(ctx);
1003 1049
@@ -1008,6 +1054,7 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
1008 size_t len, loff_t *pos) 1054 size_t len, loff_t *pos)
1009{ 1055{
1010 struct spu_context *ctx; 1056 struct spu_context *ctx;
1057 ssize_t ret;
1011 u32 data; 1058 u32 data;
1012 1059
1013 ctx = file->private_data; 1060 ctx = file->private_data;
@@ -1018,7 +1065,9 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
1018 if (copy_from_user(&data, buf, 4)) 1065 if (copy_from_user(&data, buf, 4))
1019 return -EFAULT; 1066 return -EFAULT;
1020 1067
1021 spu_acquire(ctx); 1068 ret = spu_acquire(ctx);
1069 if (ret)
1070 return ret;
1022 ctx->ops->signal1_write(ctx, data); 1071 ctx->ops->signal1_write(ctx, data);
1023 spu_release(ctx); 1072 spu_release(ctx);
1024 1073
@@ -1128,7 +1177,9 @@ static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
1128 struct spu_context *ctx = file->private_data; 1177 struct spu_context *ctx = file->private_data;
1129 int ret; 1178 int ret;
1130 1179
1131 spu_acquire_saved(ctx); 1180 ret = spu_acquire_saved(ctx);
1181 if (ret)
1182 return ret;
1132 ret = __spufs_signal2_read(ctx, buf, len, pos); 1183 ret = __spufs_signal2_read(ctx, buf, len, pos);
1133 spu_release_saved(ctx); 1184 spu_release_saved(ctx);
1134 1185
@@ -1139,6 +1190,7 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
1139 size_t len, loff_t *pos) 1190 size_t len, loff_t *pos)
1140{ 1191{
1141 struct spu_context *ctx; 1192 struct spu_context *ctx;
1193 ssize_t ret;
1142 u32 data; 1194 u32 data;
1143 1195
1144 ctx = file->private_data; 1196 ctx = file->private_data;
@@ -1149,7 +1201,9 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
1149 if (copy_from_user(&data, buf, 4)) 1201 if (copy_from_user(&data, buf, 4))
1150 return -EFAULT; 1202 return -EFAULT;
1151 1203
1152 spu_acquire(ctx); 1204 ret = spu_acquire(ctx);
1205 if (ret)
1206 return ret;
1153 ctx->ops->signal2_write(ctx, data); 1207 ctx->ops->signal2_write(ctx, data);
1154 spu_release(ctx); 1208 spu_release(ctx);
1155 1209
@@ -1220,13 +1274,18 @@ static const struct file_operations spufs_signal2_nosched_fops = {
1220static int __##__get(void *data, u64 *val) \ 1274static int __##__get(void *data, u64 *val) \
1221{ \ 1275{ \
1222 struct spu_context *ctx = data; \ 1276 struct spu_context *ctx = data; \
1277 int ret = 0; \
1223 \ 1278 \
1224 if (__acquire == SPU_ATTR_ACQUIRE) { \ 1279 if (__acquire == SPU_ATTR_ACQUIRE) { \
1225 spu_acquire(ctx); \ 1280 ret = spu_acquire(ctx); \
1281 if (ret) \
1282 return ret; \
1226 *val = __get(ctx); \ 1283 *val = __get(ctx); \
1227 spu_release(ctx); \ 1284 spu_release(ctx); \
1228 } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \ 1285 } else if (__acquire == SPU_ATTR_ACQUIRE_SAVED) { \
1229 spu_acquire_saved(ctx); \ 1286 ret = spu_acquire_saved(ctx); \
1287 if (ret) \
1288 return ret; \
1230 *val = __get(ctx); \ 1289 *val = __get(ctx); \
1231 spu_release_saved(ctx); \ 1290 spu_release_saved(ctx); \
1232 } else \ 1291 } else \
@@ -1239,8 +1298,11 @@ DEFINE_SPUFS_SIMPLE_ATTRIBUTE(__name, __##__get, __set, __fmt);
1239static int spufs_signal1_type_set(void *data, u64 val) 1298static int spufs_signal1_type_set(void *data, u64 val)
1240{ 1299{
1241 struct spu_context *ctx = data; 1300 struct spu_context *ctx = data;
1301 int ret;
1242 1302
1243 spu_acquire(ctx); 1303 ret = spu_acquire(ctx);
1304 if (ret)
1305 return ret;
1244 ctx->ops->signal1_type_set(ctx, val); 1306 ctx->ops->signal1_type_set(ctx, val);
1245 spu_release(ctx); 1307 spu_release(ctx);
1246 1308
@@ -1258,8 +1320,11 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_signal1_type, spufs_signal1_type_get,
1258static int spufs_signal2_type_set(void *data, u64 val) 1320static int spufs_signal2_type_set(void *data, u64 val)
1259{ 1321{
1260 struct spu_context *ctx = data; 1322 struct spu_context *ctx = data;
1323 int ret;
1261 1324
1262 spu_acquire(ctx); 1325 ret = spu_acquire(ctx);
1326 if (ret)
1327 return ret;
1263 ctx->ops->signal2_type_set(ctx, val); 1328 ctx->ops->signal2_type_set(ctx, val);
1264 spu_release(ctx); 1329 spu_release(ctx);
1265 1330
@@ -1512,12 +1577,17 @@ static ssize_t spufs_mfc_read(struct file *file, char __user *buffer,
1512 if (size != 4) 1577 if (size != 4)
1513 goto out; 1578 goto out;
1514 1579
1515 spu_acquire(ctx); 1580 ret = spu_acquire(ctx);
1581 if (ret)
1582 return ret;
1583
1584 ret = -EINVAL;
1516 if (file->f_flags & O_NONBLOCK) { 1585 if (file->f_flags & O_NONBLOCK) {
1517 status = ctx->ops->read_mfc_tagstatus(ctx); 1586 status = ctx->ops->read_mfc_tagstatus(ctx);
1518 if (!(status & ctx->tagwait)) 1587 if (!(status & ctx->tagwait))
1519 ret = -EAGAIN; 1588 ret = -EAGAIN;
1520 else 1589 else
1590 /* XXX(hch): shouldn't we clear ret here? */
1521 ctx->tagwait &= ~status; 1591 ctx->tagwait &= ~status;
1522 } else { 1592 } else {
1523 ret = spufs_wait(ctx->mfc_wq, 1593 ret = spufs_wait(ctx->mfc_wq,
@@ -1642,7 +1712,10 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1642 if (ret) 1712 if (ret)
1643 goto out; 1713 goto out;
1644 1714
1645 spu_acquire(ctx); 1715 ret = spu_acquire(ctx);
1716 if (ret)
1717 goto out;
1718
1646 ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE); 1719 ret = spufs_wait(ctx->run_wq, ctx->state == SPU_STATE_RUNNABLE);
1647 if (ret) 1720 if (ret)
1648 goto out; 1721 goto out;
@@ -1677,7 +1750,11 @@ static unsigned int spufs_mfc_poll(struct file *file,poll_table *wait)
1677 1750
1678 poll_wait(file, &ctx->mfc_wq, wait); 1751 poll_wait(file, &ctx->mfc_wq, wait);
1679 1752
1680 spu_acquire(ctx); 1753 /*
1754 * For now keep this uninterruptible and also ignore the rule
1755 * that poll should not sleep. Will be fixed later.
1756 */
1757 mutex_lock(&ctx->state_mutex);
1681 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2); 1758 ctx->ops->set_mfc_query(ctx, ctx->tagwait, 2);
1682 free_elements = ctx->ops->get_mfc_free_elements(ctx); 1759 free_elements = ctx->ops->get_mfc_free_elements(ctx);
1683 tagstatus = ctx->ops->read_mfc_tagstatus(ctx); 1760 tagstatus = ctx->ops->read_mfc_tagstatus(ctx);
@@ -1700,7 +1777,9 @@ static int spufs_mfc_flush(struct file *file, fl_owner_t id)
1700 struct spu_context *ctx = file->private_data; 1777 struct spu_context *ctx = file->private_data;
1701 int ret; 1778 int ret;
1702 1779
1703 spu_acquire(ctx); 1780 ret = spu_acquire(ctx);
1781 if (ret)
1782 return ret;
1704#if 0 1783#if 0
1705/* this currently hangs */ 1784/* this currently hangs */
1706 ret = spufs_wait(ctx->mfc_wq, 1785 ret = spufs_wait(ctx->mfc_wq,
@@ -1746,7 +1825,11 @@ static const struct file_operations spufs_mfc_fops = {
1746static int spufs_npc_set(void *data, u64 val) 1825static int spufs_npc_set(void *data, u64 val)
1747{ 1826{
1748 struct spu_context *ctx = data; 1827 struct spu_context *ctx = data;
1749 spu_acquire(ctx); 1828 int ret;
1829
1830 ret = spu_acquire(ctx);
1831 if (ret)
1832 return ret;
1750 ctx->ops->npc_write(ctx, val); 1833 ctx->ops->npc_write(ctx, val);
1751 spu_release(ctx); 1834 spu_release(ctx);
1752 1835
@@ -1764,7 +1847,11 @@ static int spufs_decr_set(void *data, u64 val)
1764{ 1847{
1765 struct spu_context *ctx = data; 1848 struct spu_context *ctx = data;
1766 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1849 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1767 spu_acquire_saved(ctx); 1850 int ret;
1851
1852 ret = spu_acquire_saved(ctx);
1853 if (ret)
1854 return ret;
1768 lscsa->decr.slot[0] = (u32) val; 1855 lscsa->decr.slot[0] = (u32) val;
1769 spu_release_saved(ctx); 1856 spu_release_saved(ctx);
1770 1857
@@ -1782,7 +1869,11 @@ DEFINE_SPUFS_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
1782static int spufs_decr_status_set(void *data, u64 val) 1869static int spufs_decr_status_set(void *data, u64 val)
1783{ 1870{
1784 struct spu_context *ctx = data; 1871 struct spu_context *ctx = data;
1785 spu_acquire_saved(ctx); 1872 int ret;
1873
1874 ret = spu_acquire_saved(ctx);
1875 if (ret)
1876 return ret;
1786 if (val) 1877 if (val)
1787 ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING; 1878 ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_DECREMENTER_RUNNING;
1788 else 1879 else
@@ -1807,7 +1898,11 @@ static int spufs_event_mask_set(void *data, u64 val)
1807{ 1898{
1808 struct spu_context *ctx = data; 1899 struct spu_context *ctx = data;
1809 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1900 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1810 spu_acquire_saved(ctx); 1901 int ret;
1902
1903 ret = spu_acquire_saved(ctx);
1904 if (ret)
1905 return ret;
1811 lscsa->event_mask.slot[0] = (u32) val; 1906 lscsa->event_mask.slot[0] = (u32) val;
1812 spu_release_saved(ctx); 1907 spu_release_saved(ctx);
1813 1908
@@ -1840,7 +1935,11 @@ static int spufs_srr0_set(void *data, u64 val)
1840{ 1935{
1841 struct spu_context *ctx = data; 1936 struct spu_context *ctx = data;
1842 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1937 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1843 spu_acquire_saved(ctx); 1938 int ret;
1939
1940 ret = spu_acquire_saved(ctx);
1941 if (ret)
1942 return ret;
1844 lscsa->srr0.slot[0] = (u32) val; 1943 lscsa->srr0.slot[0] = (u32) val;
1845 spu_release_saved(ctx); 1944 spu_release_saved(ctx);
1846 1945
@@ -1947,7 +2046,9 @@ static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
1947 if (!access_ok(VERIFY_WRITE, buf, len)) 2046 if (!access_ok(VERIFY_WRITE, buf, len))
1948 return -EFAULT; 2047 return -EFAULT;
1949 2048
1950 spu_acquire_saved(ctx); 2049 ret = spu_acquire_saved(ctx);
2050 if (ret)
2051 return ret;
1951 spin_lock(&ctx->csa.register_lock); 2052 spin_lock(&ctx->csa.register_lock);
1952 ret = __spufs_mbox_info_read(ctx, buf, len, pos); 2053 ret = __spufs_mbox_info_read(ctx, buf, len, pos);
1953 spin_unlock(&ctx->csa.register_lock); 2054 spin_unlock(&ctx->csa.register_lock);
@@ -1985,7 +2086,9 @@ static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
1985 if (!access_ok(VERIFY_WRITE, buf, len)) 2086 if (!access_ok(VERIFY_WRITE, buf, len))
1986 return -EFAULT; 2087 return -EFAULT;
1987 2088
1988 spu_acquire_saved(ctx); 2089 ret = spu_acquire_saved(ctx);
2090 if (ret)
2091 return ret;
1989 spin_lock(&ctx->csa.register_lock); 2092 spin_lock(&ctx->csa.register_lock);
1990 ret = __spufs_ibox_info_read(ctx, buf, len, pos); 2093 ret = __spufs_ibox_info_read(ctx, buf, len, pos);
1991 spin_unlock(&ctx->csa.register_lock); 2094 spin_unlock(&ctx->csa.register_lock);
@@ -2026,7 +2129,9 @@ static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
2026 if (!access_ok(VERIFY_WRITE, buf, len)) 2129 if (!access_ok(VERIFY_WRITE, buf, len))
2027 return -EFAULT; 2130 return -EFAULT;
2028 2131
2029 spu_acquire_saved(ctx); 2132 ret = spu_acquire_saved(ctx);
2133 if (ret)
2134 return ret;
2030 spin_lock(&ctx->csa.register_lock); 2135 spin_lock(&ctx->csa.register_lock);
2031 ret = __spufs_wbox_info_read(ctx, buf, len, pos); 2136 ret = __spufs_wbox_info_read(ctx, buf, len, pos);
2032 spin_unlock(&ctx->csa.register_lock); 2137 spin_unlock(&ctx->csa.register_lock);
@@ -2076,7 +2181,9 @@ static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
2076 if (!access_ok(VERIFY_WRITE, buf, len)) 2181 if (!access_ok(VERIFY_WRITE, buf, len))
2077 return -EFAULT; 2182 return -EFAULT;
2078 2183
2079 spu_acquire_saved(ctx); 2184 ret = spu_acquire_saved(ctx);
2185 if (ret)
2186 return ret;
2080 spin_lock(&ctx->csa.register_lock); 2187 spin_lock(&ctx->csa.register_lock);
2081 ret = __spufs_dma_info_read(ctx, buf, len, pos); 2188 ret = __spufs_dma_info_read(ctx, buf, len, pos);
2082 spin_unlock(&ctx->csa.register_lock); 2189 spin_unlock(&ctx->csa.register_lock);
@@ -2127,7 +2234,9 @@ static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
2127 struct spu_context *ctx = file->private_data; 2234 struct spu_context *ctx = file->private_data;
2128 int ret; 2235 int ret;
2129 2236
2130 spu_acquire_saved(ctx); 2237 ret = spu_acquire_saved(ctx);
2238 if (ret)
2239 return ret;
2131 spin_lock(&ctx->csa.register_lock); 2240 spin_lock(&ctx->csa.register_lock);
2132 ret = __spufs_proxydma_info_read(ctx, buf, len, pos); 2241 ret = __spufs_proxydma_info_read(ctx, buf, len, pos);
2133 spin_unlock(&ctx->csa.register_lock); 2242 spin_unlock(&ctx->csa.register_lock);
@@ -2216,8 +2325,12 @@ static unsigned long long spufs_class2_intrs(struct spu_context *ctx)
2216static int spufs_show_stat(struct seq_file *s, void *private) 2325static int spufs_show_stat(struct seq_file *s, void *private)
2217{ 2326{
2218 struct spu_context *ctx = s->private; 2327 struct spu_context *ctx = s->private;
2328 int ret;
2329
2330 ret = spu_acquire(ctx);
2331 if (ret)
2332 return ret;
2219 2333
2220 spu_acquire(ctx);
2221 seq_printf(s, "%s %llu %llu %llu %llu " 2334 seq_printf(s, "%s %llu %llu %llu %llu "
2222 "%llu %llu %llu %llu %llu %llu %llu %llu\n", 2335 "%llu %llu %llu %llu %llu %llu %llu %llu\n",
2223 ctx_state_names[ctx->stats.util_state], 2336 ctx_state_names[ctx->stats.util_state],
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index b380050cdbc7..c01a09da1e56 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -292,7 +292,7 @@ static int spu_process_callback(struct spu_context *ctx)
292 u32 ls_pointer, npc; 292 u32 ls_pointer, npc;
293 void __iomem *ls; 293 void __iomem *ls;
294 long spu_ret; 294 long spu_ret;
295 int ret; 295 int ret, ret2;
296 296
297 /* get syscall block from local store */ 297 /* get syscall block from local store */
298 npc = ctx->ops->npc_read(ctx) & ~3; 298 npc = ctx->ops->npc_read(ctx) & ~3;
@@ -314,9 +314,11 @@ static int spu_process_callback(struct spu_context *ctx)
314 if (spu_ret <= -ERESTARTSYS) { 314 if (spu_ret <= -ERESTARTSYS) {
315 ret = spu_handle_restartsys(ctx, &spu_ret, &npc); 315 ret = spu_handle_restartsys(ctx, &spu_ret, &npc);
316 } 316 }
317 spu_acquire(ctx); 317 ret2 = spu_acquire(ctx);
318 if (ret == -ERESTARTSYS) 318 if (ret == -ERESTARTSYS)
319 return ret; 319 return ret;
320 if (ret2)
321 return -EINTR;
320 } 322 }
321 323
322 /* write result, jump over indirect pointer */ 324 /* write result, jump over indirect pointer */
@@ -338,7 +340,9 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
338 spu_enable_spu(ctx); 340 spu_enable_spu(ctx);
339 ctx->event_return = 0; 341 ctx->event_return = 0;
340 342
341 spu_acquire(ctx); 343 ret = spu_acquire(ctx);
344 if (ret)
345 goto out_unlock;
342 346
343 spu_update_sched_info(ctx); 347 spu_update_sched_info(ctx);
344 348
@@ -414,6 +418,7 @@ long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *event)
414 418
415out: 419out:
416 *event = ctx->event_return; 420 *event = ctx->event_return;
421out_unlock:
417 mutex_unlock(&ctx->run_mutex); 422 mutex_unlock(&ctx->run_mutex);
418 return ret; 423 return ret;
419} 424}
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 2775c1652ba4..eee7cef28f1a 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -705,7 +705,9 @@ static void __spu_schedule(struct spu *spu, struct spu_context *ctx)
705 705
706static void spu_schedule(struct spu *spu, struct spu_context *ctx) 706static void spu_schedule(struct spu *spu, struct spu_context *ctx)
707{ 707{
708 spu_acquire(ctx); 708 /* not a candidate for interruptible because it's called either
709 from the scheduler thread or from spu_deactivate */
710 mutex_lock(&ctx->state_mutex);
709 __spu_schedule(spu, ctx); 711 __spu_schedule(spu, ctx);
710 spu_release(ctx); 712 spu_release(ctx);
711} 713}
@@ -823,7 +825,9 @@ static int __spu_deactivate(struct spu_context *ctx, int force, int max_prio)
823 else { 825 else {
824 spu_release(ctx); 826 spu_release(ctx);
825 spu_schedule(spu, new); 827 spu_schedule(spu, new);
826 spu_acquire(ctx); 828 /* this one can't easily be made
829 interruptible */
830 mutex_lock(&ctx->state_mutex);
827 } 831 }
828 } 832 }
829 } 833 }
@@ -867,7 +871,8 @@ static noinline void spusched_tick(struct spu_context *ctx)
867 struct spu *spu = NULL; 871 struct spu *spu = NULL;
868 u32 status; 872 u32 status;
869 873
870 spu_acquire(ctx); 874 if (spu_acquire(ctx))
875 BUG(); /* a kernel thread never has signals pending */
871 876
872 if (ctx->state != SPU_STATE_RUNNABLE) 877 if (ctx->state != SPU_STATE_RUNNABLE)
873 goto out; 878 goto out;
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 412de58f5b0f..0e114038ea6f 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -229,9 +229,9 @@ struct spu *affinity_check(struct spu_context *ctx);
229 229
230/* context management */ 230/* context management */
231extern atomic_t nr_spu_contexts; 231extern atomic_t nr_spu_contexts;
232static inline void spu_acquire(struct spu_context *ctx) 232static inline int __must_check spu_acquire(struct spu_context *ctx)
233{ 233{
234 mutex_lock(&ctx->state_mutex); 234 return mutex_lock_interruptible(&ctx->state_mutex);
235} 235}
236 236
237static inline void spu_release(struct spu_context *ctx) 237static inline void spu_release(struct spu_context *ctx)
@@ -246,7 +246,7 @@ int put_spu_context(struct spu_context *ctx);
246void spu_unmap_mappings(struct spu_context *ctx); 246void spu_unmap_mappings(struct spu_context *ctx);
247 247
248void spu_forget(struct spu_context *ctx); 248void spu_forget(struct spu_context *ctx);
249void spu_acquire_saved(struct spu_context *ctx); 249int __must_check spu_acquire_saved(struct spu_context *ctx);
250void spu_release_saved(struct spu_context *ctx); 250void spu_release_saved(struct spu_context *ctx);
251 251
252int spu_stopped(struct spu_context *ctx, u32 * stat); 252int spu_stopped(struct spu_context *ctx, u32 * stat);
@@ -284,7 +284,9 @@ extern char *isolated_loader;
284 } \ 284 } \
285 spu_release(ctx); \ 285 spu_release(ctx); \
286 schedule(); \ 286 schedule(); \
287 spu_acquire(ctx); \ 287 __ret = spu_acquire(ctx); \
288 if (__ret) \
289 break; \
288 } \ 290 } \
289 finish_wait(&(wq), &__wait); \ 291 finish_wait(&(wq), &__wait); \
290 __ret; \ 292 __ret; \