Update of /cvsroot/linux-mips/linux/arch/mips/kernel
In directory usw-pr-cvs1:/tmp/cvs-serv31603/arch/mips/kernel
Modified Files:
sysmips.c
Log Message:
Revert sysmips changes.
Index: sysmips.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/arch/mips/kernel/sysmips.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- sysmips.c 2001/09/25 03:36:35 1.7
+++ sysmips.c 2001/09/26 03:18:54 1.8
@@ -50,9 +50,8 @@
asmlinkage int
sys_sysmips(int cmd, int arg1, int arg2, int arg3)
{
- int *p;
char *name;
- int tmp, len, retval, errno;
+ int tmp, len, retval;
switch(cmd) {
case SETNAME: {
@@ -75,53 +74,83 @@
}
case MIPS_ATOMIC_SET: {
+ int *ptr, val, ret, err, tmp;
+ struct siginfo info;
+
+ ptr = (int *)arg1;
+ val = (int)arg2;
+
+ /* Don't emulate unaligned accesses. */
+ if ((int)ptr & 3) {
+ info.si_signo = SIGBUS;
+ info.si_code = BUS_ADRALN;
+ goto fault;
+ }
+
+ /* A zero here saves us three instructions. */
+ err = verify_area(VERIFY_WRITE, ptr, 0);
+ if (err) {
+ info.si_signo = SIGSEGV;
+ info.si_code = SEGV_ACCERR;
+ goto fault;
+ }
+
#ifdef CONFIG_CPU_HAS_LLSC
- unsigned int tmp;
+ __asm__(".set mips2\n\t"
+ "1:\n\t"
+ "ll %0,%5\n\t"
+ ".set push\n\t"
+ ".set noreorder\n\t"
+ "beq %0,%4,3f\n\t"
+ " move %3,%4\n"
+ ".set pop\n\t"
+ "2:\n\t"
+ "sc %3,%1\n\t"
+ "beqz %3,1b\n\t"
+ "3:\n\t"
+ ".set mips0\n\t"
+ ".section .fixup,\"ax\"\n"
+ "4:\n\t"
+ "li %2,%7\n\t"
+ "j 3b\n\t"
+ ".previous\n\t"
+ ".section __ex_table,\"a\"\n\t"
+ ".word 1b,4b\n\t"
+ ".word 2b,4b\n\t"
+ ".previous"
+ : "=&r" (ret), "=m" (*ptr), "=r" (err), "=&r" (tmp)
+ : "r" (val), "1" (*ptr), "2" (0), "i" (-EFAULT));
+#else
+ save_and_cli(tmp);
+ err = __get_user(ret, ptr);
+ if (ret != val)
+ err |= __put_user(val, ptr); /* No fault
+ unless unwriteable. */
+ restore_flags(tmp);
+#endif
- p = (int *) arg1;
- errno = verify_area(VERIFY_WRITE, p, sizeof(*p));
- if (errno)
- return errno;
- errno = 0;
+ if (err) {
+ info.si_signo = SIGSEGV;
+ info.si_code = SEGV_MAPERR;
+ goto fault;
+ }
- __asm__(".set\tpush\t\t\t# sysmips(MIPS_ATOMIC, ...)\n\t"
- ".set\tmips2\n\t"
- ".set\tnoat\n\t"
- "1:\tll\t%0, %4\n\t"
- "move\t$1, %3\n\t"
- "2:\tsc\t$1, %1\n\t"
- "beqz\t$1, 1b\n\t"
- ".set\tpop\n\t"
- ".section\t.fixup,\"ax\"\n"
- "3:\tli\t%2, 1\t\t\t# error\n\t"
- ".previous\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- ".word\t1b, 3b\n\t"
- ".word\t2b, 3b\n\t"
- ".previous\n\t"
- : "=&r" (tmp), "=o" (* (u32 *) p), "=r" (errno)
- : "r" (arg2), "o" (* (u32 *) p), "2" (errno)
- : "$1");
+ if ( (ret < 0) && (ret >= -EMAXERRNO) ) {
+ info.si_signo = SIGSYS;
+ info.si_code = 0;
+ goto fault;
+ }
- if (errno)
- return -EFAULT;
+ return ret;
- /* We're skipping error handling etc. */
- if (current->ptrace & PT_TRACESYS)
- syscall_trace();
+fault:
+ /* Go back to SYSCALL. */
+ ((struct pt_regs *)&cmd)->cp0_epc -= 4;
- ((struct pt_regs *)&cmd)->regs[2] = tmp;
- ((struct pt_regs *)&cmd)->regs[7] = 0;
+ info.si_addr = (void *)((struct pt_regs *)&cmd)->cp0_epc;
+ force_sig_info(info.si_signo, &info, current);
- __asm__ __volatile__(
- "move\t$29, %0\n\t"
- "j\to32_ret_from_sys_call"
- : /* No outputs */
- : "r" (&cmd));
- /* Unreached */
-#else
- printk("sys_sysmips(MIPS_ATOMIC_SET, ...) not ready for !CONFIG_CPU_HAS_LLSC\n");
-#endif
+ return 0;
}
case MIPS_FIXADE:
|