[IA64] Synchronize RBS on PTRACE_ATTACH

When attaching to a stopped process, the RSE must be explicitly
synced to user-space, so the debugger can read the correct values.

Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
CC: Roland McGrath <roland@redhat.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>

authored by Petr Tesarik and committed by Tony Luck aa91a2e9 3b2ce0b1

+61
+57
arch/ia64/kernel/ptrace.c
··· 613 613 unw_init_running(do_sync_rbs, ia64_sync_kernel_rbs); 614 614 } 615 615 616 + /* 617 + * After PTRACE_ATTACH, a thread's register backing store area in user 618 + * space is assumed to contain correct data whenever the thread is 619 + * stopped. arch_ptrace_stop takes care of this on tracing stops. 620 + * But if the child was already stopped for job control when we attach 621 + * to it, then it might not ever get into ptrace_stop by the time we 622 + * want to examine the user memory containing the RBS. 623 + */ 624 + void 625 + ptrace_attach_sync_user_rbs (struct task_struct *child) 626 + { 627 + int stopped = 0; 628 + struct unw_frame_info info; 629 + 630 + /* 631 + * If the child is in TASK_STOPPED, we need to change that to 632 + * TASK_TRACED momentarily while we operate on it. This ensures 633 + * that the child won't be woken up and return to user mode while 634 + * we are doing the sync. (It can only be woken up for SIGKILL.) 635 + */ 636 + 637 + read_lock(&tasklist_lock); 638 + if (child->signal) { 639 + spin_lock_irq(&child->sighand->siglock); 640 + if (child->state == TASK_STOPPED && 641 + !test_and_set_tsk_thread_flag(child, TIF_RESTORE_RSE)) { 642 + tsk_set_notify_resume(child); 643 + 644 + child->state = TASK_TRACED; 645 + stopped = 1; 646 + } 647 + spin_unlock_irq(&child->sighand->siglock); 648 + } 649 + read_unlock(&tasklist_lock); 650 + 651 + if (!stopped) 652 + return; 653 + 654 + unw_init_from_blocked_task(&info, child); 655 + do_sync_rbs(&info, ia64_sync_user_rbs); 656 + 657 + /* 658 + * Now move the child back into TASK_STOPPED if it should be in a 659 + * job control stop, so that SIGCONT can be used to wake it up. 660 + */ 661 + read_lock(&tasklist_lock); 662 + if (child->signal) { 663 + spin_lock_irq(&child->sighand->siglock); 664 + if (child->state == TASK_TRACED && 665 + (child->signal->flags & SIGNAL_STOP_STOPPED)) { 666 + child->state = TASK_STOPPED; 667 + } 668 + spin_unlock_irq(&child->sighand->siglock); 669 + } 670 + read_unlock(&tasklist_lock); 671 + } 672 + 616 673 static inline int 617 674 thread_matches (struct task_struct *thread, unsigned long addr) 618 675 {
+4
include/asm-ia64/ptrace.h
··· 310 310 #define arch_ptrace_stop_needed(code, info) \ 311 311 (!test_thread_flag(TIF_RESTORE_RSE)) 312 312 313 + extern void ptrace_attach_sync_user_rbs (struct task_struct *); 314 + #define arch_ptrace_attach(child) \ 315 + ptrace_attach_sync_user_rbs(child) 316 + 313 317 #endif /* !__KERNEL__ */ 314 318 315 319 /* pt_all_user_regs is used for PTRACE_GETREGS PTRACE_SETREGS */