diff options
Diffstat (limited to 'arch/sh/kernel/sys_sh.c')
-rw-r--r-- | arch/sh/kernel/sys_sh.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 90d00e47264d..8aa5d1ceaf14 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c | |||
@@ -25,6 +25,8 @@ | |||
25 | #include <asm/syscalls.h> | 25 | #include <asm/syscalls.h> |
26 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
27 | #include <asm/unistd.h> | 27 | #include <asm/unistd.h> |
28 | #include <asm/cacheflush.h> | ||
29 | #include <asm/cachectl.h> | ||
28 | 30 | ||
29 | static inline long | 31 | static inline long |
30 | do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, | 32 | do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, |
@@ -179,6 +181,47 @@ asmlinkage int sys_ipc(uint call, int first, int second, | |||
179 | return -EINVAL; | 181 | return -EINVAL; |
180 | } | 182 | } |
181 | 183 | ||
184 | /* sys_cacheflush -- flush (part of) the processor cache. */ | ||
185 | asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op) | ||
186 | { | ||
187 | struct vm_area_struct *vma; | ||
188 | |||
189 | if ((op <= 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I))) | ||
190 | return -EINVAL; | ||
191 | |||
192 | /* | ||
193 | * Verify that the specified address region actually belongs | ||
194 | * to this process. | ||
195 | */ | ||
196 | if (addr + len < addr) | ||
197 | return -EFAULT; | ||
198 | |||
199 | down_read(¤t->mm->mmap_sem); | ||
200 | vma = find_vma (current->mm, addr); | ||
201 | if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) { | ||
202 | up_read(¤t->mm->mmap_sem); | ||
203 | return -EFAULT; | ||
204 | } | ||
205 | |||
206 | switch (op & CACHEFLUSH_D_PURGE) { | ||
207 | case CACHEFLUSH_D_INVAL: | ||
208 | __flush_invalidate_region((void *)addr, len); | ||
209 | break; | ||
210 | case CACHEFLUSH_D_WB: | ||
211 | __flush_wback_region((void *)addr, len); | ||
212 | break; | ||
213 | case CACHEFLUSH_D_PURGE: | ||
214 | __flush_purge_region((void *)addr, len); | ||
215 | break; | ||
216 | } | ||
217 | |||
218 | if (op & CACHEFLUSH_I) | ||
219 | flush_cache_all(); | ||
220 | |||
221 | up_read(¤t->mm->mmap_sem); | ||
222 | return 0; | ||
223 | } | ||
224 | |||
182 | asmlinkage int sys_uname(struct old_utsname __user *name) | 225 | asmlinkage int sys_uname(struct old_utsname __user *name) |
183 | { | 226 | { |
184 | int err; | 227 | int err; |