From effaa7824da1af4db5cef50c78079d4c4e1717a7 Mon Sep 17 00:00:00 2001 From: Chris Dearman Date: Wed, 13 Nov 2013 14:15:31 -0800 Subject: [PATCH] [MIPS] Reimplement syscall to invoke the system call directly Some MIPS kernels do not correctly restart interrupted system calls that have been invoked using the indirect syscall (NR_syscall). The simplest workaround is to handle the indirection in userland and then call the required system call directly. Change-Id: I8385399621529db9a52b463c96925f6decaaca30 --- libc/SYSCALLS.TXT | 1 - libc/arch-mips/bionic/syscall.S | 57 +++++++++++++++++++++++++++++++ libc/arch-mips/mips.mk | 1 + libc/arch-mips/syscalls.mk | 1 - libc/arch-mips/syscalls/syscall.S | 23 ------------- 5 files changed, 58 insertions(+), 25 deletions(-) create mode 100644 libc/arch-mips/bionic/syscall.S delete mode 100644 libc/arch-mips/syscalls/syscall.S diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 7c1529722..533116e60 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -304,4 +304,3 @@ int cacheflush:__ARM_NR_cacheflush(long start, long end, long flags) arm # MIPS-specific int _flush_cache:cacheflush(char* addr, const int nbytes, const int op) mips -int syscall(int number, ...) mips diff --git a/libc/arch-mips/bionic/syscall.S b/libc/arch-mips/bionic/syscall.S new file mode 100644 index 000000000..60754e82e --- /dev/null +++ b/libc/arch-mips/bionic/syscall.S @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + .text + .globl syscall + .align 4 + .ent syscall + +syscall: + .set noreorder + .cpload $t9 + move $v0, $a0 + move $a0, $a1 + move $a1, $a2 + move $a2, $a3 + lw $a3, 16($sp) + lw $t0, 20($sp) + lw $t1, 24($sp) + sw $t0, 16($sp) + sw $t1, 20($sp) + syscall + bnez $a3, 1f + move $a0, $v0 + j $ra + nop +1: + la $t9,__set_errno + j $t9 + nop + .set reorder + .end syscall diff --git a/libc/arch-mips/mips.mk b/libc/arch-mips/mips.mk index 3ebedd01d..c8953576b 100644 --- a/libc/arch-mips/mips.mk +++ b/libc/arch-mips/mips.mk @@ -11,6 +11,7 @@ _LIBC_ARCH_COMMON_SRC_FILES := \ arch-mips/bionic/setjmp.S \ arch-mips/bionic/__set_tls.c \ arch-mips/bionic/sigsetjmp.S \ + arch-mips/bionic/syscall.S \ arch-mips/bionic/vfork.S \ arch-mips/string/memcpy.S \ arch-mips/string/memset.S \ diff --git a/libc/arch-mips/syscalls.mk b/libc/arch-mips/syscalls.mk index 9be619712..e141a6596 100644 --- a/libc/arch-mips/syscalls.mk +++ b/libc/arch-mips/syscalls.mk @@ -175,7 +175,6 @@ syscall_src += arch-mips/syscalls/swapoff.S syscall_src += arch-mips/syscalls/swapon.S syscall_src += arch-mips/syscalls/symlinkat.S syscall_src += arch-mips/syscalls/sync.S -syscall_src += arch-mips/syscalls/syscall.S syscall_src += arch-mips/syscalls/sysinfo.S syscall_src += arch-mips/syscalls/tgkill.S syscall_src += arch-mips/syscalls/timerfd_create.S diff --git a/libc/arch-mips/syscalls/syscall.S b/libc/arch-mips/syscalls/syscall.S deleted file mode 100644 index 2b2b7077e..000000000 --- a/libc/arch-mips/syscalls/syscall.S +++ /dev/null @@ -1,23 +0,0 @@ -/* Generated by gensyscalls.py. Do not edit. */ - -#include - .text - .globl syscall - .align 4 - .ent syscall - -syscall: - .set noreorder - .cpload $t9 - li $v0, __NR_syscall - syscall - bnez $a3, 1f - move $a0, $v0 - j $ra - nop -1: - la $t9,__set_errno - j $t9 - nop - .set reorder - .end syscall