eliminate assumption that mips syscall restart preserves r25
authorRich Felker <dalias@aerifal.cx>
Tue, 11 Sep 2012 02:43:22 +0000 (22:43 -0400)
committerRich Felker <dalias@aerifal.cx>
Tue, 11 Sep 2012 02:43:22 +0000 (22:43 -0400)
all past and current kernel versions have done so, but there seems to
be no reason it's necessary and the sentiment from everyone I've asked
has been that we should not rely on it. instead, use r7 (an argument
register) which will necessarily be preserved upon syscall restart.
however this only works for 0-3 argument syscalls, and we have to
resort to the function call for 4-argument syscalls.

arch/mips/syscall_arch.h

index f3df2dc..5890476 100644 (file)
@@ -9,53 +9,42 @@
 
 #define __asm_syscall(...) do { \
        register long r2 __asm__("$2"); \
 
 #define __asm_syscall(...) do { \
        register long r2 __asm__("$2"); \
-       register long r7 __asm__("$7"); \
        __asm__ __volatile__ ( \
        __asm__ __volatile__ ( \
-       "move $2,%2 ; syscall" \
+       "move $2,$7 ; syscall" \
        : "=&r"(r2), "=r"(r7) : __VA_ARGS__ \
        : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
        : "=&r"(r2), "=r"(r7) : __VA_ARGS__ \
        : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
-         "$14", "$15", "$24", "hi", "lo", "memory"); \
+         "$14", "$15", "$24", "$25", "hi", "lo", "memory"); \
        return r7 ? -r2 : r2; \
        } while (0)
 
 static inline long __syscall0(long n)
 {
        return r7 ? -r2 : r2; \
        } while (0)
 
 static inline long __syscall0(long n)
 {
-       register long r25 __asm__("$25") = n;
-       __asm_syscall("r"(r25));
+       register long r7 __asm__("$7") = n;
+       __asm_syscall("r"(r7));
 }
 
 static inline long __syscall1(long n, long a)
 {
 }
 
 static inline long __syscall1(long n, long a)
 {
-       register long r25 __asm__("$25") = n;
+       register long r7 __asm__("$7") = n;
        register long r4 __asm__("$4") = a;
        register long r4 __asm__("$4") = a;
-       __asm_syscall("r"(r25), "r"(r4));
+       __asm_syscall("r"(r7), "r"(r4));
 }
 
 static inline long __syscall2(long n, long a, long b)
 {
 }
 
 static inline long __syscall2(long n, long a, long b)
 {
-       register long r25 __asm__("$25") = n;
+       register long r7 __asm__("$7") = n;
        register long r4 __asm__("$4") = a;
        register long r5 __asm__("$5") = b;
        register long r4 __asm__("$4") = a;
        register long r5 __asm__("$5") = b;
-       __asm_syscall("r"(r25), "r"(r4), "r"(r5));
+       __asm_syscall("r"(r7), "r"(r4), "r"(r5));
 }
 
 static inline long __syscall3(long n, long a, long b, long c)
 {
 }
 
 static inline long __syscall3(long n, long a, long b, long c)
 {
-       register long r25 __asm__("$25") = n;
+       register long r7 __asm__("$7") = n;
        register long r4 __asm__("$4") = a;
        register long r5 __asm__("$5") = b;
        register long r6 __asm__("$6") = c;
        register long r4 __asm__("$4") = a;
        register long r5 __asm__("$5") = b;
        register long r6 __asm__("$6") = c;
-       __asm_syscall("r"(r25), "r"(r4), "r"(r5), "r"(r6));
-}
-
-static inline long __syscall4(long n, long a, long b, long c, long d)
-{
-       register long r25 __asm__("$25") = n;
-       register long r4 __asm__("$4") = a;
-       register long r5 __asm__("$5") = b;
-       register long r6 __asm__("$6") = c;
-       register long r7 __asm__("$7") = d;
-       __asm_syscall("r"(r25), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
+       __asm_syscall("r"(r7), "r"(r4), "r"(r5), "r"(r6));
 }
 
 #else
 }
 
 #else
@@ -80,13 +69,13 @@ static inline long __syscall3(long n, long a, long b, long c)
        return (__syscall)(n, a, b, c);
 }
 
        return (__syscall)(n, a, b, c);
 }
 
+#endif
+
 static inline long __syscall4(long n, long a, long b, long c, long d)
 {
        return (__syscall)(n, a, b, c, d);
 }
 
 static inline long __syscall4(long n, long a, long b, long c, long d)
 {
        return (__syscall)(n, a, b, c, d);
 }
 
-#endif
-
 static inline long __syscall5(long n, long a, long b, long c, long d, long e)
 {
        return (__syscall)(n, a, b, c, d, e);
 static inline long __syscall5(long n, long a, long b, long c, long d, long e)
 {
        return (__syscall)(n, a, b, c, d, e);