From: NIIBE Y. <gn...@m1...> - 2002-03-27 10:39:03
|
Bug fix for syscall restart. Besides, sh_do_profile implemented. 2002-03-27 NIIBE Yutaka <gn...@m1...> * arch/sh/kernel/entry.S (IS_SYSCALL): Renamed from SYSCALL_NR. (system_call, handle_exception): Set is_syscall. * arch/sh/kernel/signal.c (restore_sigcontext, handle_signal, do_signal): Use is_syscall. * include/asm-sh/ptrace.h (is_syscall): Renamed from syscall_nr. * arch/sh/kernel/signal.c (save_sigcontext_fpu): Use __put_user (was: __copy_to_user). (handle_signal, do_signal): Bug fix. Don't set register 0. * include/asm-sh/hw_irq.h (sh_do_profile): Removed from here. * arch/sh/kernel/time.c (sh_do_profile): But implemented here. Index: arch/sh/kernel/entry.S =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/entry.S,v retrieving revision 1.10 diff -u -3 -p -r1.10 entry.S --- arch/sh/kernel/entry.S 22 Mar 2002 14:28:34 -0000 1.10 +++ arch/sh/kernel/entry.S 27 Mar 2002 10:35:42 -0000 @@ -85,7 +85,7 @@ OFF_R6 = 24 /* New ABI: ar OFF_R7 = 28 /* New ABI: arg3 */ OFF_SP = (15*4) OFF_SR = (16*4+8) -SYSCALL_NR = (16*4+6*4) +IS_SYSCALL = (16*4+6*4) #define k0 r0 @@ -404,19 +404,13 @@ system_call: mov.l @r9, r8 ! Read from TRA (Trap Address) Register ! ! Is the trap argument >= 0x20? (TRA will be >= 0x80) - mov #0x20, r9 - shll2 r9 - cmp/hs r9, r8 + mov #0x7f, r9 + cmp/hi r9, r8 bt/s debug_trap - mov #SYSCALL_NR, r9 - add r15, r9 + mov #IS_SYSCALL, r8 + add r15, r8 ! - add #-0x40, r8 - shlr2 r8 - shll8 r8 - shll8 r8 ! r8 = num_args<<16 - or r3, r8 ! Encode syscall # and # of arguments - mov.l r8, @r9 ! set syscall_nr + mov.l r9, @r8 ! set 0x7f to is_syscall STI() ! Call the system call handler through the table. ! First check for bad syscall number @@ -578,10 +572,10 @@ handle_exception: add current, k1 mov k1, r15 ! change to kernel stack ! -1: mov #-1, k4 +1: mov #0, k4 mov.l 2f, k1 ! Save the user registers on the stack. - mov.l k4, @-r15 ! syscall_nr (default: -1) + mov.l k4, @-r15 ! set is_syscall (default: 0) ! sts.l macl, @-r15 sts.l mach, @-r15 Index: arch/sh/kernel/signal.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/signal.c,v retrieving revision 1.6 diff -u -3 -p -r1.6 signal.c --- arch/sh/kernel/signal.c 22 Mar 2002 12:57:10 -0000 1.6 +++ arch/sh/kernel/signal.c 27 Mar 2002 10:35:42 -0000 @@ -199,16 +199,13 @@ static inline int save_sigcontext_fpu(st { struct task_struct *tsk = current; unsigned long flags; - int val; if (!tsk->used_math) { - val = 0; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(0, &sc->sc_ownedfp); return 0; } - val = 1; - __copy_to_user(&sc->sc_ownedfp, &val, sizeof(int)); + __put_user(1, &sc->sc_ownedfp); /* This will cause a "finit" to be triggered by the next attempted FPU operation by the 'current' process. @@ -257,7 +254,7 @@ restore_sigcontext(struct pt_regs *regs, } #endif - regs->syscall_nr = -1; /* disable syscall checks */ + regs->is_syscall = 0; /* disable syscall checks */ err |= __get_user(*r0_p, &sc->sc_regs[0]); return err; } @@ -526,7 +523,7 @@ handle_signal(unsigned long sig, struct siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { /* Are we from a system call? */ - if (regs->syscall_nr >= 0) { + if (regs->is_syscall) { /* If so, check system call restarting.. */ switch (regs->regs[0]) { case -ERESTARTNOHAND: @@ -540,7 +537,6 @@ handle_signal(unsigned long sig, struct } /* fallthrough */ case -ERESTARTNOINTR: - regs->regs[0] = regs->syscall_nr; regs->pc -= 2; } } @@ -684,12 +680,11 @@ int do_signal(struct pt_regs *regs, sigs } /* Did we come from a system call? */ - if (regs->syscall_nr >= 0) { + if (regs->is_syscall) { /* Restart the system call - no handlers present */ if (regs->regs[0] == -ERESTARTNOHAND || regs->regs[0] == -ERESTARTSYS || regs->regs[0] == -ERESTARTNOINTR) { - regs->regs[0] = regs->syscall_nr; regs->pc -= 2; } } Index: arch/sh/kernel/time.c =================================================================== RCS file: /cvsroot/linuxsh/linux/arch/sh/kernel/time.c,v retrieving revision 1.1 diff -u -3 -p -r1.1 time.c --- arch/sh/kernel/time.c 15 Oct 2001 20:44:50 -0000 1.1 +++ arch/sh/kernel/time.c 27 Mar 2002 10:35:42 -0000 @@ -176,6 +176,25 @@ void do_settimeofday(struct timeval *tv) /* last time the RTC clock got updated */ static long last_rtc_update; +static __inline__ void sh_do_profile (unsigned long pc) +{ + extern int _stext; + + if (!prof_buffer) + return; + + pc -= (unsigned long) &_stext; + pc >>= prof_shift; + /* + * Don't ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (pc > prof_len-1) + pc = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[pc]); +} + /* * timer_interrupt() needs to keep up the real-time clock, * as well as call the "do_timer()" routine every clocktick Index: include/asm-sh/hw_irq.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/hw_irq.h,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 hw_irq.h --- include/asm-sh/hw_irq.h 15 Oct 2001 20:45:08 -0000 1.1.1.1 +++ include/asm-sh/hw_irq.h 27 Mar 2002 10:35:42 -0000 @@ -1,6 +1,4 @@ #ifndef __ASM_SH_HW_IRQ_H #define __ASM_SH_HW_IRQ_H -static __inline__ void sh_do_profile (unsigned long pc) {/*Not implemented yet*/} - static __inline__ void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) { /* Nothing to do */ } #endif /* __ASM_SH_HW_IRQ_H */ Index: include/asm-sh/ptrace.h =================================================================== RCS file: /cvsroot/linuxsh/linux/include/asm-sh/ptrace.h,v retrieving revision 1.1.1.1 diff -u -3 -p -r1.1.1.1 ptrace.h --- include/asm-sh/ptrace.h 15 Oct 2001 20:45:11 -0000 1.1.1.1 +++ include/asm-sh/ptrace.h 27 Mar 2002 10:35:42 -0000 @@ -61,7 +61,7 @@ struct pt_regs { unsigned long gbr; unsigned long mach; unsigned long macl; - long syscall_nr; + long is_syscall; }; #ifdef __KERNEL__ |