[parisc-linux-cvs] linux-2.6 tausq
Randolph Chung
Randolph Chung <randolph@tausq.org>
Sat, 1 Nov 2003 20:51:50 -0800
In reference to a message from Randolph Chung, dated Nov 01:
> CVSROOT: /var/cvs
> Module name: linux-2.6
> Changes by: tausq 03/11/01 21:40:50
>
> Modified files:
> . : Makefile
> arch/parisc/kernel: syscall_table.S signal.c
> include/asm-parisc: unistd.h
>
> Log message:
> 2.6.0-test9-pa4
> Support for restarting syscalls via the restart block
Index: arch/parisc/kernel/syscall_table.S
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/syscall_table.S,v
retrieving revision 1.1
diff -u -p -r1.1 syscall_table.S
--- arch/parisc/kernel/syscall_table.S 21 Sep 2003 14:33:58 -0000 1.1
+++ arch/parisc/kernel/syscall_table.S 2 Nov 2003 04:39:23 -0000
@@ -28,7 +28,7 @@
#define ENTRY_COMP(_name_) .word sys_##_name_
#endif
- ENTRY_SAME(ni_syscall) /* 0 - old "setup()" system call*/
+ ENTRY_SAME(restart_syscall) /* 0 */
ENTRY_SAME(exit)
ENTRY_SAME(fork_wrapper)
ENTRY_SAME(read)
Index: arch/parisc/kernel/signal.c
===================================================================
RCS file: /var/cvs/linux-2.6/arch/parisc/kernel/signal.c,v
retrieving revision 1.11
diff -u -p -r1.11 signal.c
--- arch/parisc/kernel/signal.c 24 Sep 2003 17:54:31 -0000 1.11
+++ arch/parisc/kernel/signal.c 2 Nov 2003 04:39:24 -0000
@@ -486,6 +486,7 @@ do_signal(sigset_t *oldset, struct pt_re
signr = get_signal_to_deliver(&info, regs, NULL);
+ /* printk("do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); */
if (signr > 0) {
/* Restart a system call if necessary. */
if (in_syscall) {
@@ -530,10 +531,42 @@ do_signal(sigset_t *oldset, struct pt_re
/* Did we come from a system call? */
if (in_syscall) {
/* Restart the system call - no handlers present */
- if (regs->gr[28] == -ERESTART_RESTARTBLOCK ||
- regs->gr[28] == -ERESTARTNOHAND ||
- regs->gr[28] == -ERESTARTSYS ||
- regs->gr[28] == -ERESTARTNOINTR) {
+ if (regs->gr[28] == -ERESTART_RESTARTBLOCK) {
+ unsigned int *usp = (unsigned int *)regs->gr[30];
+
+ /* Setup a trampoline to restart the syscall
+ * with __NR_restart_syscall
+ *
+ * 0: <return address (orig r31)>
+ * 8: <2nd half for 64-bit>
+ * 12: ldw 0(%sp), %r31
+ * 16: be 0x100(%sr2, %r0)
+ * 20: ldi __NR_restart_syscall, %r20
+ */
+#ifndef __LP64__
+ put_user(regs->gr[31], &usp[0]);
+ put_user(0x0fc0109f, &usp[2]);
+#else
+ put_user(regs->gr[31] >> 32, &usp[0]);
+ put_user(regs->gr[31] & 0xffffffff, &usp[1]);
+ put_user(0x0fc010df, &usp[2]);
+#endif
+ put_user(0xe0008200, &usp[3]);
+ put_user(0x34140000, &usp[4]);
+
+ /* Stack is 64-byte aligned, and we only
+ * need to flush 1 cache line */
+ asm("fdc 0(%%sr3, %0)\n"
+ "fic 0(%%sr3, %0)\n"
+ "sync\n"
+ : : "r"(regs->gr[30]));
+
+ regs->gr[31] = regs->gr[30] + 8;
+ /* Preserve original r28. */
+ regs->gr[28] = regs->orig_r28;
+ } else if (regs->gr[28] == -ERESTARTNOHAND ||
+ regs->gr[28] == -ERESTARTSYS ||
+ regs->gr[28] == -ERESTARTNOINTR) {
/* Hooray for delayed branching. We don't
have to restore %r20 (the system call
number) because it gets loaded in the delay
Index: include/asm-parisc/unistd.h
===================================================================
RCS file: /var/cvs/linux-2.6/include/asm-parisc/unistd.h,v
retrieving revision 1.1
diff -u -p -r1.1 unistd.h
--- include/asm-parisc/unistd.h 29 Jul 2003 17:02:04 -0000 1.1
+++ include/asm-parisc/unistd.h 2 Nov 2003 04:39:24 -0000
@@ -490,7 +490,7 @@
*/
#define __NR_Linux 0
-#define __NR_syscall (__NR_Linux + 0)
+#define __NR_restart_syscall (__NR_Linux + 0)
#define __NR_exit (__NR_Linux + 1)
#define __NR_fork (__NR_Linux + 2)
#define __NR_read (__NR_Linux + 3)