GIT 4c79ca6f882fa1bd595fb3d5f128e09371611358 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6.git commit Author: Stuart Menefy Date: Fri Feb 16 20:26:03 2007 +0900 sh: Clear UBC when not in use. This takes care of tearing down the UBC so it's not inadvertently left configured at the next context switch time. Failure to do this results in spurious SIGTRAPs in certain debug sequences. Signed-off-by: Stuart Menefy Signed-off-by: Paul Mundt commit 45ae81f8265e7271939071dcd1053c6e4a1dec89 Author: Mike Frysinger Date: Fri Feb 16 17:30:17 2007 +0900 sh: ioctls.h tidying and build fix. This brings ioctls.h more in line with what others are doing by dropping the _IO*() mess and just open-coding the values. This ended up breaking where the structures weren't able to be resolved, and rather than littering with includes, we just convert it instead. Signed-off-by: Mike Frysinger Signed-off-by: Paul Mundt arch/sh/kernel/entry-common.S | 2 - arch/sh/kernel/ptrace.c | 45 +++++++++++++----- include/asm-sh/ioctls.h | 102 +++++++++++++++++++++-------------------- include/asm-sh/thread_info.h | 2 + 4 files changed, 87 insertions(+), 64 deletions(-) diff --git a/arch/sh/kernel/entry-common.S b/arch/sh/kernel/entry-common.S index ab4ebb8..b467280 100644 --- a/arch/sh/kernel/entry-common.S +++ b/arch/sh/kernel/entry-common.S @@ -224,7 +224,7 @@ #endif syscall_exit_work: ! r0: current_thread_info->flags ! r8: current_thread_info - tst #_TIF_SYSCALL_TRACE, r0 + tst #_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP, r0 bt/s work_pending tst #_TIF_NEED_RESCHED, r0 #ifdef CONFIG_TRACE_IRQFLAGS diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c index 04ca13a..855f724 100644 --- a/arch/sh/kernel/ptrace.c +++ b/arch/sh/kernel/ptrace.c @@ -8,7 +8,6 @@ * SuperH version: Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka * */ - #include #include #include @@ -20,8 +19,7 @@ #include #include #include #include - -#include +#include #include #include #include @@ -59,6 +57,23 @@ static inline int put_stack_long(struct return 0; } +static void ptrace_disable_singlestep(struct task_struct *child) +{ + clear_tsk_thread_flag(child, TIF_SINGLESTEP); + + /* + * Ensure the UBC is not programmed at the next context switch. + * + * Normally this is not needed but there are sequences such as + * singlestep, signal delivery, and continue that leave the + * ubc_pc non-zero leading to spurious SIGTRAPs. + */ + if (child->thread.ubc_pc != 0) { + ubc_usercnt -= 1; + child->thread.ubc_pc = 0; + } +} + /* * Called by kernel/ptrace.c when detaching.. * @@ -66,7 +81,7 @@ static inline int put_stack_long(struct */ void ptrace_disable(struct task_struct *child) { - /* nothing to do.. */ + ptrace_disable_singlestep(child); } long arch_ptrace(struct task_struct *child, long request, long addr, long data) @@ -76,7 +91,7 @@ long arch_ptrace(struct task_struct *chi switch (request) { /* when I and D space are separate, these will need to be fixed. */ - case PTRACE_PEEKTEXT: /* read word at location addr. */ + case PTRACE_PEEKTEXT: /* read word at location addr. */ case PTRACE_PEEKDATA: { unsigned long tmp; int copied; @@ -94,7 +109,7 @@ long arch_ptrace(struct task_struct *chi unsigned long tmp; ret = -EIO; - if ((addr & 3) || addr < 0 || + if ((addr & 3) || addr < 0 || addr > sizeof(struct user) - 3) break; @@ -129,7 +144,7 @@ long arch_ptrace(struct task_struct *chi case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ ret = -EIO; - if ((addr & 3) || addr < 0 || + if ((addr & 3) || addr < 0 || addr > sizeof(struct user) - 3) break; @@ -156,6 +171,9 @@ long arch_ptrace(struct task_struct *chi set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); + + ptrace_disable_singlestep(child); + child->exit_code = data; wake_up_process(child); ret = 0; @@ -163,14 +181,15 @@ long arch_ptrace(struct task_struct *chi } /* - * make the child exit. Best I can do is send it a sigkill. - * perhaps it should be put in the status that it wants to + * make the child exit. Best I can do is send it a sigkill. + * perhaps it should be put in the status that it wants to * exit. */ case PTRACE_KILL: { ret = 0; if (child->exit_state == EXIT_ZOMBIE) /* already dead */ break; + ptrace_disable_singlestep(child); child->exit_code = SIGKILL; wake_up_process(child); break; @@ -196,6 +215,7 @@ long arch_ptrace(struct task_struct *chi ubc_usercnt += 1; child->thread.ubc_pc = pc; + set_tsk_thread_flag(child, TIF_SINGLESTEP); child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); @@ -248,14 +268,15 @@ asmlinkage void do_syscall_trace(void) { struct task_struct *tsk = current; - if (!test_thread_flag(TIF_SYSCALL_TRACE)) + if (!test_thread_flag(TIF_SYSCALL_TRACE) && + !test_thread_flag(TIF_SINGLESTEP)) return; if (!(tsk->ptrace & PT_PTRACED)) return; /* the 0x80 provides a way for the tracing parent to distinguish between a syscall stop and SIGTRAP delivery */ - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) && + !test_thread_flag(TIF_SINGLESTEP) ? 0x80 : 0)); /* * this isn't the same as continuing with a signal, but it will do diff --git a/include/asm-sh/ioctls.h b/include/asm-sh/ioctls.h index 9d84a2d..568a873 100644 --- a/include/asm-sh/ioctls.h +++ b/include/asm-sh/ioctls.h @@ -3,46 +3,46 @@ #define __ASM_SH_IOCTLS_H #include -#define FIOCLEX _IO('f', 1) -#define FIONCLEX _IO('f', 2) -#define FIOASYNC _IOW('f', 125, int) -#define FIONBIO _IOW('f', 126, int) -#define FIONREAD _IOR('f', 127, int) +#define FIOCLEX 0x5451 +#define FIONCLEX 0x5450 +#define FIOASYNC 0x5452 +#define FIONBIO 0x5421 +#define FIONREAD 0x541B #define TIOCINQ FIONREAD -#define FIOQSIZE _IOR('f', 128, loff_t) +#define FIOQSIZE 0x5460 #define TCGETS 0x5401 #define TCSETS 0x5402 #define TCSETSW 0x5403 #define TCSETSF 0x5404 -#define TCGETA _IOR('t', 23, struct termio) -#define TCSETA _IOW('t', 24, struct termio) -#define TCSETAW _IOW('t', 25, struct termio) -#define TCSETAF _IOW('t', 28, struct termio) +#define TCGETA 0x5405 +#define TCSETA 0x5406 +#define TCSETAW 0x5407 +#define TCSETAF 0x5408 -#define TCSBRK _IO('t', 29) -#define TCXONC _IO('t', 30) -#define TCFLSH _IO('t', 31) +#define TCSBRK 0x5409 +#define TCXONC 0x540A +#define TCFLSH 0x540B -#define TIOCSWINSZ _IOW('t', 103, struct winsize) -#define TIOCGWINSZ _IOR('t', 104, struct winsize) -#define TIOCSTART _IO('t', 110) /* start output, like ^Q */ -#define TIOCSTOP _IO('t', 111) /* stop output, like ^S */ -#define TIOCOUTQ _IOR('t', 115, int) /* output queue size */ +#define TIOCSWINSZ 0x5414 +#define TIOCGWINSZ 0x5413 +#define TIOCSTART 0x746E +#define TIOCSTOP 0x746F +#define TIOCOUTQ 0x5411 -#define TIOCSPGRP _IOW('t', 118, int) -#define TIOCGPGRP _IOR('t', 119, int) +#define TIOCSPGRP 0x5410 +#define TIOCGPGRP 0x540F -#define TIOCEXCL _IO('T', 12) /* 0x540C */ -#define TIOCNXCL _IO('T', 13) /* 0x540D */ -#define TIOCSCTTY _IO('T', 14) /* 0x540E */ +#define TIOCEXCL 0x540C +#define TIOCNXCL 0x540D +#define TIOCSCTTY 0x540E -#define TIOCSTI _IOW('T', 18, char) /* 0x5412 */ -#define TIOCMGET _IOR('T', 21, unsigned int) /* 0x5415 */ -#define TIOCMBIS _IOW('T', 22, unsigned int) /* 0x5416 */ -#define TIOCMBIC _IOW('T', 23, unsigned int) /* 0x5417 */ -#define TIOCMSET _IOW('T', 24, unsigned int) /* 0x5418 */ +#define TIOCSTI 0x5412 +#define TIOCMGET 0x5415 +#define TIOCMBIS 0x5416 +#define TIOCMBIC 0x5417 +#define TIOCMSET 0x5418 # define TIOCM_LE 0x001 # define TIOCM_DTR 0x002 # define TIOCM_RTS 0x004 @@ -55,13 +55,13 @@ # define TIOCM_DSR 0x100 # define TIOCM_CD TIOCM_CAR # define TIOCM_RI TIOCM_RNG -#define TIOCGSOFTCAR _IOR('T', 25, unsigned int) /* 0x5419 */ -#define TIOCSSOFTCAR _IOW('T', 26, unsigned int) /* 0x541A */ -#define TIOCLINUX _IOW('T', 28, char) /* 0x541C */ -#define TIOCCONS _IO('T', 29) /* 0x541D */ -#define TIOCGSERIAL _IOR('T', 30, struct serial_struct) /* 0x541E */ -#define TIOCSSERIAL _IOW('T', 31, struct serial_struct) /* 0x541F */ -#define TIOCPKT _IOW('T', 32, int) /* 0x5420 */ +#define TIOCGSOFTCAR 0x5419 +#define TIOCSSOFTCAR 0x541A +#define TIOCLINUX 0x541C +#define TIOCCONS 0x541D +#define TIOCGSERIAL 0x541E +#define TIOCSSERIAL 0x541F +#define TIOCPKT 0x5420 # define TIOCPKT_DATA 0 # define TIOCPKT_FLUSHREAD 1 # define TIOCPKT_FLUSHWRITE 2 @@ -71,29 +71,29 @@ # define TIOCPKT_NOSTOP 16 # define TIOCPKT_DOSTOP 32 -#define TIOCNOTTY _IO('T', 34) /* 0x5422 */ -#define TIOCSETD _IOW('T', 35, int) /* 0x5423 */ -#define TIOCGETD _IOR('T', 36, int) /* 0x5424 */ -#define TCSBRKP _IOW('T', 37, int) /* 0x5425 */ /* Needed for POSIX tcsendbreak() */ -#define TIOCSBRK _IO('T', 39) /* 0x5427 */ /* BSD compatibility */ -#define TIOCCBRK _IO('T', 40) /* 0x5428 */ /* BSD compatibility */ -#define TIOCGSID _IOR('T', 41, pid_t) /* 0x5429 */ /* Return the session ID of FD */ +#define TIOCNOTTY 0x5422 +#define TIOCSETD 0x5423 +#define TIOCGETD 0x5424 +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ +#define TIOCSBRK 0x5427 /* BSD compatibility */ +#define TIOCCBRK 0x5428 /* BSD compatibility */ +#define TIOCGSID 0x5429 /* Return the session ID of FD */ #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ -#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ +#define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ -#define TIOCSERCONFIG _IO('T', 83) /* 0x5453 */ -#define TIOCSERGWILD _IOR('T', 84, int) /* 0x5454 */ -#define TIOCSERSWILD _IOW('T', 85, int) /* 0x5455 */ +#define TIOCSERCONFIG 0x5453 +#define TIOCSERGWILD 0x5454 +#define TIOCSERSWILD 0x5455 #define TIOCGLCKTRMIOS 0x5456 #define TIOCSLCKTRMIOS 0x5457 -#define TIOCSERGSTRUCT _IOR('T', 88, struct async_struct) /* 0x5458 */ /* For debugging only */ -#define TIOCSERGETLSR _IOR('T', 89, unsigned int) /* 0x5459 */ /* Get line status register */ +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */ +#define TIOCSERGETLSR 0x5459 /* Get line status register */ /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ # define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ -#define TIOCSERGETMULTI _IOR('T', 90, struct serial_multiport_struct) /* 0x545A */ /* Get multiport config */ -#define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* 0x545B */ /* Set multiport config */ +#define TIOCSERGETMULTI 0x545A /* Get multiport config */ +#define TIOCSERSETMULTI 0x545B /* Set multiport config */ -#define TIOCMIWAIT _IO('T', 92) /* 0x545C */ /* wait for a change on serial input line(s) */ +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ #endif /* __ASM_SH_IOCTLS_H */ diff --git a/include/asm-sh/thread_info.h b/include/asm-sh/thread_info.h index 279e70a..31d55e3 100644 --- a/include/asm-sh/thread_info.h +++ b/include/asm-sh/thread_info.h @@ -111,6 +111,7 @@ #define TIF_NOTIFY_RESUME 1 /* resumptio #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ #define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */ +#define TIF_SINGLESTEP 5 /* singlestepping active */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 @@ -121,6 +122,7 @@ #define _TIF_NOTIFY_RESUME (1<