0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/capability.h>
0011 #include <linux/errno.h>
0012 #include <linux/linkage.h>
0013 #include <linux/fs.h>
0014 #include <linux/smp.h>
0015 #include <linux/ptrace.h>
0016 #include <linux/string.h>
0017 #include <linux/syscalls.h>
0018 #include <linux/file.h>
0019 #include <linux/utsname.h>
0020 #include <linux/unistd.h>
0021 #include <linux/sem.h>
0022 #include <linux/msg.h>
0023 #include <linux/shm.h>
0024 #include <linux/compiler.h>
0025 #include <linux/ipc.h>
0026 #include <linux/uaccess.h>
0027 #include <linux/slab.h>
0028 #include <linux/elf.h>
0029 #include <linux/sched/task_stack.h>
0030
0031 #include <asm/asm.h>
0032 #include <asm/asm-eva.h>
0033 #include <asm/branch.h>
0034 #include <asm/cachectl.h>
0035 #include <asm/cacheflush.h>
0036 #include <asm/asm-offsets.h>
0037 #include <asm/signal.h>
0038 #include <asm/sim.h>
0039 #include <asm/shmparam.h>
0040 #include <asm/sync.h>
0041 #include <asm/sysmips.h>
0042 #include <asm/switch_to.h>
0043
0044
0045
0046
0047
0048
0049
0050
0051 asmlinkage int sysm_pipe(void)
0052 {
0053 int fd[2];
0054 int error = do_pipe_flags(fd, 0);
0055 if (error)
0056 return error;
0057 current_pt_regs()->regs[3] = fd[1];
0058 return fd[0];
0059 }
0060
0061 SYSCALL_DEFINE6(mips_mmap, unsigned long, addr, unsigned long, len,
0062 unsigned long, prot, unsigned long, flags, unsigned long,
0063 fd, off_t, offset)
0064 {
0065 if (offset & ~PAGE_MASK)
0066 return -EINVAL;
0067 return ksys_mmap_pgoff(addr, len, prot, flags, fd,
0068 offset >> PAGE_SHIFT);
0069 }
0070
0071 SYSCALL_DEFINE6(mips_mmap2, unsigned long, addr, unsigned long, len,
0072 unsigned long, prot, unsigned long, flags, unsigned long, fd,
0073 unsigned long, pgoff)
0074 {
0075 if (pgoff & (~PAGE_MASK >> 12))
0076 return -EINVAL;
0077
0078 return ksys_mmap_pgoff(addr, len, prot, flags, fd,
0079 pgoff >> (PAGE_SHIFT - 12));
0080 }
0081
0082 save_static_function(sys_fork);
0083 save_static_function(sys_clone);
0084 save_static_function(sys_clone3);
0085
0086 SYSCALL_DEFINE1(set_thread_area, unsigned long, addr)
0087 {
0088 struct thread_info *ti = task_thread_info(current);
0089
0090 ti->tp_value = addr;
0091 if (cpu_has_userlocal)
0092 write_c0_userlocal(addr);
0093
0094 return 0;
0095 }
0096
0097 static inline int mips_atomic_set(unsigned long addr, unsigned long new)
0098 {
0099 unsigned long old, tmp;
0100 struct pt_regs *regs;
0101 unsigned int err;
0102
0103 if (unlikely(addr & 3))
0104 return -EINVAL;
0105
0106 if (unlikely(!access_ok((const void __user *)addr, 4)))
0107 return -EINVAL;
0108
0109 if (cpu_has_llsc && IS_ENABLED(CONFIG_WAR_R10000_LLSC)) {
0110 __asm__ __volatile__ (
0111 " .set push \n"
0112 " .set arch=r4000 \n"
0113 " li %[err], 0 \n"
0114 "1: ll %[old], (%[addr]) \n"
0115 " move %[tmp], %[new] \n"
0116 "2: sc %[tmp], (%[addr]) \n"
0117 " beqzl %[tmp], 1b \n"
0118 "3: \n"
0119 " .insn \n"
0120 " .section .fixup,\"ax\" \n"
0121 "4: li %[err], %[efault] \n"
0122 " j 3b \n"
0123 " .previous \n"
0124 " .section __ex_table,\"a\" \n"
0125 " "STR(PTR_WD)" 1b, 4b \n"
0126 " "STR(PTR_WD)" 2b, 4b \n"
0127 " .previous \n"
0128 " .set pop \n"
0129 : [old] "=&r" (old),
0130 [err] "=&r" (err),
0131 [tmp] "=&r" (tmp)
0132 : [addr] "r" (addr),
0133 [new] "r" (new),
0134 [efault] "i" (-EFAULT)
0135 : "memory");
0136 } else if (cpu_has_llsc) {
0137 __asm__ __volatile__ (
0138 " .set push \n"
0139 " .set "MIPS_ISA_ARCH_LEVEL" \n"
0140 " li %[err], 0 \n"
0141 "1: \n"
0142 " " __SYNC(full, loongson3_war) " \n"
0143 user_ll("%[old]", "(%[addr])")
0144 " move %[tmp], %[new] \n"
0145 "2: \n"
0146 user_sc("%[tmp]", "(%[addr])")
0147 " beqz %[tmp], 1b \n"
0148 "3: \n"
0149 " .insn \n"
0150 " .section .fixup,\"ax\" \n"
0151 "5: li %[err], %[efault] \n"
0152 " j 3b \n"
0153 " .previous \n"
0154 " .section __ex_table,\"a\" \n"
0155 " "STR(PTR_WD)" 1b, 5b \n"
0156 " "STR(PTR_WD)" 2b, 5b \n"
0157 " .previous \n"
0158 " .set pop \n"
0159 : [old] "=&r" (old),
0160 [err] "=&r" (err),
0161 [tmp] "=&r" (tmp)
0162 : [addr] "r" (addr),
0163 [new] "r" (new),
0164 [efault] "i" (-EFAULT)
0165 : "memory");
0166 } else {
0167 do {
0168 preempt_disable();
0169 ll_bit = 1;
0170 ll_task = current;
0171 preempt_enable();
0172
0173 err = __get_user(old, (unsigned int *) addr);
0174 err |= __put_user(new, (unsigned int *) addr);
0175 if (err)
0176 break;
0177 rmb();
0178 } while (!ll_bit);
0179 }
0180
0181 if (unlikely(err))
0182 return err;
0183
0184 regs = current_pt_regs();
0185 regs->regs[2] = old;
0186 regs->regs[7] = 0;
0187
0188
0189
0190
0191 __asm__ __volatile__(
0192 " move $29, %0 \n"
0193 " j syscall_exit \n"
0194 :
0195 : "r" (regs));
0196
0197
0198 unreachable();
0199 }
0200
0201
0202
0203
0204
0205 save_static_function(sys_sysmips);
0206
0207 SYSCALL_DEFINE3(sysmips, long, cmd, long, arg1, long, arg2)
0208 {
0209 switch (cmd) {
0210 case MIPS_ATOMIC_SET:
0211 return mips_atomic_set(arg1, arg2);
0212
0213 case MIPS_FIXADE:
0214 if (arg1 & ~3)
0215 return -EINVAL;
0216
0217 if (arg1 & 1)
0218 set_thread_flag(TIF_FIXADE);
0219 else
0220 clear_thread_flag(TIF_FIXADE);
0221 if (arg1 & 2)
0222 set_thread_flag(TIF_LOGADE);
0223 else
0224 clear_thread_flag(TIF_LOGADE);
0225
0226 return 0;
0227
0228 case FLUSH_CACHE:
0229 __flush_cache_all();
0230 return 0;
0231 }
0232
0233 return -EINVAL;
0234 }
0235
0236
0237
0238
0239 SYSCALL_DEFINE3(cachectl, char *, addr, int, nbytes, int, op)
0240 {
0241 return -ENOSYS;
0242 }