From: Paul M. <le...@us...> - 2001-09-26 03:18:57
|
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: |