diff options
Diffstat (limited to 'arch/ia64/kernel/unwind.c')
-rw-r--r-- | arch/ia64/kernel/unwind.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c index d494ff647cac..2776a074c6f1 100644 --- a/arch/ia64/kernel/unwind.c +++ b/arch/ia64/kernel/unwind.c | |||
@@ -1943,23 +1943,30 @@ EXPORT_SYMBOL(unw_unwind); | |||
1943 | int | 1943 | int |
1944 | unw_unwind_to_user (struct unw_frame_info *info) | 1944 | unw_unwind_to_user (struct unw_frame_info *info) |
1945 | { | 1945 | { |
1946 | unsigned long ip, sp; | 1946 | unsigned long ip, sp, pr = 0; |
1947 | 1947 | ||
1948 | while (unw_unwind(info) >= 0) { | 1948 | while (unw_unwind(info) >= 0) { |
1949 | if (unw_get_rp(info, &ip) < 0) { | ||
1950 | unw_get_ip(info, &ip); | ||
1951 | UNW_DPRINT(0, "unwind.%s: failed to read return pointer (ip=0x%lx)\n", | ||
1952 | __FUNCTION__, ip); | ||
1953 | return -1; | ||
1954 | } | ||
1955 | unw_get_sp(info, &sp); | 1949 | unw_get_sp(info, &sp); |
1956 | if (sp >= (unsigned long)info->task + IA64_STK_OFFSET) | 1950 | if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp) |
1951 | < IA64_PT_REGS_SIZE) { | ||
1952 | UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n", | ||
1953 | __FUNCTION__); | ||
1957 | break; | 1954 | break; |
1958 | if (ip < FIXADDR_USER_END) | 1955 | } |
1956 | if (unw_is_intr_frame(info) && | ||
1957 | (pr & (1UL << PRED_USER_STACK))) | ||
1959 | return 0; | 1958 | return 0; |
1959 | if (unw_get_pr (info, &pr) < 0) { | ||
1960 | unw_get_rp(info, &ip); | ||
1961 | UNW_DPRINT(0, "unwind.%s: failed to read " | ||
1962 | "predicate register (ip=0x%lx)\n", | ||
1963 | __FUNCTION__, ip); | ||
1964 | return -1; | ||
1965 | } | ||
1960 | } | 1966 | } |
1961 | unw_get_ip(info, &ip); | 1967 | unw_get_ip(info, &ip); |
1962 | UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", __FUNCTION__, ip); | 1968 | UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", |
1969 | __FUNCTION__, ip); | ||
1963 | return -1; | 1970 | return -1; |
1964 | } | 1971 | } |
1965 | EXPORT_SYMBOL(unw_unwind_to_user); | 1972 | EXPORT_SYMBOL(unw_unwind_to_user); |