From: Carsten Langgaard <carstenl@mips.com>
To: Ralf Baechle <ralf@oss.sgi.com>, linux-mips@oss.sgi.com
Subject: sys_syscall patch.
Date: Mon, 24 Jun 2002 11:07:24 +0200 [thread overview]
Message-ID: <3D16E14C.5C8D2FAD@mips.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 529 bytes --]
The 'sys_syscall' syscall isn't properly implemented in the 64-bit
kernel (for o32 as well as n64).
Below is a patch, it seems to work for in the o32 case, but I haven't
tested the n64 version (obviously).
/Carsten
--
_ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com
|\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527
| \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555
TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556
Denmark http://www.mips.com
[-- Attachment #2: sys_syscall.patch --]
[-- Type: text/plain, Size: 5686 bytes --]
Index: arch/mips64/kernel//linux32.c
===================================================================
RCS file: /home/repository/sw/linux-2.4.18/arch/mips64/kernel/linux32.c,v
retrieving revision 1.3
diff -u -r1.3 linux32.c
--- arch/mips64/kernel//linux32.c 13 Jun 2002 09:08:02 -0000 1.3
+++ arch/mips64/kernel//linux32.c 24 Jun 2002 08:56:02 -0000
@@ -32,6 +32,7 @@
#include <asm/uaccess.h>
#include <asm/mman.h>
#include <asm/ipc.h>
+#include <asm/unistd.h>
#define A(__x) ((unsigned long)(__x))
@@ -872,6 +873,82 @@
oldalarm++;
return oldalarm;
+}
+
+typedef asmlinkage long (*syscall_t)(void *a0,...);
+extern syscall_t sys32_call_table[];
+extern unsigned char sys32_narg_table[];
+
+/*
+ * Do the indirect syscall syscall.
+ * Don't care about kernel locking; the actual syscall will do it.
+ *
+ * XXX This is broken.
+ */
+asmlinkage int sys32_syscall(abi64_no_regargs, struct pt_regs regs)
+{
+ syscall_t syscall;
+ unsigned long syscallnr = regs.regs[4];
+ unsigned long a0, a1, a2, a3, a4, a5, a6;
+ int nargs, errno;
+
+ if ((syscallnr < __NR_Linux32) ||
+ (syscallnr > __NR_Linux32 + __NR_Linux32_syscalls))
+ return -ENOSYS;
+
+ syscall = sys32_call_table[syscallnr-__NR_Linux32];
+ nargs = sys32_narg_table[syscallnr-__NR_Linux32];
+
+ /*
+ * Prevent stack overflow by recursive
+ * syscall(__NR_syscall, __NR_syscall,...);
+ */
+ if (syscall == (syscall_t) sys32_syscall) {
+ return -EINVAL;
+ }
+
+ if (syscall == NULL) {
+ return -ENOSYS;
+ }
+
+ if(nargs > 3) {
+ unsigned long usp = regs.regs[29];
+ unsigned long *sp = (unsigned long *) usp;
+ if(usp & 3) {
+ printk("unaligned usp -EFAULT\n");
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+ }
+ errno = verify_area(VERIFY_READ, (void *) (usp + 16),
+ (nargs - 3) * sizeof(unsigned long));
+ if(errno) {
+ return -EFAULT;
+ }
+ switch(nargs) {
+ case 7:
+ a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = sp[7];
+ break;
+ case 6:
+ a3 = sp[4]; a4 = sp[5]; a5 = sp[6]; a6 = 0;
+ break;
+ case 5:
+ a3 = sp[4]; a4 = sp[5]; a5 = a6 = 0;
+ break;
+ case 4:
+ a3 = sp[4]; a4 = a5 = a6 = 0;
+ break;
+
+ default:
+ a3 = a4 = a5 = a6 = 0;
+ break;
+ }
+ } else {
+ a3 = a4 = a5 = a6 = 0;
+ }
+ a0 = regs.regs[5]; a1 = regs.regs[6]; a2 = regs.regs[7];
+ if(nargs == 0)
+ a0 = (unsigned long) ®s;
+ return syscall((void *)a0, a1, a2, a3, a4, a5, a6);
}
/* Translations due to time_t size differences. Which affects all
Index: arch/mips64/kernel//scall_64.S
===================================================================
RCS file: /home/repository/sw/linux-2.4.18/arch/mips64/kernel/scall_64.S,v
retrieving revision 1.3
diff -u -r1.3 scall_64.S
--- arch/mips64/kernel//scall_64.S 19 Jun 2002 07:04:08 -0000 1.3
+++ arch/mips64/kernel//scall_64.S 24 Jun 2002 08:10:23 -0000
@@ -132,7 +132,7 @@
j ret_from_sys_call
END(handle_sys64)
-sys_call_table:
+EXPORT(sys_call_table)
PTR sys_syscall /* 5000 */
PTR sys_exit
PTR sys_fork
Index: arch/mips64/kernel//scall_o32.S
===================================================================
RCS file: /home/repository/sw/linux-2.4.18/arch/mips64/kernel/scall_o32.S,v
retrieving revision 1.3
diff -u -r1.3 scall_o32.S
--- arch/mips64/kernel//scall_o32.S 19 Jun 2002 07:04:08 -0000 1.3
+++ arch/mips64/kernel//scall_o32.S 24 Jun 2002 08:53:48 -0000
@@ -52,8 +52,8 @@
/* XXX Put both in one cacheline, should save a bit. */
dsll t0, v0, 3 # offset into table
- ld t2, (sys_call_table - (__NR_Linux32 * 8))(t0) # syscall routine
- lbu t3, (sys_narg_table - __NR_Linux32)(v0) # number of arguments
+ ld t2, (sys32_call_table - (__NR_Linux32 * 8))(t0) # syscall routine
+ lbu t3, (sys32_narg_table - __NR_Linux32)(v0) # number of arguments
subu t0, t3, 5 # 5 or more arguments?
sd a3, PT_R26(sp) # save a3 for syscall restarting
@@ -246,7 +246,7 @@
END(sys_sysmips)
.macro syscalltable
- sys sys_syscall 0 /* 4000 */
+ sys sys32_syscall 0 /* 4000 */
sys sys_exit 1
sys sys_fork 0
sys sys_read 3
@@ -489,12 +489,12 @@
PTR \function
.endm
-sys_call_table:
+EXPORT(sys32_call_table)
syscalltable
.macro sys function, nargs
.byte \nargs
.endm
-
-sys_narg_table:
+
+EXPORT(sys32_narg_table)
syscalltable
Index: arch/mips64/kernel//syscall.c
===================================================================
RCS file: /home/repository/sw/linux-2.4.18/arch/mips64/kernel/syscall.c,v
retrieving revision 1.2
diff -u -r1.2 syscall.c
--- arch/mips64/kernel//syscall.c 13 Jun 2002 09:08:02 -0000 1.2
+++ arch/mips64/kernel//syscall.c 24 Jun 2002 08:38:55 -0000
@@ -123,14 +123,41 @@
return error;
}
+typedef asmlinkage long (*syscall_t)(void *a0,...);
+extern syscall_t sys_call_table[];
+
/*
* Do the indirect syscall syscall.
- *
- * XXX This is borken.
+ * Don't care about kernel locking; the actual syscall will do it.
*/
asmlinkage int sys_syscall(abi64_no_regargs, struct pt_regs regs)
{
- return -ENOSYS;
+ syscall_t syscall;
+ unsigned long syscallnr = regs.regs[4];
+ unsigned long a0, a1, a2, a3, a4, a5, a6;
+
+ if ((syscallnr < __NR_Linux) ||
+ (syscallnr > __NR_Linux + __NR_Linux_syscalls))
+ return -ENOSYS;
+
+ syscall = sys_call_table[syscallnr-__NR_Linux];
+
+ /*
+ * Prevent stack overflow by recursive
+ * syscall(__NR_syscall, __NR_syscall,...);
+ */
+ if (syscall == (syscall_t) sys_syscall) {
+ return -EINVAL;
+ }
+
+ if (syscall == NULL) {
+ return -ENOSYS;
+ }
+
+ a0 = regs.regs[5]; a1 = regs.regs[6]; a2 = regs.regs[7];
+ a3 = regs.regs[8]; a4 = regs.regs[9]; a5 = regs.regs[10];
+ a6 = regs.regs[11];
+ return syscall((void *)a0, a1, a2, a3, a4, a5, a6);
}
asmlinkage int
next reply other threads:[~2002-06-24 9:04 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-06-24 9:07 Carsten Langgaard [this message]
2002-06-24 9:54 ` sys_syscall patch Ralf Baechle
2002-06-24 10:06 ` Carsten Langgaard
2002-06-24 10:24 ` Ralf Baechle
2002-06-24 10:46 ` Carsten Langgaard
2002-06-24 11:38 ` Maciej W. Rozycki
2002-06-24 11:45 ` Ralf Baechle
2002-06-24 14:49 ` Maciej W. Rozycki
2002-06-24 12:02 ` Kevin D. Kissell
2002-06-24 12:02 ` Kevin D. Kissell
2002-06-24 12:04 ` Ralf Baechle
2002-06-24 12:02 ` Ralf Baechle
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3D16E14C.5C8D2FAD@mips.com \
--to=carstenl@mips.com \
--cc=linux-mips@oss.sgi.com \
--cc=ralf@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox