| 1 | |
| 2 | |
| 3 | * linux/arch/sh/kernel/sys_sh.c
|
| 4 | *
|
| 5 | * This file contains various random system calls that
|
| 6 | * have a non-standard calling sequence on the Linux/SuperH
|
| 7 | * platform.
|
| 8 | *
|
| 9 | * Taken from i386 version.
|
| 10 |
|
| 11 | #include <linux/errno.h>
|
| 12 | #include <linux/sched.h>
|
| 13 | #include <linux/mm.h>
|
| 14 | #include <linux/smp.h>
|
| 15 | #include <linux/sem.h>
|
| 16 | #include <linux/msg.h>
|
| 17 | #include <linux/shm.h>
|
| 18 | #include <linux/stat.h>
|
| 19 | #include <linux/syscalls.h>
|
| 20 | #include <linux/mman.h>
|
| 21 | #include <linux/file.h>
|
| 22 | #include <linux/utsname.h>
|
| 23 | #include <linux/module.h>
|
| 24 | #include <linux/fs.h>
|
| 25 | #include <linux/ipc.h>
|
| 26 | #include <asm/syscalls.h>
|
| 27 | #include <linux/uaccess.h>
|
| 28 | #include <asm/unistd.h>
|
| 29 | #include <asm/cacheflush.h>
|
| 30 | #include <asm/cachectl.h>
|
| 31 |
|
| 32 | asmlinkage int old_mmap(unsigned long addr, unsigned long len,
|
| 33 | unsigned long prot, unsigned long flags,
|
| 34 | int fd, unsigned long off)
|
| 35 | {
|
| 36 | if (off & ~PAGE_MASK)
|
| 37 | return -EINVAL;
|
| 38 | return ksys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
|
| 39 | }
|
| 40 |
|
| 41 | asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
|
| 42 | unsigned long prot, unsigned long flags,
|
| 43 | unsigned long fd, unsigned long pgoff)
|
| 44 | {
|
| 45 | |
| 46 | * The shift for mmap2 is constant, regardless of PAGE_SIZE
|
| 47 | * setting.
|
| 48 |
|
| 49 | if (pgoff & ((1 << (PAGE_SHIFT - 12)) - 1))
|
| 50 | return -EINVAL;
|
| 51 |
|
| 52 | pgoff >>= PAGE_SHIFT - 12;
|
| 53 |
|
| 54 | return ksys_mmap_pgoff(addr, len, prot, flags, fd, pgoff);
|
| 55 | }
|
| 56 |
|
| 57 |
|
| 58 | asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op)
|
| 59 | {
|
| 60 | struct vm_area_struct *vma;
|
| 61 |
|
| 62 | if ((op <= 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I)))
|
| 63 | return -EINVAL;
|
| 64 |
|
| 65 | |
| 66 | * Verify that the specified address region actually belongs
|
| 67 | * to this process.
|
| 68 |
|
| 69 | if (addr + len < addr)
|
| 70 | return -EFAULT;
|
| 71 |
|
| 72 | mmap_read_lock(current->mm);
|
| 73 | vma = find_vma (current->mm, addr);
|
| 74 | if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) {
|
| 75 | mmap_read_unlock(current->mm);
|
| 76 | return -EFAULT;
|
| 77 | }
|
| 78 |
|
| 79 | switch (op & CACHEFLUSH_D_PURGE) {
|
| 80 | case CACHEFLUSH_D_INVAL:
|
| 81 | __flush_invalidate_region((void *)addr, len);
|
| 82 | break;
|
| 83 | case CACHEFLUSH_D_WB:
|
| 84 | __flush_wback_region((void *)addr, len);
|
| 85 | break;
|
| 86 | case CACHEFLUSH_D_PURGE:
|
| 87 | __flush_purge_region((void *)addr, len);
|
| 88 | break;
|
| 89 | }
|
| 90 |
|
| 91 | if (op & CACHEFLUSH_I)
|
| 92 | flush_icache_range(addr, addr+len);
|
| 93 |
|
| 94 | mmap_read_unlock(current->mm);
|
| 95 | return 0;
|
| 96 | }
|