mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-12 05:48:39 +08:00
[IA64] Tighten up unw_unwind_to_user check
Detect user space by the unwind frame with predicate PRED_USER_STACK set, instead of a user space IP. Tighten up the last ditch check for running off the top of the kernel stack. Based on a suggestion by David Mosberger, reworked to fit the current tree. This survives my stress test which used to break 2.6.9 kernels. Unlike 2.6.11, the stress test now unwinds to the correct point, so gdb can get the user space registers. Signed-off-by: Keith Owens <kaos@sgi.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
parent
8297511530
commit
e8d1cb2f28
@ -1943,23 +1943,30 @@ EXPORT_SYMBOL(unw_unwind);
|
||||
int
|
||||
unw_unwind_to_user (struct unw_frame_info *info)
|
||||
{
|
||||
unsigned long ip, sp;
|
||||
unsigned long ip, sp, pr = 0;
|
||||
|
||||
while (unw_unwind(info) >= 0) {
|
||||
if (unw_get_rp(info, &ip) < 0) {
|
||||
unw_get_ip(info, &ip);
|
||||
UNW_DPRINT(0, "unwind.%s: failed to read return pointer (ip=0x%lx)\n",
|
||||
__FUNCTION__, ip);
|
||||
unw_get_sp(info, &sp);
|
||||
if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp)
|
||||
< IA64_PT_REGS_SIZE) {
|
||||
UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n",
|
||||
__FUNCTION__);
|
||||
break;
|
||||
}
|
||||
if (unw_is_intr_frame(info) &&
|
||||
(pr & (1UL << PRED_USER_STACK)))
|
||||
return 0;
|
||||
if (unw_get_pr (info, &pr) < 0) {
|
||||
unw_get_rp(info, &ip);
|
||||
UNW_DPRINT(0, "unwind.%s: failed to read "
|
||||
"predicate register (ip=0x%lx)\n",
|
||||
__FUNCTION__, ip);
|
||||
return -1;
|
||||
}
|
||||
unw_get_sp(info, &sp);
|
||||
if (sp >= (unsigned long)info->task + IA64_STK_OFFSET)
|
||||
break;
|
||||
if (ip < FIXADDR_USER_END)
|
||||
return 0;
|
||||
}
|
||||
unw_get_ip(info, &ip);
|
||||
UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", __FUNCTION__, ip);
|
||||
UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n",
|
||||
__FUNCTION__, ip);
|
||||
return -1;
|
||||
}
|
||||
EXPORT_SYMBOL(unw_unwind_to_user);
|
||||
|
Loading…
Reference in New Issue
Block a user