diff options
| -rw-r--r-- | arch/ia64/kernel/ptrace.c | 22 |
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 | ||
| 716 | static int | 736 | static int |
