~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/mips/kernel/syscall.c

Version: ~ [ linux-5.8-rc4 ] ~ [ linux-5.7.7 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.50 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.131 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.187 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.229 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.229 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * This file is subject to the terms and conditions of the GNU General Public
  3  * License.  See the file "COPYING" in the main directory of this archive
  4  * for more details.
  5  *
  6  * Copyright (C) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle
  7  * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
  8  * Copyright (C) 2001 MIPS Technologies, Inc.
  9  */
 10 #include <linux/capability.h>
 11 #include <linux/errno.h>
 12 #include <linux/linkage.h>
 13 #include <linux/fs.h>
 14 #include <linux/smp.h>
 15 #include <linux/ptrace.h>
 16 #include <linux/string.h>
 17 #include <linux/syscalls.h>
 18 #include <linux/file.h>
 19 #include <linux/utsname.h>
 20 #include <linux/unistd.h>
 21 #include <linux/sem.h>
 22 #include <linux/msg.h>
 23 #include <linux/shm.h>
 24 #include <linux/compiler.h>
 25 #include <linux/ipc.h>
 26 #include <linux/uaccess.h>
 27 #include <linux/slab.h>
 28 #include <linux/elf.h>
 29 
 30 #include <asm/asm.h>
 31 #include <asm/branch.h>
 32 #include <asm/cachectl.h>
 33 #include <asm/cacheflush.h>
 34 #include <asm/asm-offsets.h>
 35 #include <asm/signal.h>
 36 #include <asm/sim.h>
 37 #include <asm/shmparam.h>
 38 #include <asm/sysmips.h>
 39 #include <asm/uaccess.h>
 40 #include <asm/switch_to.h>
 41 
 42 /*
 43  * For historic reasons the pipe(2) syscall on MIPS has an unusual calling
 44  * convention.  It returns results in registers $v0 / $v1 which means there
 45  * is no need for it to do verify the validity of a userspace pointer
 46  * argument.  Historically that used to be expensive in Linux.  These days
 47  * the performance advantage is negligible.
 48  */
 49 asmlinkage int sysm_pipe(void)
 50 {
 51         int fd[2];
 52         int error = do_pipe_flags(fd, 0);
 53         if (error)
 54                 return error;
 55         current_pt_regs()->regs[3] = fd[1];
 56         return fd[0];
 57 }
 58 
 59 SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
 60         unsigned long, prot, unsigned long, flags, unsigned long,
 61         fd, off_t, offset)
 62 {
 63         unsigned long result;
 64 
 65         result = -EINVAL;
 66         if (offset & ~PAGE_MASK)
 67                 goto out;
 68 
 69         result = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
 70 
 71 out:
 72         return result;
 73 }
 74 
 75 SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
 76         unsigned long, prot, unsigned long, flags, unsigned long, fd,
 77         unsigned long, pgoff)
 78 {
 79         if (pgoff & (~PAGE_MASK >> 12))
 80                 return -EINVAL;
 81 
 82         return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> (PAGE_SHIFT-12));
 83 }
 84 
 85 save_static_function(sys_fork);
 86 save_static_function(sys_clone);
 87 
 88 SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
 89 {
 90         struct thread_info *ti = task_thread_info(current);
 91 
 92         ti->tp_value = addr;
 93         if (cpu_has_userlocal)
 94                 write_c0_userlocal(addr);
 95 
 96         return 0;
 97 }
 98 
 99 static inline int mips_atomic_set(unsigned long addr, unsigned long new)
100 {
101         unsigned long old, tmp;
102         struct pt_regs *regs;
103         unsigned int err;
104 
105         if (unlikely(addr & 3))
106                 return -EINVAL;
107 
108         if (unlikely(!access_ok(VERIFY_WRITE, addr, 4)))
109                 return -EINVAL;
110 
111         if (cpu_has_llsc && R10000_LLSC_WAR) {
112                 __asm__ __volatile__ (
113                 "       .set    mips3                                   \n"
114                 "       li      %[err], 0                               \n"
115                 "1:     ll      %[old], (%[addr])                       \n"
116                 "       move    %[tmp], %[new]                          \n"
117                 "2:     sc      %[tmp], (%[addr])                       \n"
118                 "       beqzl   %[tmp], 1b                              \n"
119                 "3:                                                     \n"
120                 "       .section .fixup,\"ax\"                          \n"
121                 "4:     li      %[err], %[efault]                       \n"
122                 "       j       3b                                      \n"
123                 "       .previous                                       \n"
124                 "       .section __ex_table,\"a\"                       \n"
125                 "       "STR(PTR)"      1b, 4b                          \n"
126                 "       "STR(PTR)"      2b, 4b                          \n"
127                 "       .previous                                       \n"
128                 "       .set    mips0                                   \n"
129                 : [old] "=&r" (old),
130                   [err] "=&r" (err),
131                   [tmp] "=&r" (tmp)
132                 : [addr] "r" (addr),
133                   [new] "r" (new),
134                   [efault] "i" (-EFAULT)
135                 : "memory");
136         } else if (cpu_has_llsc) {
137                 __asm__ __volatile__ (
138                 "       .set    mips3                                   \n"
139                 "       li      %[err], 0                               \n"
140                 "1:     ll      %[old], (%[addr])                       \n"
141                 "       move    %[tmp], %[new]                          \n"
142                 "2:     sc      %[tmp], (%[addr])                       \n"
143                 "       bnez    %[tmp], 4f                              \n"
144                 "3:                                                     \n"
145                 "       .subsection 2                                   \n"
146                 "4:     b       1b                                      \n"
147                 "       .previous                                       \n"
148                 "                                                       \n"
149                 "       .section .fixup,\"ax\"                          \n"
150                 "5:     li      %[err], %[efault]                       \n"
151                 "       j       3b                                      \n"
152                 "       .previous                                       \n"
153                 "       .section __ex_table,\"a\"                       \n"
154                 "       "STR(PTR)"      1b, 5b                          \n"
155                 "       "STR(PTR)"      2b, 5b                          \n"
156                 "       .previous                                       \n"
157                 "       .set    mips0                                   \n"
158                 : [old] "=&r" (old),
159                   [err] "=&r" (err),
160                   [tmp] "=&r" (tmp)
161                 : [addr] "r" (addr),
162                   [new] "r" (new),
163                   [efault] "i" (-EFAULT)
164                 : "memory");
165         } else {
166                 do {
167                         preempt_disable();
168                         ll_bit = 1;
169                         ll_task = current;
170                         preempt_enable();
171 
172                         err = __get_user(old, (unsigned int *) addr);
173                         err |= __put_user(new, (unsigned int *) addr);
174                         if (err)
175                                 break;
176                         rmb();
177                 } while (!ll_bit);
178         }
179 
180         if (unlikely(err))
181                 return err;
182 
183         regs = current_pt_regs();
184         regs->regs[2] = old;
185         regs->regs[7] = 0;      /* No error */
186 
187         /*
188          * Don't let your children do this ...
189          */
190         __asm__ __volatile__(
191         "       move    $29, %0                                         \n"
192         "       j       syscall_exit                                    \n"
193         : /* no outputs */
194         : "r" (regs));
195 
196         /* unreached.  Honestly.  */
197         unreachable();
198 }
199 
200 SYSCALL_DEFINE3(sysmips, long, cmd, long, arg1, long, arg2)
201 {
202         switch (cmd) {
203         case MIPS_ATOMIC_SET:
204                 return mips_atomic_set(arg1, arg2);
205 
206         case MIPS_FIXADE:
207                 if (arg1 & ~3)
208                         return -EINVAL;
209 
210                 if (arg1 & 1)
211                         set_thread_flag(TIF_FIXADE);
212                 else
213                         clear_thread_flag(TIF_FIXADE);
214                 if (arg1 & 2)
215                         set_thread_flag(TIF_LOGADE);
216                 else
217                         clear_thread_flag(TIF_LOGADE);
218 
219                 return 0;
220 
221         case FLUSH_CACHE:
222                 __flush_cache_all();
223                 return 0;
224         }
225 
226         return -EINVAL;
227 }
228 
229 /*
230  * No implemented yet ...
231  */
232 SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op)
233 {
234         return -ENOSYS;
235 }
236 
237 /*
238  * If we ever come here the user sp is bad.  Zap the process right away.
239  * Due to the bad stack signaling wouldn't work.
240  */
241 asmlinkage void bad_stack(void)
242 {
243         do_exit(SIGSEGV);
244 }
245 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp