* sys_syscall patch.
@ 2002-06-24 9:07 Carsten Langgaard
2002-06-24 9:54 ` Ralf Baechle
0 siblings, 1 reply; 12+ messages in thread
From: Carsten Langgaard @ 2002-06-24 9:07 UTC (permalink / raw)
To: Ralf Baechle, linux-mips
[-- 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
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: sys_syscall patch.
2002-06-24 9:07 sys_syscall patch Carsten Langgaard
@ 2002-06-24 9:54 ` Ralf Baechle
2002-06-24 10:06 ` Carsten Langgaard
0 siblings, 1 reply; 12+ messages in thread
From: Ralf Baechle @ 2002-06-24 9:54 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: linux-mips
On Mon, Jun 24, 2002 at 11:07:24AM +0200, Carsten Langgaard wrote:
> 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).
> +/*
> + * Do the indirect syscall syscall.
> + * Don't care about kernel locking; the actual syscall will do it.
> + *
> + * XXX This is broken.
> + */
As the comment says - it's broken. This implementation just like it's
32-bit predecessor don't handle the error return value correctly. Worse,
there's unprotected accesses to userspace which allow any user crashing
the system ...
Ralf
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sys_syscall patch.
2002-06-24 9:54 ` Ralf Baechle
@ 2002-06-24 10:06 ` Carsten Langgaard
2002-06-24 10:24 ` Ralf Baechle
0 siblings, 1 reply; 12+ messages in thread
From: Carsten Langgaard @ 2002-06-24 10:06 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Ralf Baechle wrote:
> On Mon, Jun 24, 2002 at 11:07:24AM +0200, Carsten Langgaard wrote:
>
> > 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).
>
> > +/*
> > + * Do the indirect syscall syscall.
> > + * Don't care about kernel locking; the actual syscall will do it.
> > + *
> > + * XXX This is broken.
> > + */
>
> As the comment says - it's broken. This implementation just like it's
> 32-bit predecessor don't handle the error return value correctly. Worse,
> there's unprotected accesses to userspace which allow any user crashing
> the system ...
>
At least it makes my system work as well as for the 32-bit kernel.
--
_ _ ____ ___ 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
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: sys_syscall patch.
2002-06-24 10:06 ` Carsten Langgaard
@ 2002-06-24 10:24 ` Ralf Baechle
2002-06-24 10:46 ` Carsten Langgaard
0 siblings, 1 reply; 12+ messages in thread
From: Ralf Baechle @ 2002-06-24 10:24 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: linux-mips
On Mon, Jun 24, 2002 at 12:06:52PM +0200, Carsten Langgaard wrote:
>
> At least it makes my system work as well as for the 32-bit kernel.
What programs btw are using syscall()? To be honest I don't recall one ...
Looking more into it I found a nice showstopper - a few functions like
_sys_sigsuspend() expect a struct pt_regs on the stack. That's only
working if we call those functions directly from the exception handler.
It won't work if we have another function's stackframe - in this case
sys_syscall()'s there also ...
Ralf
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sys_syscall patch.
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 12:02 ` Ralf Baechle
0 siblings, 2 replies; 12+ messages in thread
From: Carsten Langgaard @ 2002-06-24 10:46 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips
Ralf Baechle wrote:
> On Mon, Jun 24, 2002 at 12:06:52PM +0200, Carsten Langgaard wrote:
>
> >
> > At least it makes my system work as well as for the 32-bit kernel.
>
> What programs btw are using syscall()? To be honest I don't recall one ...
/sbin/rpc.lockd.
It use syscall() to indirectly call the 'sys_nfsservctl' syscall, why it
doesn't do the syscall directly is beyond me.
>
> Looking more into it I found a nice showstopper - a few functions like
> _sys_sigsuspend() expect a struct pt_regs on the stack. That's only
> working if we call those functions directly from the exception handler.
> It won't work if we have another function's stackframe - in this case
> sys_syscall()'s there also ...
>
> Ralf
--
_ _ ____ ___ 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
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: sys_syscall patch.
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 12:02 ` Kevin D. Kissell
2002-06-24 12:02 ` Ralf Baechle
1 sibling, 2 replies; 12+ messages in thread
From: Maciej W. Rozycki @ 2002-06-24 11:38 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: Ralf Baechle, linux-mips
On Mon, 24 Jun 2002, Carsten Langgaard wrote:
> > What programs btw are using syscall()? To be honest I don't recall one ...
>
> /sbin/rpc.lockd.
> It use syscall() to indirectly call the 'sys_nfsservctl' syscall, why it
> doesn't do the syscall directly is beyond me.
Hmm, shouldn't syscall() be a library wrapper? I think we should kill
sys_syscall().
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sys_syscall patch.
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
1 sibling, 1 reply; 12+ messages in thread
From: Ralf Baechle @ 2002-06-24 11:45 UTC (permalink / raw)
To: Maciej W. Rozycki; +Cc: Carsten Langgaard, linux-mips
On Mon, Jun 24, 2002 at 01:38:27PM +0200, Maciej W. Rozycki wrote:
> > > What programs btw are using syscall()? To be honest I don't recall one ...
> >
> > /sbin/rpc.lockd.
> > It use syscall() to indirectly call the 'sys_nfsservctl' syscall, why it
> > doesn't do the syscall directly is beyond me.
>
> Hmm, shouldn't syscall() be a library wrapper? I think we should kill
> sys_syscall().
It's in the kernel for no better reason than Risc/OS and IRIX having this
syscall. Also the glibc syscall implementation was historically broken
wrt. syscall restarting and a few other subtilities.
Ralf
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sys_syscall patch.
2002-06-24 11:45 ` Ralf Baechle
@ 2002-06-24 14:49 ` Maciej W. Rozycki
0 siblings, 0 replies; 12+ messages in thread
From: Maciej W. Rozycki @ 2002-06-24 14:49 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Carsten Langgaard, linux-mips
On Mon, 24 Jun 2002, Ralf Baechle wrote:
> It's in the kernel for no better reason than Risc/OS and IRIX having this
> syscall. Also the glibc syscall implementation was historically broken
> wrt. syscall restarting and a few other subtilities.
Well, userland implementations for other archs seem quite
straightforward. So should be ours -- we only have to shuffle arguments
appropriately. Restarting is easy -- we just have to make sure to reload
v0 just before "syscall" reliably (we can use a static register or an
automatic variable to preserve it). What are the few other subtleties?
Also I can't see an implementation of syscall() for MIPS/Linux anywhere
in glibc. What implementation do you refer to? The Mach one?
The win is we don't have to mess with user accesses specially -- the
final syscall will handle them.
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sys_syscall patch.
2002-06-24 11:38 ` Maciej W. Rozycki
2002-06-24 11:45 ` Ralf Baechle
@ 2002-06-24 12:02 ` Kevin D. Kissell
2002-06-24 12:02 ` Kevin D. Kissell
2002-06-24 12:04 ` Ralf Baechle
1 sibling, 2 replies; 12+ messages in thread
From: Kevin D. Kissell @ 2002-06-24 12:02 UTC (permalink / raw)
To: Maciej W. Rozycki, Carsten Langgaard; +Cc: Ralf Baechle, linux-mips
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
> On Mon, 24 Jun 2002, Carsten Langgaard wrote:
>
> > > What programs btw are using syscall()? To be honest I don't recall one ...
> >
> > /sbin/rpc.lockd.
> > It use syscall() to indirectly call the 'sys_nfsservctl' syscall, why it
> > doesn't do the syscall directly is beyond me.
I can only speculate that at the time it was written, there was not
a universally respected library binding to get to the direct syscall.
> Hmm, shouldn't syscall() be a library wrapper? I think we should kill
> sys_syscall().
While I agree that rpc.lockd should directly invoke the desired
system call if possible, having an indirect system call mechanism
is something that has proved useful to me in the past on other
Unices, and I would rather see it fixed than discarded.
Kevin K.
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: sys_syscall patch.
2002-06-24 12:02 ` Kevin D. Kissell
@ 2002-06-24 12:02 ` Kevin D. Kissell
2002-06-24 12:04 ` Ralf Baechle
1 sibling, 0 replies; 12+ messages in thread
From: Kevin D. Kissell @ 2002-06-24 12:02 UTC (permalink / raw)
To: Maciej W. Rozycki, Carsten Langgaard; +Cc: Ralf Baechle, linux-mips
From: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>
> On Mon, 24 Jun 2002, Carsten Langgaard wrote:
>
> > > What programs btw are using syscall()? To be honest I don't recall one ...
> >
> > /sbin/rpc.lockd.
> > It use syscall() to indirectly call the 'sys_nfsservctl' syscall, why it
> > doesn't do the syscall directly is beyond me.
I can only speculate that at the time it was written, there was not
a universally respected library binding to get to the direct syscall.
> Hmm, shouldn't syscall() be a library wrapper? I think we should kill
> sys_syscall().
While I agree that rpc.lockd should directly invoke the desired
system call if possible, having an indirect system call mechanism
is something that has proved useful to me in the past on other
Unices, and I would rather see it fixed than discarded.
Kevin K.
^ permalink raw reply [flat|nested] 12+ messages in thread* Re: sys_syscall patch.
2002-06-24 12:02 ` Kevin D. Kissell
2002-06-24 12:02 ` Kevin D. Kissell
@ 2002-06-24 12:04 ` Ralf Baechle
1 sibling, 0 replies; 12+ messages in thread
From: Ralf Baechle @ 2002-06-24 12:04 UTC (permalink / raw)
To: Kevin D. Kissell; +Cc: Maciej W. Rozycki, Carsten Langgaard, linux-mips
On Mon, Jun 24, 2002 at 02:02:49PM +0200, Kevin D. Kissell wrote:
> While I agree that rpc.lockd should directly invoke the desired
> system call if possible, having an indirect system call mechanism
> is something that has proved useful to me in the past on other
> Unices, and I would rather see it fixed than discarded.
The question is not wheather to drop this mechnism - we can't anyway for
compatibility reasons - but if a kernel or userspace implementation is
preferable for the future.
Ralf
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: sys_syscall patch.
2002-06-24 10:46 ` Carsten Langgaard
2002-06-24 11:38 ` Maciej W. Rozycki
@ 2002-06-24 12:02 ` Ralf Baechle
1 sibling, 0 replies; 12+ messages in thread
From: Ralf Baechle @ 2002-06-24 12:02 UTC (permalink / raw)
To: Carsten Langgaard; +Cc: linux-mips
On Mon, Jun 24, 2002 at 12:46:41PM +0200, Carsten Langgaard wrote:
> > > At least it makes my system work as well as for the 32-bit kernel.
> >
> > What programs btw are using syscall()? To be honest I don't recall one ...
>
> /sbin/rpc.lockd.
> It use syscall() to indirectly call the 'sys_nfsservctl' syscall, why it
> doesn't do the syscall directly is beyond me.
More historic garbage - the kernel NFS server for a long time didn't
have it's own, registered syscall.
Ralf
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2002-06-24 14:45 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-06-24 9:07 sys_syscall patch Carsten Langgaard
2002-06-24 9:54 ` 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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox