diff options
| author | Mark Nutter <mnutter@us.ibm.com> | 2006-03-22 18:00:12 -0500 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-03-26 22:48:28 -0500 |
| commit | 6df10a82f8de89c66eb91c371d62d76e87b2cbba (patch) | |
| tree | e8615f4c00a44f4e4a609d59c51e958f0300526b | |
| parent | a33a7d7309d79656bc19a0e96fc4547a1633283e (diff) | |
[PATCH] spufs: enable SPE problem state MMIO access.
This patch is layered on top of CONFIG_SPARSEMEM
and is patterned after direct mapping of LS.
This patch allows mmap() of the following regions:
"mfc", which represents the area from [0x3000 - 0x3fff];
"cntl", which represents the area from [0x4000 - 0x4fff];
"signal1" which begins at offset 0x14000; "signal2" which
begins at offset 0x1c000.
The signal1 & signal2 files may be mmap()'d by regular user
processes. The cntl and mfc file, on the other hand, may
only be accessed if the owning process has CAP_SYS_RAWIO,
because they have the potential to confuse the kernel
with regard to parallel access to the same files with
regular file operations: the kernel always holds a spinlock
when accessing registers in these areas to serialize them,
which can not be guaranteed with user mmaps,
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/Kconfig | 5 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 5 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/context.c | 18 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/file.c | 229 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/inode.c | 2 | ||||
| -rw-r--r-- | arch/powerpc/platforms/cell/spufs/spufs.h | 8 | ||||
| -rw-r--r-- | include/asm-powerpc/spu.h | 1 |
7 files changed, 256 insertions, 12 deletions
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 3157071e241c..c2a3db8edb0c 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig | |||
| @@ -10,4 +10,9 @@ config SPU_FS | |||
| 10 | Units on machines implementing the Broadband Processor | 10 | Units on machines implementing the Broadband Processor |
| 11 | Architecture. | 11 | Architecture. |
| 12 | 12 | ||
| 13 | config SPUFS_MMAP | ||
| 14 | bool | ||
| 15 | depends on SPU_FS && SPARSEMEM && !PPC_64K_PAGES | ||
| 16 | default y | ||
| 17 | |||
| 13 | endmenu | 18 | endmenu |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 162b6cfa8a43..d152a3fbdb83 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
| @@ -570,6 +570,11 @@ static int __init spu_map_device(struct spu *spu, struct device_node *spe) | |||
| 570 | if (!spu->local_store) | 570 | if (!spu->local_store) |
| 571 | goto out; | 571 | goto out; |
| 572 | 572 | ||
| 573 | prop = get_property(spe, "problem", NULL); | ||
| 574 | if (!prop) | ||
| 575 | goto out_unmap; | ||
| 576 | spu->problem_phys = *(unsigned long *)prop; | ||
| 577 | |||
| 573 | spu->problem= map_spe_prop(spe, "problem"); | 578 | spu->problem= map_spe_prop(spe, "problem"); |
| 574 | if (!spu->problem) | 579 | if (!spu->problem) |
| 575 | goto out_unmap; | 580 | goto out_unmap; |
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 7e016b9eab21..3f75c1e7adea 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <asm/spu_csa.h> | 27 | #include <asm/spu_csa.h> |
| 28 | #include "spufs.h" | 28 | #include "spufs.h" |
| 29 | 29 | ||
| 30 | struct spu_context *alloc_spu_context(struct address_space *local_store) | 30 | struct spu_context *alloc_spu_context(void) |
| 31 | { | 31 | { |
| 32 | struct spu_context *ctx; | 32 | struct spu_context *ctx; |
| 33 | ctx = kmalloc(sizeof *ctx, GFP_KERNEL); | 33 | ctx = kmalloc(sizeof *ctx, GFP_KERNEL); |
| @@ -53,7 +53,10 @@ struct spu_context *alloc_spu_context(struct address_space *local_store) | |||
| 53 | ctx->mfc_fasync = NULL; | 53 | ctx->mfc_fasync = NULL; |
| 54 | ctx->tagwait = 0; | 54 | ctx->tagwait = 0; |
| 55 | ctx->state = SPU_STATE_SAVED; | 55 | ctx->state = SPU_STATE_SAVED; |
| 56 | ctx->local_store = local_store; | 56 | ctx->local_store = NULL; |
| 57 | ctx->cntl = NULL; | ||
| 58 | ctx->signal1 = NULL; | ||
| 59 | ctx->signal2 = NULL; | ||
| 57 | ctx->spu = NULL; | 60 | ctx->spu = NULL; |
| 58 | ctx->ops = &spu_backing_ops; | 61 | ctx->ops = &spu_backing_ops; |
| 59 | ctx->owner = get_task_mm(current); | 62 | ctx->owner = get_task_mm(current); |
| @@ -110,7 +113,16 @@ void spu_release(struct spu_context *ctx) | |||
| 110 | 113 | ||
| 111 | void spu_unmap_mappings(struct spu_context *ctx) | 114 | void spu_unmap_mappings(struct spu_context *ctx) |
| 112 | { | 115 | { |
| 113 | unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); | 116 | if (ctx->local_store) |
| 117 | unmap_mapping_range(ctx->local_store, 0, LS_SIZE, 1); | ||
| 118 | if (ctx->mfc) | ||
| 119 | unmap_mapping_range(ctx->mfc, 0, 0x4000, 1); | ||
| 120 | if (ctx->cntl) | ||
| 121 | unmap_mapping_range(ctx->cntl, 0, 0x4000, 1); | ||
| 122 | if (ctx->signal1) | ||
| 123 | unmap_mapping_range(ctx->signal1, 0, 0x4000, 1); | ||
| 124 | if (ctx->signal2) | ||
| 125 | unmap_mapping_range(ctx->signal2, 0, 0x4000, 1); | ||
| 114 | } | 126 | } |
| 115 | 127 | ||
| 116 | int spu_acquire_runnable(struct spu_context *ctx) | 128 | int spu_acquire_runnable(struct spu_context *ctx) |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 62fe9941ccee..366185e92667 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
| @@ -41,8 +41,10 @@ static int | |||
| 41 | spufs_mem_open(struct inode *inode, struct file *file) | 41 | spufs_mem_open(struct inode *inode, struct file *file) |
| 42 | { | 42 | { |
| 43 | struct spufs_inode_info *i = SPUFS_I(inode); | 43 | struct spufs_inode_info *i = SPUFS_I(inode); |
| 44 | file->private_data = i->i_ctx; | 44 | struct spu_context *ctx = i->i_ctx; |
| 45 | file->f_mapping = i->i_ctx->local_store; | 45 | file->private_data = ctx; |
| 46 | file->f_mapping = inode->i_mapping; | ||
| 47 | ctx->local_store = inode->i_mapping; | ||
| 46 | return 0; | 48 | return 0; |
| 47 | } | 49 | } |
| 48 | 50 | ||
| @@ -86,7 +88,7 @@ spufs_mem_write(struct file *file, const char __user *buffer, | |||
| 86 | return ret; | 88 | return ret; |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | #ifdef CONFIG_SPARSEMEM | 91 | #ifdef CONFIG_SPUFS_MMAP |
| 90 | static struct page * | 92 | static struct page * |
| 91 | spufs_mem_mmap_nopage(struct vm_area_struct *vma, | 93 | spufs_mem_mmap_nopage(struct vm_area_struct *vma, |
| 92 | unsigned long address, int *type) | 94 | unsigned long address, int *type) |
| @@ -138,11 +140,113 @@ static struct file_operations spufs_mem_fops = { | |||
| 138 | .read = spufs_mem_read, | 140 | .read = spufs_mem_read, |
| 139 | .write = spufs_mem_write, | 141 | .write = spufs_mem_write, |
| 140 | .llseek = generic_file_llseek, | 142 | .llseek = generic_file_llseek, |
| 141 | #ifdef CONFIG_SPARSEMEM | 143 | #ifdef CONFIG_SPUFS_MMAP |
| 142 | .mmap = spufs_mem_mmap, | 144 | .mmap = spufs_mem_mmap, |
| 143 | #endif | 145 | #endif |
| 144 | }; | 146 | }; |
| 145 | 147 | ||
| 148 | #ifdef CONFIG_SPUFS_MMAP | ||
| 149 | static struct page *spufs_ps_nopage(struct vm_area_struct *vma, | ||
| 150 | unsigned long address, | ||
| 151 | int *type, unsigned long ps_offs) | ||
| 152 | { | ||
| 153 | struct page *page = NOPAGE_SIGBUS; | ||
| 154 | int fault_type = VM_FAULT_SIGBUS; | ||
| 155 | struct spu_context *ctx = vma->vm_file->private_data; | ||
| 156 | unsigned long offset = address - vma->vm_start; | ||
| 157 | unsigned long area; | ||
| 158 | int ret; | ||
| 159 | |||
| 160 | offset += vma->vm_pgoff << PAGE_SHIFT; | ||
| 161 | if (offset >= 0x4000) | ||
| 162 | goto out; | ||
| 163 | |||
| 164 | ret = spu_acquire_runnable(ctx); | ||
| 165 | if (ret) | ||
| 166 | goto out; | ||
| 167 | |||
| 168 | area = ctx->spu->problem_phys + ps_offs; | ||
| 169 | page = pfn_to_page((area + offset) >> PAGE_SHIFT); | ||
| 170 | fault_type = VM_FAULT_MINOR; | ||
| 171 | page_cache_get(page); | ||
| 172 | |||
| 173 | spu_release(ctx); | ||
| 174 | |||
| 175 | out: | ||
| 176 | if (type) | ||
| 177 | *type = fault_type; | ||
| 178 | |||
| 179 | return page; | ||
| 180 | } | ||
| 181 | |||
| 182 | static struct page *spufs_cntl_mmap_nopage(struct vm_area_struct *vma, | ||
| 183 | unsigned long address, int *type) | ||
| 184 | { | ||
| 185 | return spufs_ps_nopage(vma, address, type, 0x4000); | ||
| 186 | } | ||
| 187 | |||
| 188 | static struct vm_operations_struct spufs_cntl_mmap_vmops = { | ||
| 189 | .nopage = spufs_cntl_mmap_nopage, | ||
| 190 | }; | ||
| 191 | |||
| 192 | /* | ||
| 193 | * mmap support for problem state control area [0x4000 - 0x4fff]. | ||
| 194 | * Mapping this area requires that the application have CAP_SYS_RAWIO, | ||
| 195 | * as these registers require special care when read/writing. | ||
| 196 | */ | ||
| 197 | static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) | ||
| 198 | { | ||
| 199 | if (!(vma->vm_flags & VM_SHARED)) | ||
| 200 | return -EINVAL; | ||
| 201 | |||
| 202 | if (!capable(CAP_SYS_RAWIO)) | ||
| 203 | return -EPERM; | ||
| 204 | |||
| 205 | vma->vm_flags |= VM_RESERVED; | ||
| 206 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | ||
| 207 | | _PAGE_NO_CACHE); | ||
| 208 | |||
| 209 | vma->vm_ops = &spufs_cntl_mmap_vmops; | ||
| 210 | return 0; | ||
| 211 | } | ||
| 212 | #endif | ||
| 213 | |||
| 214 | static int spufs_cntl_open(struct inode *inode, struct file *file) | ||
| 215 | { | ||
| 216 | struct spufs_inode_info *i = SPUFS_I(inode); | ||
| 217 | struct spu_context *ctx = i->i_ctx; | ||
| 218 | |||
| 219 | file->private_data = ctx; | ||
| 220 | file->f_mapping = inode->i_mapping; | ||
| 221 | ctx->cntl = inode->i_mapping; | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | static ssize_t | ||
| 226 | spufs_cntl_read(struct file *file, char __user *buffer, | ||
| 227 | size_t size, loff_t *pos) | ||
| 228 | { | ||
| 229 | /* FIXME: read from spu status */ | ||
| 230 | return -EINVAL; | ||
| 231 | } | ||
| 232 | |||
| 233 | static ssize_t | ||
| 234 | spufs_cntl_write(struct file *file, const char __user *buffer, | ||
| 235 | size_t size, loff_t *pos) | ||
| 236 | { | ||
| 237 | /* FIXME: write to runctl bit */ | ||
| 238 | return -EINVAL; | ||
| 239 | } | ||
| 240 | |||
| 241 | static struct file_operations spufs_cntl_fops = { | ||
| 242 | .open = spufs_cntl_open, | ||
| 243 | .read = spufs_cntl_read, | ||
| 244 | .write = spufs_cntl_write, | ||
| 245 | #ifdef CONFIG_SPUFS_MMAP | ||
| 246 | .mmap = spufs_cntl_mmap, | ||
| 247 | #endif | ||
| 248 | }; | ||
| 249 | |||
| 146 | static int | 250 | static int |
| 147 | spufs_regs_open(struct inode *inode, struct file *file) | 251 | spufs_regs_open(struct inode *inode, struct file *file) |
| 148 | { | 252 | { |
| @@ -503,6 +607,16 @@ static struct file_operations spufs_wbox_stat_fops = { | |||
| 503 | .read = spufs_wbox_stat_read, | 607 | .read = spufs_wbox_stat_read, |
| 504 | }; | 608 | }; |
| 505 | 609 | ||
| 610 | static int spufs_signal1_open(struct inode *inode, struct file *file) | ||
| 611 | { | ||
| 612 | struct spufs_inode_info *i = SPUFS_I(inode); | ||
| 613 | struct spu_context *ctx = i->i_ctx; | ||
| 614 | file->private_data = ctx; | ||
| 615 | file->f_mapping = inode->i_mapping; | ||
| 616 | ctx->signal1 = inode->i_mapping; | ||
| 617 | return nonseekable_open(inode, file); | ||
| 618 | } | ||
| 619 | |||
| 506 | static ssize_t spufs_signal1_read(struct file *file, char __user *buf, | 620 | static ssize_t spufs_signal1_read(struct file *file, char __user *buf, |
| 507 | size_t len, loff_t *pos) | 621 | size_t len, loff_t *pos) |
| 508 | { | 622 | { |
| @@ -543,12 +657,50 @@ static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, | |||
| 543 | return 4; | 657 | return 4; |
| 544 | } | 658 | } |
| 545 | 659 | ||
| 660 | #ifdef CONFIG_SPUFS_MMAP | ||
| 661 | static struct page *spufs_signal1_mmap_nopage(struct vm_area_struct *vma, | ||
| 662 | unsigned long address, int *type) | ||
| 663 | { | ||
| 664 | return spufs_ps_nopage(vma, address, type, 0x14000); | ||
| 665 | } | ||
| 666 | |||
| 667 | static struct vm_operations_struct spufs_signal1_mmap_vmops = { | ||
| 668 | .nopage = spufs_signal1_mmap_nopage, | ||
| 669 | }; | ||
| 670 | |||
| 671 | static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) | ||
| 672 | { | ||
| 673 | if (!(vma->vm_flags & VM_SHARED)) | ||
| 674 | return -EINVAL; | ||
| 675 | |||
| 676 | vma->vm_flags |= VM_RESERVED; | ||
| 677 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | ||
| 678 | | _PAGE_NO_CACHE); | ||
| 679 | |||
| 680 | vma->vm_ops = &spufs_signal1_mmap_vmops; | ||
| 681 | return 0; | ||
| 682 | } | ||
| 683 | #endif | ||
| 684 | |||
| 546 | static struct file_operations spufs_signal1_fops = { | 685 | static struct file_operations spufs_signal1_fops = { |
| 547 | .open = spufs_pipe_open, | 686 | .open = spufs_signal1_open, |
| 548 | .read = spufs_signal1_read, | 687 | .read = spufs_signal1_read, |
| 549 | .write = spufs_signal1_write, | 688 | .write = spufs_signal1_write, |
| 689 | #ifdef CONFIG_SPUFS_MMAP | ||
| 690 | .mmap = spufs_signal1_mmap, | ||
| 691 | #endif | ||
| 550 | }; | 692 | }; |
| 551 | 693 | ||
| 694 | static int spufs_signal2_open(struct inode *inode, struct file *file) | ||
| 695 | { | ||
| 696 | struct spufs_inode_info *i = SPUFS_I(inode); | ||
| 697 | struct spu_context *ctx = i->i_ctx; | ||
| 698 | file->private_data = ctx; | ||
| 699 | file->f_mapping = inode->i_mapping; | ||
| 700 | ctx->signal2 = inode->i_mapping; | ||
| 701 | return nonseekable_open(inode, file); | ||
| 702 | } | ||
| 703 | |||
| 552 | static ssize_t spufs_signal2_read(struct file *file, char __user *buf, | 704 | static ssize_t spufs_signal2_read(struct file *file, char __user *buf, |
| 553 | size_t len, loff_t *pos) | 705 | size_t len, loff_t *pos) |
| 554 | { | 706 | { |
| @@ -591,10 +743,39 @@ static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, | |||
| 591 | return 4; | 743 | return 4; |
| 592 | } | 744 | } |
| 593 | 745 | ||
| 746 | #ifdef CONFIG_SPUFS_MMAP | ||
| 747 | static struct page *spufs_signal2_mmap_nopage(struct vm_area_struct *vma, | ||
| 748 | unsigned long address, int *type) | ||
| 749 | { | ||
| 750 | return spufs_ps_nopage(vma, address, type, 0x1c000); | ||
| 751 | } | ||
| 752 | |||
| 753 | static struct vm_operations_struct spufs_signal2_mmap_vmops = { | ||
| 754 | .nopage = spufs_signal2_mmap_nopage, | ||
| 755 | }; | ||
| 756 | |||
| 757 | static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) | ||
| 758 | { | ||
| 759 | if (!(vma->vm_flags & VM_SHARED)) | ||
| 760 | return -EINVAL; | ||
| 761 | |||
| 762 | /* FIXME: */ | ||
| 763 | vma->vm_flags |= VM_RESERVED; | ||
| 764 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | ||
| 765 | | _PAGE_NO_CACHE); | ||
| 766 | |||
| 767 | vma->vm_ops = &spufs_signal2_mmap_vmops; | ||
| 768 | return 0; | ||
| 769 | } | ||
| 770 | #endif | ||
| 771 | |||
| 594 | static struct file_operations spufs_signal2_fops = { | 772 | static struct file_operations spufs_signal2_fops = { |
| 595 | .open = spufs_pipe_open, | 773 | .open = spufs_signal2_open, |
| 596 | .read = spufs_signal2_read, | 774 | .read = spufs_signal2_read, |
| 597 | .write = spufs_signal2_write, | 775 | .write = spufs_signal2_write, |
| 776 | #ifdef CONFIG_SPUFS_MMAP | ||
| 777 | .mmap = spufs_signal2_mmap, | ||
| 778 | #endif | ||
| 598 | }; | 779 | }; |
| 599 | 780 | ||
| 600 | static void spufs_signal1_type_set(void *data, u64 val) | 781 | static void spufs_signal1_type_set(void *data, u64 val) |
| @@ -643,6 +824,38 @@ static u64 spufs_signal2_type_get(void *data) | |||
| 643 | DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, | 824 | DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, |
| 644 | spufs_signal2_type_set, "%llu"); | 825 | spufs_signal2_type_set, "%llu"); |
| 645 | 826 | ||
| 827 | #ifdef CONFIG_SPUFS_MMAP | ||
| 828 | static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, | ||
| 829 | unsigned long address, int *type) | ||
| 830 | { | ||
| 831 | return spufs_ps_nopage(vma, address, type, 0x3000); | ||
| 832 | } | ||
| 833 | |||
| 834 | static struct vm_operations_struct spufs_mfc_mmap_vmops = { | ||
| 835 | .nopage = spufs_mfc_mmap_nopage, | ||
| 836 | }; | ||
| 837 | |||
| 838 | /* | ||
| 839 | * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. | ||
| 840 | * Mapping this area requires that the application have CAP_SYS_RAWIO, | ||
| 841 | * as these registers require special care when read/writing. | ||
| 842 | */ | ||
| 843 | static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) | ||
| 844 | { | ||
| 845 | if (!(vma->vm_flags & VM_SHARED)) | ||
| 846 | return -EINVAL; | ||
| 847 | |||
| 848 | if (!capable(CAP_SYS_RAWIO)) | ||
| 849 | return -EPERM; | ||
| 850 | |||
| 851 | vma->vm_flags |= VM_RESERVED; | ||
| 852 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | ||
| 853 | | _PAGE_NO_CACHE); | ||
| 854 | |||
| 855 | vma->vm_ops = &spufs_mfc_mmap_vmops; | ||
| 856 | return 0; | ||
| 857 | } | ||
| 858 | #endif | ||
| 646 | 859 | ||
| 647 | static int spufs_mfc_open(struct inode *inode, struct file *file) | 860 | static int spufs_mfc_open(struct inode *inode, struct file *file) |
| 648 | { | 861 | { |
| @@ -932,6 +1145,9 @@ static struct file_operations spufs_mfc_fops = { | |||
| 932 | .flush = spufs_mfc_flush, | 1145 | .flush = spufs_mfc_flush, |
| 933 | .fsync = spufs_mfc_fsync, | 1146 | .fsync = spufs_mfc_fsync, |
| 934 | .fasync = spufs_mfc_fasync, | 1147 | .fasync = spufs_mfc_fasync, |
| 1148 | #ifdef CONFIG_SPUFS_MMAP | ||
| 1149 | .mmap = spufs_mfc_mmap, | ||
| 1150 | #endif | ||
| 935 | }; | 1151 | }; |
| 936 | 1152 | ||
| 937 | static void spufs_npc_set(void *data, u64 val) | 1153 | static void spufs_npc_set(void *data, u64 val) |
| @@ -1077,6 +1293,7 @@ struct tree_descr spufs_dir_contents[] = { | |||
| 1077 | { "signal1_type", &spufs_signal1_type, 0666, }, | 1293 | { "signal1_type", &spufs_signal1_type, 0666, }, |
| 1078 | { "signal2_type", &spufs_signal2_type, 0666, }, | 1294 | { "signal2_type", &spufs_signal2_type, 0666, }, |
| 1079 | { "mfc", &spufs_mfc_fops, 0666, }, | 1295 | { "mfc", &spufs_mfc_fops, 0666, }, |
| 1296 | { "cntl", &spufs_cntl_fops, 0666, }, | ||
| 1080 | { "npc", &spufs_npc_ops, 0666, }, | 1297 | { "npc", &spufs_npc_ops, 0666, }, |
| 1081 | { "fpcr", &spufs_fpcr_fops, 0666, }, | 1298 | { "fpcr", &spufs_fpcr_fops, 0666, }, |
| 1082 | { "decr", &spufs_decr_ops, 0666, }, | 1299 | { "decr", &spufs_decr_ops, 0666, }, |
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index b3962c3a0348..dc06305eecf5 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
| @@ -241,7 +241,7 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 241 | inode->i_gid = dir->i_gid; | 241 | inode->i_gid = dir->i_gid; |
| 242 | inode->i_mode &= S_ISGID; | 242 | inode->i_mode &= S_ISGID; |
| 243 | } | 243 | } |
| 244 | ctx = alloc_spu_context(inode->i_mapping); | 244 | ctx = alloc_spu_context(); |
| 245 | SPUFS_I(inode)->i_ctx = ctx; | 245 | SPUFS_I(inode)->i_ctx = ctx; |
| 246 | if (!ctx) | 246 | if (!ctx) |
| 247 | goto out_iput; | 247 | goto out_iput; |
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 57d687ca3f03..4485738e2102 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h | |||
| @@ -43,7 +43,11 @@ struct spu_context { | |||
| 43 | struct spu *spu; /* pointer to a physical SPU */ | 43 | struct spu *spu; /* pointer to a physical SPU */ |
| 44 | struct spu_state csa; /* SPU context save area. */ | 44 | struct spu_state csa; /* SPU context save area. */ |
| 45 | spinlock_t mmio_lock; /* protects mmio access */ | 45 | spinlock_t mmio_lock; /* protects mmio access */ |
| 46 | struct address_space *local_store;/* local store backing store */ | 46 | struct address_space *local_store; /* local store mapping. */ |
| 47 | struct address_space *mfc; /* 'mfc' area mappings. */ | ||
| 48 | struct address_space *cntl; /* 'control' area mappings. */ | ||
| 49 | struct address_space *signal1; /* 'signal1' area mappings. */ | ||
| 50 | struct address_space *signal2; /* 'signal2' area mappings. */ | ||
| 47 | 51 | ||
| 48 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; | 52 | enum { SPU_STATE_RUNNABLE, SPU_STATE_SAVED } state; |
| 49 | struct rw_semaphore state_sema; | 53 | struct rw_semaphore state_sema; |
| @@ -125,7 +129,7 @@ long spufs_create_thread(struct nameidata *nd, | |||
| 125 | extern struct file_operations spufs_context_fops; | 129 | extern struct file_operations spufs_context_fops; |
| 126 | 130 | ||
| 127 | /* context management */ | 131 | /* context management */ |
| 128 | struct spu_context * alloc_spu_context(struct address_space *local_store); | 132 | struct spu_context * alloc_spu_context(void); |
| 129 | void destroy_spu_context(struct kref *kref); | 133 | void destroy_spu_context(struct kref *kref); |
| 130 | struct spu_context * get_spu_context(struct spu_context *ctx); | 134 | struct spu_context * get_spu_context(struct spu_context *ctx); |
| 131 | int put_spu_context(struct spu_context *ctx); | 135 | int put_spu_context(struct spu_context *ctx); |
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index 8564b8234069..f431d8b0b651 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h | |||
| @@ -110,6 +110,7 @@ struct spu { | |||
| 110 | char *name; | 110 | char *name; |
| 111 | unsigned long local_store_phys; | 111 | unsigned long local_store_phys; |
| 112 | u8 *local_store; | 112 | u8 *local_store; |
| 113 | unsigned long problem_phys; | ||
| 113 | struct spu_problem __iomem *problem; | 114 | struct spu_problem __iomem *problem; |
| 114 | struct spu_priv1 __iomem *priv1; | 115 | struct spu_priv1 __iomem *priv1; |
| 115 | struct spu_priv2 __iomem *priv2; | 116 | struct spu_priv2 __iomem *priv2; |
