aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/cell/spufs
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-17 16:15:55 -0500
commit8dea78da5cee153b8af9c07a2745f6c55057fe12 (patch)
treea8f4d49d63b1ecc92f2fddceba0655b2472c5bd9 /arch/powerpc/platforms/cell/spufs
parent406089d01562f1e2bf9f089fd7637009ebaad589 (diff)
Patched in Tegra support.
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs')
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c41
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c1
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c155
-rw-r--r--arch/powerpc/platforms/cell/spufs/sched.c3
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h4
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c10
11 files changed, 134 insertions, 88 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index 6e8a9ef8590..64eb15b2204 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -21,6 +21,7 @@
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */ 22 */
23 23
24#include <linux/module.h>
24#include <linux/errno.h> 25#include <linux/errno.h>
25#include <linux/sched.h> 26#include <linux/sched.h>
26#include <linux/kernel.h> 27#include <linux/kernel.h>
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 9c6790d17ed..bf4d41d8fa1 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -22,9 +22,9 @@
22 22
23#include <linux/fs.h> 23#include <linux/fs.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/module.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/atomic.h> 27#include <linux/atomic.h>
27#include <linux/sched.h>
28#include <asm/spu.h> 28#include <asm/spu.h>
29#include <asm/spu_csa.h> 29#include <asm/spu_csa.h>
30#include "spufs.h" 30#include "spufs.h"
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
index 657e3f233a6..6cf3ec62852 100644
--- a/arch/powerpc/platforms/cell/spufs/coredump.c
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -26,6 +26,7 @@
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/gfp.h> 27#include <linux/gfp.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/module.h>
29#include <linux/syscalls.h> 30#include <linux/syscalls.h>
30 31
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
@@ -106,17 +107,6 @@ static int spufs_ctx_note_size(struct spu_context *ctx, int dfd)
106 return total; 107 return total;
107} 108}
108 109
109static int match_context(const void *v, struct file *file, unsigned fd)
110{
111 struct spu_context *ctx;
112 if (file->f_op != &spufs_context_fops)
113 return 0;
114 ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
115 if (ctx->flags & SPU_CREATE_NOSCHED)
116 return 0;
117 return fd + 1;
118}
119
120/* 110/*
121 * The additional architecture-specific notes for Cell are various 111 * The additional architecture-specific notes for Cell are various
122 * context files in the spu context. 112 * context files in the spu context.
@@ -126,18 +116,29 @@ static int match_context(const void *v, struct file *file, unsigned fd)
126 * internal functionality to dump them without needing to actually 116 * internal functionality to dump them without needing to actually
127 * open the files. 117 * open the files.
128 */ 118 */
129/*
130 * descriptor table is not shared, so files can't change or go away.
131 */
132static struct spu_context *coredump_next_context(int *fd) 119static struct spu_context *coredump_next_context(int *fd)
133{ 120{
121 struct fdtable *fdt = files_fdtable(current->files);
134 struct file *file; 122 struct file *file;
135 int n = iterate_fd(current->files, *fd, match_context, NULL); 123 struct spu_context *ctx = NULL;
136 if (!n) 124
137 return NULL; 125 for (; *fd < fdt->max_fds; (*fd)++) {
138 *fd = n - 1; 126 if (!FD_ISSET(*fd, fdt->open_fds))
139 file = fcheck(*fd); 127 continue;
140 return SPUFS_I(file->f_dentry->d_inode)->i_ctx; 128
129 file = fcheck(*fd);
130
131 if (!file || file->f_op != &spufs_context_fops)
132 continue;
133
134 ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
135 if (ctx->flags & SPU_CREATE_NOSCHED)
136 continue;
137
138 break;
139 }
140
141 return ctx;
141} 142}
142 143
143int spufs_coredump_extra_notes_size(void) 144int spufs_coredump_extra_notes_size(void)
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 8cb6260cc80..a4dd3ae7223 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -21,6 +21,7 @@
21 */ 21 */
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/module.h>
24 25
25#include <asm/spu.h> 26#include <asm/spu.h>
26#include <asm/spu_csa.h> 27#include <asm/spu_csa.h>
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 0cfece4cf6e..fb59c46e9e9 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -24,7 +24,7 @@
24 24
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/ioctl.h> 26#include <linux/ioctl.h>
27#include <linux/export.h> 27#include <linux/module.h>
28#include <linux/pagemap.h> 28#include <linux/pagemap.h>
29#include <linux/poll.h> 29#include <linux/poll.h>
30#include <linux/ptrace.h> 30#include <linux/ptrace.h>
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index 8655c4cbefc..64f8540b832 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -18,6 +18,7 @@
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */ 19 */
20 20
21#include <linux/module.h>
21#include <linux/errno.h> 22#include <linux/errno.h>
22#include <linux/sched.h> 23#include <linux/sched.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index dba1ce235da..e481f6b9a78 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -74,6 +74,7 @@ spufs_alloc_inode(struct super_block *sb)
74static void spufs_i_callback(struct rcu_head *head) 74static void spufs_i_callback(struct rcu_head *head)
75{ 75{
76 struct inode *inode = container_of(head, struct inode, i_rcu); 76 struct inode *inode = container_of(head, struct inode, i_rcu);
77 INIT_LIST_HEAD(&inode->i_dentry);
77 kmem_cache_free(spufs_inode_cache, SPUFS_I(inode)); 78 kmem_cache_free(spufs_inode_cache, SPUFS_I(inode));
78} 79}
79 80
@@ -91,7 +92,7 @@ spufs_init_once(void *p)
91} 92}
92 93
93static struct inode * 94static struct inode *
94spufs_new_inode(struct super_block *sb, umode_t mode) 95spufs_new_inode(struct super_block *sb, int mode)
95{ 96{
96 struct inode *inode; 97 struct inode *inode;
97 98
@@ -123,7 +124,7 @@ spufs_setattr(struct dentry *dentry, struct iattr *attr)
123 124
124static int 125static int
125spufs_new_file(struct super_block *sb, struct dentry *dentry, 126spufs_new_file(struct super_block *sb, struct dentry *dentry,
126 const struct file_operations *fops, umode_t mode, 127 const struct file_operations *fops, int mode,
127 size_t size, struct spu_context *ctx) 128 size_t size, struct spu_context *ctx)
128{ 129{
129 static const struct inode_operations spufs_file_iops = { 130 static const struct inode_operations spufs_file_iops = {
@@ -151,7 +152,7 @@ static void
151spufs_evict_inode(struct inode *inode) 152spufs_evict_inode(struct inode *inode)
152{ 153{
153 struct spufs_inode_info *ei = SPUFS_I(inode); 154 struct spufs_inode_info *ei = SPUFS_I(inode);
154 clear_inode(inode); 155 end_writeback(inode);
155 if (ei->i_ctx) 156 if (ei->i_ctx)
156 put_spu_context(ei->i_ctx); 157 put_spu_context(ei->i_ctx);
157 if (ei->i_gang) 158 if (ei->i_gang)
@@ -186,17 +187,14 @@ static void spufs_prune_dir(struct dentry *dir)
186static int spufs_rmdir(struct inode *parent, struct dentry *dir) 187static int spufs_rmdir(struct inode *parent, struct dentry *dir)
187{ 188{
188 /* remove all entries */ 189 /* remove all entries */
189 int res;
190 spufs_prune_dir(dir); 190 spufs_prune_dir(dir);
191 d_drop(dir); 191 d_drop(dir);
192 res = simple_rmdir(parent, dir); 192
193 /* We have to give up the mm_struct */ 193 return simple_rmdir(parent, dir);
194 spu_forget(SPUFS_I(dir->d_inode)->i_ctx);
195 return res;
196} 194}
197 195
198static int spufs_fill_dir(struct dentry *dir, 196static int spufs_fill_dir(struct dentry *dir,
199 const struct spufs_tree_descr *files, umode_t mode, 197 const struct spufs_tree_descr *files, int mode,
200 struct spu_context *ctx) 198 struct spu_context *ctx)
201{ 199{
202 struct dentry *dentry, *tmp; 200 struct dentry *dentry, *tmp;
@@ -248,6 +246,9 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
248 mutex_unlock(&parent->i_mutex); 246 mutex_unlock(&parent->i_mutex);
249 WARN_ON(ret); 247 WARN_ON(ret);
250 248
249 /* We have to give up the mm_struct */
250 spu_forget(ctx);
251
251 return dcache_dir_close(inode, file); 252 return dcache_dir_close(inode, file);
252} 253}
253 254
@@ -263,7 +264,7 @@ EXPORT_SYMBOL_GPL(spufs_context_fops);
263 264
264static int 265static int
265spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, 266spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
266 umode_t mode) 267 int mode)
267{ 268{
268 int ret; 269 int ret;
269 struct inode *inode; 270 struct inode *inode;
@@ -317,23 +318,28 @@ out:
317 return ret; 318 return ret;
318} 319}
319 320
320static int spufs_context_open(struct path *path) 321static int spufs_context_open(struct dentry *dentry, struct vfsmount *mnt)
321{ 322{
322 int ret; 323 int ret;
323 struct file *filp; 324 struct file *filp;
324 325
325 ret = get_unused_fd(); 326 ret = get_unused_fd();
326 if (ret < 0) 327 if (ret < 0) {
327 return ret; 328 dput(dentry);
329 mntput(mnt);
330 goto out;
331 }
328 332
329 filp = dentry_open(path, O_RDONLY, current_cred()); 333 filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
330 if (IS_ERR(filp)) { 334 if (IS_ERR(filp)) {
331 put_unused_fd(ret); 335 put_unused_fd(ret);
332 return PTR_ERR(filp); 336 ret = PTR_ERR(filp);
337 goto out;
333 } 338 }
334 339
335 filp->f_op = &spufs_context_fops; 340 filp->f_op = &spufs_context_fops;
336 fd_install(ret, filp); 341 fd_install(ret, filp);
342out:
337 return ret; 343 return ret;
338} 344}
339 345
@@ -441,33 +447,36 @@ spufs_set_affinity(unsigned int flags, struct spu_context *ctx,
441 447
442static int 448static int
443spufs_create_context(struct inode *inode, struct dentry *dentry, 449spufs_create_context(struct inode *inode, struct dentry *dentry,
444 struct vfsmount *mnt, int flags, umode_t mode, 450 struct vfsmount *mnt, int flags, int mode,
445 struct file *aff_filp) 451 struct file *aff_filp)
446{ 452{
447 int ret; 453 int ret;
448 int affinity; 454 int affinity;
449 struct spu_gang *gang; 455 struct spu_gang *gang;
450 struct spu_context *neighbor; 456 struct spu_context *neighbor;
451 struct path path = {.mnt = mnt, .dentry = dentry};
452 457
458 ret = -EPERM;
453 if ((flags & SPU_CREATE_NOSCHED) && 459 if ((flags & SPU_CREATE_NOSCHED) &&
454 !capable(CAP_SYS_NICE)) 460 !capable(CAP_SYS_NICE))
455 return -EPERM; 461 goto out_unlock;
456 462
463 ret = -EINVAL;
457 if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE)) 464 if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))
458 == SPU_CREATE_ISOLATE) 465 == SPU_CREATE_ISOLATE)
459 return -EINVAL; 466 goto out_unlock;
460 467
468 ret = -ENODEV;
461 if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader) 469 if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
462 return -ENODEV; 470 goto out_unlock;
463 471
464 gang = NULL; 472 gang = NULL;
465 neighbor = NULL; 473 neighbor = NULL;
466 affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU); 474 affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);
467 if (affinity) { 475 if (affinity) {
468 gang = SPUFS_I(inode)->i_gang; 476 gang = SPUFS_I(inode)->i_gang;
477 ret = -EINVAL;
469 if (!gang) 478 if (!gang)
470 return -EINVAL; 479 goto out_unlock;
471 mutex_lock(&gang->aff_mutex); 480 mutex_lock(&gang->aff_mutex);
472 neighbor = spufs_assert_affinity(flags, gang, aff_filp); 481 neighbor = spufs_assert_affinity(flags, gang, aff_filp);
473 if (IS_ERR(neighbor)) { 482 if (IS_ERR(neighbor)) {
@@ -487,18 +496,32 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
487 put_spu_context(neighbor); 496 put_spu_context(neighbor);
488 } 497 }
489 498
490 ret = spufs_context_open(&path); 499 /*
491 if (ret < 0) 500 * get references for dget and mntget, will be released
501 * in error path of *_open().
502 */
503 ret = spufs_context_open(dget(dentry), mntget(mnt));
504 if (ret < 0) {
492 WARN_ON(spufs_rmdir(inode, dentry)); 505 WARN_ON(spufs_rmdir(inode, dentry));
506 if (affinity)
507 mutex_unlock(&gang->aff_mutex);
508 mutex_unlock(&inode->i_mutex);
509 spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
510 goto out;
511 }
493 512
494out_aff_unlock: 513out_aff_unlock:
495 if (affinity) 514 if (affinity)
496 mutex_unlock(&gang->aff_mutex); 515 mutex_unlock(&gang->aff_mutex);
516out_unlock:
517 mutex_unlock(&inode->i_mutex);
518out:
519 dput(dentry);
497 return ret; 520 return ret;
498} 521}
499 522
500static int 523static int
501spufs_mkgang(struct inode *dir, struct dentry *dentry, umode_t mode) 524spufs_mkgang(struct inode *dir, struct dentry *dentry, int mode)
502{ 525{
503 int ret; 526 int ret;
504 struct inode *inode; 527 struct inode *inode;
@@ -534,45 +557,54 @@ out:
534 return ret; 557 return ret;
535} 558}
536 559
537static int spufs_gang_open(struct path *path) 560static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt)
538{ 561{
539 int ret; 562 int ret;
540 struct file *filp; 563 struct file *filp;
541 564
542 ret = get_unused_fd(); 565 ret = get_unused_fd();
543 if (ret < 0) 566 if (ret < 0) {
544 return ret; 567 dput(dentry);
568 mntput(mnt);
569 goto out;
570 }
545 571
546 /* 572 filp = dentry_open(dentry, mnt, O_RDONLY, current_cred());
547 * get references for dget and mntget, will be released
548 * in error path of *_open().
549 */
550 filp = dentry_open(path, O_RDONLY, current_cred());
551 if (IS_ERR(filp)) { 573 if (IS_ERR(filp)) {
552 put_unused_fd(ret); 574 put_unused_fd(ret);
553 return PTR_ERR(filp); 575 ret = PTR_ERR(filp);
576 goto out;
554 } 577 }
555 578
556 filp->f_op = &simple_dir_operations; 579 filp->f_op = &simple_dir_operations;
557 fd_install(ret, filp); 580 fd_install(ret, filp);
581out:
558 return ret; 582 return ret;
559} 583}
560 584
561static int spufs_create_gang(struct inode *inode, 585static int spufs_create_gang(struct inode *inode,
562 struct dentry *dentry, 586 struct dentry *dentry,
563 struct vfsmount *mnt, umode_t mode) 587 struct vfsmount *mnt, int mode)
564{ 588{
565 struct path path = {.mnt = mnt, .dentry = dentry};
566 int ret; 589 int ret;
567 590
568 ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO); 591 ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO);
569 if (!ret) { 592 if (ret)
570 ret = spufs_gang_open(&path); 593 goto out;
571 if (ret < 0) { 594
572 int err = simple_rmdir(inode, dentry); 595 /*
573 WARN_ON(err); 596 * get references for dget and mntget, will be released
574 } 597 * in error path of *_open().
598 */
599 ret = spufs_gang_open(dget(dentry), mntget(mnt));
600 if (ret < 0) {
601 int err = simple_rmdir(inode, dentry);
602 WARN_ON(err);
575 } 603 }
604
605out:
606 mutex_unlock(&inode->i_mutex);
607 dput(dentry);
576 return ret; 608 return ret;
577} 609}
578 610
@@ -580,34 +612,41 @@ static int spufs_create_gang(struct inode *inode,
580static struct file_system_type spufs_type; 612static struct file_system_type spufs_type;
581 613
582long spufs_create(struct path *path, struct dentry *dentry, 614long spufs_create(struct path *path, struct dentry *dentry,
583 unsigned int flags, umode_t mode, struct file *filp) 615 unsigned int flags, mode_t mode, struct file *filp)
584{ 616{
585 struct inode *dir = path->dentry->d_inode;
586 int ret; 617 int ret;
587 618
619 ret = -EINVAL;
588 /* check if we are on spufs */ 620 /* check if we are on spufs */
589 if (path->dentry->d_sb->s_type != &spufs_type) 621 if (path->dentry->d_sb->s_type != &spufs_type)
590 return -EINVAL; 622 goto out;
591 623
592 /* don't accept undefined flags */ 624 /* don't accept undefined flags */
593 if (flags & (~SPU_CREATE_FLAG_ALL)) 625 if (flags & (~SPU_CREATE_FLAG_ALL))
594 return -EINVAL; 626 goto out;
595 627
596 /* only threads can be underneath a gang */ 628 /* only threads can be underneath a gang */
597 if (path->dentry != path->dentry->d_sb->s_root) 629 if (path->dentry != path->dentry->d_sb->s_root) {
598 if ((flags & SPU_CREATE_GANG) || !SPUFS_I(dir)->i_gang) 630 if ((flags & SPU_CREATE_GANG) ||
599 return -EINVAL; 631 !SPUFS_I(path->dentry->d_inode)->i_gang)
632 goto out;
633 }
600 634
601 mode &= ~current_umask(); 635 mode &= ~current_umask();
602 636
603 if (flags & SPU_CREATE_GANG) 637 if (flags & SPU_CREATE_GANG)
604 ret = spufs_create_gang(dir, dentry, path->mnt, mode); 638 ret = spufs_create_gang(path->dentry->d_inode,
639 dentry, path->mnt, mode);
605 else 640 else
606 ret = spufs_create_context(dir, dentry, path->mnt, flags, mode, 641 ret = spufs_create_context(path->dentry->d_inode,
642 dentry, path->mnt, flags, mode,
607 filp); 643 filp);
608 if (ret >= 0) 644 if (ret >= 0)
609 fsnotify_mkdir(dir, dentry); 645 fsnotify_mkdir(path->dentry->d_inode, dentry);
646 return ret;
610 647
648out:
649 mutex_unlock(&path->dentry->d_inode->i_mutex);
611 return ret; 650 return ret;
612} 651}
613 652
@@ -719,9 +758,9 @@ spufs_create_root(struct super_block *sb, void *data)
719 goto out_iput; 758 goto out_iput;
720 759
721 ret = -ENOMEM; 760 ret = -ENOMEM;
722 sb->s_root = d_make_root(inode); 761 sb->s_root = d_alloc_root(inode);
723 if (!sb->s_root) 762 if (!sb->s_root)
724 goto out; 763 goto out_iput;
725 764
726 return 0; 765 return 0;
727out_iput: 766out_iput:
@@ -790,19 +829,19 @@ static int __init spufs_init(void)
790 ret = spu_sched_init(); 829 ret = spu_sched_init();
791 if (ret) 830 if (ret)
792 goto out_cache; 831 goto out_cache;
793 ret = register_spu_syscalls(&spufs_calls); 832 ret = register_filesystem(&spufs_type);
794 if (ret) 833 if (ret)
795 goto out_sched; 834 goto out_sched;
796 ret = register_filesystem(&spufs_type); 835 ret = register_spu_syscalls(&spufs_calls);
797 if (ret) 836 if (ret)
798 goto out_syscalls; 837 goto out_fs;
799 838
800 spufs_init_isolated_loader(); 839 spufs_init_isolated_loader();
801 840
802 return 0; 841 return 0;
803 842
804out_syscalls: 843out_fs:
805 unregister_spu_syscalls(&spufs_calls); 844 unregister_filesystem(&spufs_type);
806out_sched: 845out_sched:
807 spu_sched_exit(); 846 spu_sched_exit();
808out_cache: 847out_cache:
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c
index 25db92a8e1c..32cb4e66d2c 100644
--- a/arch/powerpc/platforms/cell/spufs/sched.c
+++ b/arch/powerpc/platforms/cell/spufs/sched.c
@@ -22,6 +22,7 @@
22 22
23#undef DEBUG 23#undef DEBUG
24 24
25#include <linux/module.h>
25#include <linux/errno.h> 26#include <linux/errno.h>
26#include <linux/sched.h> 27#include <linux/sched.h>
27#include <linux/kernel.h> 28#include <linux/kernel.h>
@@ -1094,7 +1095,7 @@ static int show_spu_loadavg(struct seq_file *s, void *private)
1094 LOAD_INT(c), LOAD_FRAC(c), 1095 LOAD_INT(c), LOAD_FRAC(c),
1095 count_active_contexts(), 1096 count_active_contexts(),
1096 atomic_read(&nr_spu_contexts), 1097 atomic_read(&nr_spu_contexts),
1097 task_active_pid_ns(current)->last_pid); 1098 current->nsproxy->pid_ns->last_pid);
1098 return 0; 1099 return 0;
1099} 1100}
1100 1101
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index 67852ade4c0..099245f230b 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -237,7 +237,7 @@ struct spufs_inode_info {
237struct spufs_tree_descr { 237struct spufs_tree_descr {
238 const char *name; 238 const char *name;
239 const struct file_operations *ops; 239 const struct file_operations *ops;
240 umode_t mode; 240 int mode;
241 size_t size; 241 size_t size;
242}; 242};
243 243
@@ -249,7 +249,7 @@ extern const struct spufs_tree_descr spufs_dir_debug_contents[];
249extern struct spufs_calls spufs_calls; 249extern struct spufs_calls spufs_calls;
250long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status); 250long spufs_run_spu(struct spu_context *ctx, u32 *npc, u32 *status);
251long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags, 251long spufs_create(struct path *nd, struct dentry *dentry, unsigned int flags,
252 umode_t mode, struct file *filp); 252 mode_t mode, struct file *filp);
253/* ELF coredump callbacks for writing SPU ELF notes */ 253/* ELF coredump callbacks for writing SPU ELF notes */
254extern int spufs_coredump_extra_notes_size(void); 254extern int spufs_coredump_extra_notes_size(void);
255extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset); 255extern int spufs_coredump_extra_notes_write(struct file *file, loff_t *foffset);
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index dde35551e74..3df9a36eb2f 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -32,7 +32,7 @@
32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 32 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 */ 33 */
34 34
35#include <linux/export.h> 35#include <linux/module.h>
36#include <linux/errno.h> 36#include <linux/errno.h>
37#include <linux/hardirq.h> 37#include <linux/hardirq.h>
38#include <linux/sched.h> 38#include <linux/sched.h>
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index baee994fe81..609e016e92d 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -1,6 +1,6 @@
1#include <linux/file.h> 1#include <linux/file.h>
2#include <linux/fs.h> 2#include <linux/fs.h>
3#include <linux/export.h> 3#include <linux/module.h>
4#include <linux/mount.h> 4#include <linux/mount.h>
5#include <linux/namei.h> 5#include <linux/namei.h>
6#include <linux/slab.h> 6#include <linux/slab.h>
@@ -60,17 +60,19 @@ out:
60} 60}
61 61
62static long do_spu_create(const char __user *pathname, unsigned int flags, 62static long do_spu_create(const char __user *pathname, unsigned int flags,
63 umode_t mode, struct file *neighbor) 63 mode_t mode, struct file *neighbor)
64{ 64{
65 struct path path; 65 struct path path;
66 struct dentry *dentry; 66 struct dentry *dentry;
67 int ret; 67 int ret;
68 68
69 dentry = user_path_create(AT_FDCWD, pathname, &path, LOOKUP_DIRECTORY); 69 dentry = user_path_create(AT_FDCWD, pathname, &path, 1);
70 ret = PTR_ERR(dentry); 70 ret = PTR_ERR(dentry);
71 if (!IS_ERR(dentry)) { 71 if (!IS_ERR(dentry)) {
72 ret = spufs_create(&path, dentry, flags, mode, neighbor); 72 ret = spufs_create(&path, dentry, flags, mode, neighbor);
73 done_path_create(&path, dentry); 73 mutex_unlock(&path.dentry->d_inode->i_mutex);
74 dput(dentry);
75 path_put(&path);
74 } 76 }
75 77
76 return ret; 78 return ret;