aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid Mosberger-Tang <davidm@hpl.hp.com>2005-05-10 15:49:00 -0400
committerTony Luck <tony.luck@intel.com>2005-05-17 17:07:10 -0400
commit7f9eaedf894dbaa08c157832e9a6c9c03ffed1ed (patch)
tree12a561efa197fdbe78ba74b576c28f132e04660a /arch
parent8800cea62025a5209d110c5fa5990429239d6eee (diff)
[IA64] Fix convert_to_non_syscall() so gdb inferior calls work again
Fix convert_to_non_syscall() so it arranges for the kernel to be left via ia64_leave_kernel() rather than ia64_leave_syscall(). The latter no longer tolerates being called with pSys=0 and pNonSys=1. Signed-off-by: David Mosberger-Tang <davidm@hpl.hp.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/kernel/ptrace.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index c253fd5914fc..9e730c7bf0cd 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -705,12 +705,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt,
705 break; 705 break;
706 } 706 }
707 707
708 /*
709 * Note: at the time of this call, the target task is blocked
710 * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL
711 * (aka, "pLvSys") we redirect execution from
712 * .work_pending_syscall_end to .work_processed_kernel.
713 */
708 unw_get_pr(&prev_info, &pr); 714 unw_get_pr(&prev_info, &pr);
709 pr &= ~(1UL << PRED_SYSCALL); 715 pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL));
710 pr |= (1UL << PRED_NON_SYSCALL); 716 pr |= (1UL << PRED_NON_SYSCALL);
711 unw_set_pr(&prev_info, pr); 717 unw_set_pr(&prev_info, pr);
712 718
713 pt->cr_ifs = (1UL << 63) | cfm; 719 pt->cr_ifs = (1UL << 63) | cfm;
720 /*
721 * Clear the memory that is NOT written on syscall-entry to
722 * ensure we do not leak kernel-state to user when execution
723 * resumes.
724 */
725 pt->r2 = 0;
726 pt->r3 = 0;
727 pt->r14 = 0;
728 memset(&pt->r16, 0, 16*8); /* clear r16-r31 */
729 memset(&pt->f6, 0, 6*16); /* clear f6-f11 */
730 pt->b7 = 0;
731 pt->ar_ccv = 0;
732 pt->ar_csd = 0;
733 pt->ar_ssd = 0;
714} 734}
715 735
716static int 736static int