]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
parisc: Fix and improve kernel stack unwinding
authorHelge Deller <deller@gmx.de>
Sat, 4 Aug 2018 22:03:29 +0000 (00:03 +0200)
committerHelge Deller <deller@gmx.de>
Mon, 13 Aug 2018 07:54:17 +0000 (09:54 +0200)
This patchset fixes and improves stack unwinding a lot:
1. Show backward stack traces with up to 30 callsites
2. Add callinfo to ENTRY_CFI() such that every assembler function will get an
   entry in the unwind table
3. Use constants instead of numbers in call_on_stack()
4. Do not depend on CONFIG_KALLSYMS to generate backtraces.
5. Speed up backtrace generation

Make sure you have this patch to GNU as installed:
https://sourceware.org/ml/binutils/2018-07/msg00474.html
Without this patch, unwind info in the kernel is often wrong for various
functions.

Signed-off-by: Helge Deller <deller@gmx.de>
arch/parisc/include/asm/assembly.h
arch/parisc/include/asm/linkage.h
arch/parisc/include/asm/unwind.h
arch/parisc/kernel/entry.S
arch/parisc/kernel/pacache.S
arch/parisc/kernel/process.c
arch/parisc/kernel/real2.S
arch/parisc/kernel/traps.c
arch/parisc/kernel/unwind.c
arch/parisc/lib/lusercopy.S

index 60e6f07b7e326bc4eb306105dcae477d5aa01f0e..e9c6385ef0d16235dd24ff256a9ea9181745c355 100644 (file)
@@ -36,6 +36,7 @@
 #define RP_OFFSET      16
 #define FRAME_SIZE     128
 #define CALLEE_REG_FRAME_SIZE  144
+#define REG_SZ         8
 #define ASM_ULONG_INSN .dword
 #else  /* CONFIG_64BIT */
 #define LDREG  ldw
@@ -50,6 +51,7 @@
 #define RP_OFFSET      20
 #define FRAME_SIZE     64
 #define CALLEE_REG_FRAME_SIZE  128
+#define REG_SZ         4
 #define ASM_ULONG_INSN .word
 #endif
 
index 9a69bf6fc4b6938260162b8ba7435301e5ccf2db..49f6f3d772cc643b7cced383bf17ec73a6b1fd6b 100644 (file)
@@ -18,9 +18,9 @@
 #ifdef __ASSEMBLY__
 
 #define ENTRY(name) \
-       .export name !\
-       ALIGN !\
-name:
+       ALIGN   !\
+name:          ASM_NL\
+       .export name
 
 #ifdef CONFIG_64BIT
 #define ENDPROC(name) \
@@ -31,13 +31,18 @@ name:
        END(name)
 #endif
 
-#define ENTRY_CFI(name) \
+#define ENTRY_CFI(name, ...) \
        ENTRY(name)     ASM_NL\
+       .proc           ASM_NL\
+       .callinfo __VA_ARGS__   ASM_NL\
+       .entry          ASM_NL\
        CFI_STARTPROC
 
 #define ENDPROC_CFI(name) \
-       ENDPROC(name)   ASM_NL\
-       CFI_ENDPROC
+       CFI_ENDPROC     ASM_NL\
+       .exit           ASM_NL\
+       .procend        ASM_NL\
+       ENDPROC(name)
 
 #endif /* __ASSEMBLY__ */
 
index c73a3ee202267b281217014c549272212f387b78..f133b7efbebbf882ac0e26d3edf02c0924175930 100644 (file)
@@ -4,6 +4,9 @@
 
 #include <linux/list.h>
 
+/* Max number of levels to backtrace */
+#define MAX_UNWIND_ENTRIES     30
+
 /* From ABI specifications */
 struct unwind_table_entry {
        unsigned int region_start;
index 1b4732e201374adc2721ab7141e5ed9b5bf9bd69..c7508f5717fb511ee463fc9aac83270a00d71cc4 100644 (file)
@@ -766,7 +766,6 @@ END(fault_vector_11)
 #endif
        /* Fault vector is separately protected and *must* be on its own page */
        .align          PAGE_SIZE
-ENTRY(end_fault_vector)
 
        .import         handle_interruption,code
        .import         do_cpu_irq_mask,code
@@ -778,7 +777,6 @@ ENTRY(end_fault_vector)
         */
 
 ENTRY_CFI(ret_from_kernel_thread)
-
        /* Call schedule_tail first though */
        BL      schedule_tail, %r2
        nop
@@ -817,8 +815,9 @@ ENTRY_CFI(_switch_to)
        LDREG   TASK_THREAD_INFO(%r25), %r25
        bv      %r0(%r2)
        mtctl   %r25,%cr30
+ENDPROC_CFI(_switch_to)
 
-_switch_to_ret:
+ENTRY_CFI(_switch_to_ret)
        mtctl   %r0, %cr0               /* Needed for single stepping */
        callee_rest
        callee_rest_float
@@ -826,7 +825,7 @@ _switch_to_ret:
        LDREG   -RP_OFFSET(%r30), %r2
        bv      %r0(%r2)
        copy    %r26, %r28
-ENDPROC_CFI(_switch_to)
+ENDPROC_CFI(_switch_to_ret)
 
        /*
         * Common rfi return path for interruptions, kernel execve, and
@@ -887,12 +886,14 @@ ENTRY_CFI(syscall_exit_rfi)
        STREG   %r19,PT_SR5(%r16)
        STREG   %r19,PT_SR6(%r16)
        STREG   %r19,PT_SR7(%r16)
+ENDPROC_CFI(syscall_exit_rfi)
 
-intr_return:
+ENTRY_CFI(intr_return)
        /* check for reschedule */
        mfctl   %cr30,%r1
        LDREG   TI_FLAGS(%r1),%r19      /* sched.h: TIF_NEED_RESCHED */
        bb,<,n  %r19,31-TIF_NEED_RESCHED,intr_do_resched /* forward */
+ENDPROC_CFI(intr_return)
 
        .import do_notify_resume,code
 intr_check_sig:
@@ -1048,7 +1049,6 @@ intr_extint:
 
        b       do_cpu_irq_mask
        ldo     R%intr_return(%r2), %r2 /* return to intr_return, not here */
-ENDPROC_CFI(syscall_exit_rfi)
 
 
        /* Generic interruptions (illegal insn, unaligned, page fault, etc) */
@@ -1999,12 +1999,9 @@ ENDPROC_CFI(syscall_exit)
        .align L1_CACHE_BYTES
        .globl mcount
        .type  mcount, @function
-ENTRY(mcount)
+ENTRY_CFI(mcount, caller)
 _mcount:
        .export _mcount,data
-       .proc
-       .callinfo caller,frame=0
-       .entry
        /*
         * The 64bit mcount() function pointer needs 4 dwords, of which the
         * first two are free.  We optimize it here and put 2 instructions for
@@ -2026,18 +2023,13 @@ ftrace_stub:
        .dword mcount
        .dword 0 /* code in head.S puts value of global gp here */
 #endif
-       .exit
-       .procend
-ENDPROC(mcount)
+ENDPROC_CFI(mcount)
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
        .align 8
        .globl return_to_handler
        .type  return_to_handler, @function
-ENTRY_CFI(return_to_handler)
-       .proc
-       .callinfo caller,frame=FRAME_SIZE
-       .entry
+ENTRY_CFI(return_to_handler, caller,frame=FRAME_SIZE)
        .export parisc_return_to_handler,data
 parisc_return_to_handler:
        copy %r3,%r1
@@ -2076,8 +2068,6 @@ parisc_return_to_handler:
        bv      %r0(%rp)
 #endif
        LDREGM -FRAME_SIZE(%sp),%r3
-       .exit
-       .procend
 ENDPROC_CFI(return_to_handler)
 
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
@@ -2087,31 +2077,30 @@ ENDPROC_CFI(return_to_handler)
 #ifdef CONFIG_IRQSTACKS
 /* void call_on_stack(unsigned long param1, void *func,
                      unsigned long new_stack) */
-ENTRY_CFI(call_on_stack)
+ENTRY_CFI(call_on_stack, FRAME=2*FRAME_SIZE,CALLS,SAVE_RP,SAVE_SP)
        copy    %sp, %r1
 
        /* Regarding the HPPA calling conventions for function pointers,
           we assume the PIC register is not changed across call.  For
           CONFIG_64BIT, the argument pointer is left to point at the
           argument region allocated for the call to call_on_stack. */
+
+       /* Switch to new stack.  We allocate two frames.  */
+       ldo     2*FRAME_SIZE(%arg2), %sp
 # ifdef CONFIG_64BIT
-       /* Switch to new stack.  We allocate two 128 byte frames.  */
-       ldo     256(%arg2), %sp
        /* Save previous stack pointer and return pointer in frame marker */
-       STREG   %rp, -144(%sp)
+       STREG   %rp, -FRAME_SIZE-RP_OFFSET(%sp)
        /* Calls always use function descriptor */
        LDREG   16(%arg1), %arg1
        bve,l   (%arg1), %rp
-       STREG   %r1, -136(%sp)
-       LDREG   -144(%sp), %rp
+       STREG   %r1, -FRAME_SIZE-REG_SZ(%sp)
+       LDREG   -FRAME_SIZE-RP_OFFSET(%sp), %rp
        bve     (%rp)
-       LDREG   -136(%sp), %sp
+       LDREG   -FRAME_SIZE-REG_SZ(%sp), %sp
 # else
-       /* Switch to new stack.  We allocate two 64 byte frames.  */
-       ldo     128(%arg2), %sp
        /* Save previous stack pointer and return pointer in frame marker */
-       STREG   %r1, -68(%sp)
-       STREG   %rp, -84(%sp)
+       STREG   %r1, -FRAME_SIZE-REG_SZ(%sp)
+       STREG   %rp, -FRAME_SIZE-RP_OFFSET(%sp)
        /* Calls use function descriptor if PLABEL bit is set */
        bb,>=,n %arg1, 30, 1f
        depwi   0,31,2, %arg1
@@ -2119,9 +2108,9 @@ ENTRY_CFI(call_on_stack)
 1:
        be,l    0(%sr4,%arg1), %sr0, %r31
        copy    %r31, %rp
-       LDREG   -84(%sp), %rp
+       LDREG   -FRAME_SIZE-RP_OFFSET(%sp), %rp
        bv      (%rp)
-       LDREG   -68(%sp), %sp
+       LDREG   -FRAME_SIZE-REG_SZ(%sp), %sp
 # endif /* CONFIG_64BIT */
 ENDPROC_CFI(call_on_stack)
 #endif /* CONFIG_IRQSTACKS */
index 97451e67d35bf8d5c124af7ad88e3546bb33190d..f33bf2d306d607fb915c8469471793d9c1ddf2b5 100644 (file)
        .align  16
 
 ENTRY_CFI(flush_tlb_all_local)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        /*
         * The pitlbe and pdtlbe instructions should only be used to
         * flush the entire tlb. Also, there needs to be no intervening
@@ -189,18 +185,11 @@ fdtdone:
 
 2:      bv             %r0(%r2)
        nop
-
-       .exit
-       .procend
 ENDPROC_CFI(flush_tlb_all_local)
 
        .import cache_info,data
 
 ENTRY_CFI(flush_instruction_cache_local)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        load32          cache_info, %r1
 
        /* Flush Instruction Cache */
@@ -256,18 +245,11 @@ fisync:
        mtsm            %r22                    /* restore I-bit */
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_instruction_cache_local)
 
 
        .import cache_info, data
 ENTRY_CFI(flush_data_cache_local)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        load32          cache_info, %r1
 
        /* Flush Data Cache */
@@ -324,9 +306,6 @@ fdsync:
        mtsm            %r22                    /* restore I-bit */
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_data_cache_local)
 
 /* Macros to serialize TLB purge operations on SMP.  */
@@ -362,10 +341,6 @@ ENDPROC_CFI(flush_data_cache_local)
 /* Clear page using kernel mapping.  */
 
 ENTRY_CFI(clear_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
 #ifdef CONFIG_64BIT
 
        /* Unroll the loop.  */
@@ -424,18 +399,11 @@ ENTRY_CFI(clear_page_asm)
 #endif
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(clear_page_asm)
 
 /* Copy page using kernel mapping.  */
 
 ENTRY_CFI(copy_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
 #ifdef CONFIG_64BIT
        /* PA8x00 CPUs can consume 2 loads or 1 store per cycle.
         * Unroll the loop by hand and arrange insn appropriately.
@@ -542,9 +510,6 @@ ENTRY_CFI(copy_page_asm)
 #endif
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(copy_page_asm)
 
 /*
@@ -598,10 +563,6 @@ ENDPROC_CFI(copy_page_asm)
         */
 
 ENTRY_CFI(copy_user_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        /* Convert virtual `to' and `from' addresses to physical addresses.
           Move `from' physical address to non shadowed register.  */
        ldil            L%(__PAGE_OFFSET), %r1
@@ -750,16 +711,9 @@ ENTRY_CFI(copy_user_page_asm)
 
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(copy_user_page_asm)
 
 ENTRY_CFI(clear_user_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        tophys_r1       %r26
 
        ldil            L%(TMPALIAS_MAP_START), %r28
@@ -836,16 +790,9 @@ ENTRY_CFI(clear_user_page_asm)
 
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(clear_user_page_asm)
 
 ENTRY_CFI(flush_dcache_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%(TMPALIAS_MAP_START), %r28
 #ifdef CONFIG_64BIT
 #if (TMPALIAS_MAP_START >= 0x80000000)
@@ -903,16 +850,9 @@ ENTRY_CFI(flush_dcache_page_asm)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_dcache_page_asm)
 
 ENTRY_CFI(flush_icache_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%(TMPALIAS_MAP_START), %r28
 #ifdef CONFIG_64BIT
 #if (TMPALIAS_MAP_START >= 0x80000000)
@@ -977,16 +917,9 @@ ENTRY_CFI(flush_icache_page_asm)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_icache_page_asm)
 
 ENTRY_CFI(flush_kernel_dcache_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%dcache_stride, %r1
        ldw             R%dcache_stride(%r1), %r23
 
@@ -1020,16 +953,9 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_kernel_dcache_page_asm)
 
 ENTRY_CFI(purge_kernel_dcache_page_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%dcache_stride, %r1
        ldw             R%dcache_stride(%r1), %r23
 
@@ -1062,16 +988,9 @@ ENTRY_CFI(purge_kernel_dcache_page_asm)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(purge_kernel_dcache_page_asm)
 
 ENTRY_CFI(flush_user_dcache_range_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%dcache_stride, %r1
        ldw             R%dcache_stride(%r1), %r23
        ldo             -1(%r23), %r21
@@ -1083,16 +1002,9 @@ ENTRY_CFI(flush_user_dcache_range_asm)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_user_dcache_range_asm)
 
 ENTRY_CFI(flush_kernel_dcache_range_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%dcache_stride, %r1
        ldw             R%dcache_stride(%r1), %r23
        ldo             -1(%r23), %r21
@@ -1105,16 +1017,9 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
        syncdma
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_kernel_dcache_range_asm)
 
 ENTRY_CFI(purge_kernel_dcache_range_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%dcache_stride, %r1
        ldw             R%dcache_stride(%r1), %r23
        ldo             -1(%r23), %r21
@@ -1127,16 +1032,9 @@ ENTRY_CFI(purge_kernel_dcache_range_asm)
        syncdma
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(purge_kernel_dcache_range_asm)
 
 ENTRY_CFI(flush_user_icache_range_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%icache_stride, %r1
        ldw             R%icache_stride(%r1), %r23
        ldo             -1(%r23), %r21
@@ -1148,16 +1046,9 @@ ENTRY_CFI(flush_user_icache_range_asm)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_user_icache_range_asm)
 
 ENTRY_CFI(flush_kernel_icache_page)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%icache_stride, %r1
        ldw             R%icache_stride(%r1), %r23
 
@@ -1191,16 +1082,9 @@ ENTRY_CFI(flush_kernel_icache_page)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(flush_kernel_icache_page)
 
 ENTRY_CFI(flush_kernel_icache_range_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        ldil            L%icache_stride, %r1
        ldw             R%icache_stride(%r1), %r23
        ldo             -1(%r23), %r21
@@ -1212,8 +1096,6 @@ ENTRY_CFI(flush_kernel_icache_range_asm)
        sync
        bv              %r0(%r2)
        nop
-       .exit
-       .procend
 ENDPROC_CFI(flush_kernel_icache_range_asm)
 
        __INIT
@@ -1223,10 +1105,6 @@ ENDPROC_CFI(flush_kernel_icache_range_asm)
         */
        .align  256
 ENTRY_CFI(disable_sr_hashing_asm)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        /*
         * Switch to real mode
         */
@@ -1308,9 +1186,6 @@ srdis_done:
 
 2:      bv             %r0(%r2)
        nop
-       .exit
-
-       .procend
 ENDPROC_CFI(disable_sr_hashing_asm)
 
        .end
index b931745815e0f4e752ccd2c0b0342c5b49e69773..eb39e7e380d7e27b24f6bae39ae0e6c3583511e3 100644 (file)
@@ -302,7 +302,7 @@ get_wchan(struct task_struct *p)
                ip = info.ip;
                if (!in_sched_functions(ip))
                        return ip;
-       } while (count++ < 16);
+       } while (count++ < MAX_UNWIND_ENTRIES);
        return 0;
 }
 
index cc9963421a19377f3faea08bf2686611a0856816..2b16d8d6598f1d6015795a4455a24a4c039d0108 100644 (file)
@@ -35,12 +35,6 @@ real32_stack:
 real64_stack:
        .block  8192
 
-#ifdef CONFIG_64BIT
-#  define REG_SZ 8
-#else
-#  define REG_SZ 4
-#endif
-
 #define N_SAVED_REGS 9
 
 save_cr_space:
index 4309ad31a8743d5b39bfae82095e8a08b7cd0532..318815212518962bec3bf8391abd791ad30f6879 100644 (file)
@@ -172,7 +172,7 @@ static void do_show_stack(struct unwind_frame_info *info)
        int i = 1;
 
        printk(KERN_CRIT "Backtrace:\n");
-       while (i <= 16) {
+       while (i <= MAX_UNWIND_ENTRIES) {
                if (unwind_once(info) < 0 || info->ip == 0)
                        break;
 
index a4b430f440a91b095ffd98cd587121e3ae2b39c9..5cdf13069dd99d41e3f4d2061e4d82474296e80f 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/kallsyms.h>
 #include <linux/sort.h>
 
 #include <linux/uaccess.h>
@@ -117,7 +116,8 @@ unwind_table_init(struct unwind_table *table, const char *name,
        for (; start <= end; start++) {
                if (start < end && 
                    start->region_end > (start+1)->region_start) {
-                       printk("WARNING: Out of order unwind entry! %p and %p\n", start, start+1);
+                       pr_warn("Out of order unwind entry! %px and %px\n",
+                               start, start+1);
                }
 
                start->region_start += base_addr;
@@ -203,25 +203,60 @@ int __init unwind_init(void)
        return 0;
 }
 
-#ifdef CONFIG_64BIT
-#define get_func_addr(fptr) fptr[2]
-#else
-#define get_func_addr(fptr) fptr[0]
-#endif
-
 static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int frame_size)
 {
-       extern void handle_interruption(int, struct pt_regs *);
-       static unsigned long *hi = (unsigned long *)&handle_interruption;
-
-       if (pc == get_func_addr(hi)) {
+       /*
+        * We have to use void * instead of a function pointer, because
+        * function pointers aren't a pointer to the function on 64-bit.
+        * Make them const so the compiler knows they live in .text
+        */
+       extern void * const handle_interruption;
+       extern void * const ret_from_kernel_thread;
+       extern void * const syscall_exit;
+       extern void * const intr_return;
+       extern void * const _switch_to_ret;
+#ifdef CONFIG_IRQSTACKS
+       extern void * const call_on_stack;
+#endif /* CONFIG_IRQSTACKS */
+
+       if (pc == (unsigned long) &handle_interruption) {
                struct pt_regs *regs = (struct pt_regs *)(info->sp - frame_size - PT_SZ_ALGN);
                dbg("Unwinding through handle_interruption()\n");
                info->prev_sp = regs->gr[30];
                info->prev_ip = regs->iaoq[0];
+               return 1;
+       }
+
+       if (pc == (unsigned long) &ret_from_kernel_thread ||
+           pc == (unsigned long) &syscall_exit) {
+               info->prev_sp = info->prev_ip = 0;
+               return 1;
+       }
+
+       if (pc == (unsigned long) &intr_return) {
+               struct pt_regs *regs;
+
+               dbg("Found intr_return()\n");
+               regs = (struct pt_regs *)(info->sp - PT_SZ_ALGN);
+               info->prev_sp = regs->gr[30];
+               info->prev_ip = regs->iaoq[0];
+               info->rp = regs->gr[2];
+               return 1;
+       }
+
+       if (pc == (unsigned long) &_switch_to_ret) {
+               info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
+               info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
+               return 1;
+       }
 
+#ifdef CONFIG_IRQSTACKS
+       if (pc == (unsigned long) &call_on_stack) {
+               info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
+               info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
                return 1;
        }
+#endif
 
        return 0;
 }
@@ -238,34 +273,8 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
        if (e == NULL) {
                unsigned long sp;
 
-               dbg("Cannot find unwind entry for 0x%lx; forced unwinding\n", info->ip);
-
-#ifdef CONFIG_KALLSYMS
-               /* Handle some frequent special cases.... */
-               {
-                       char symname[KSYM_NAME_LEN];
-                       char *modname;
-
-                       kallsyms_lookup(info->ip, NULL, NULL, &modname,
-                               symname);
-
-                       dbg("info->ip = 0x%lx, name = %s\n", info->ip, symname);
-
-                       if (strcmp(symname, "_switch_to_ret") == 0) {
-                               info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
-                               info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
-                               dbg("_switch_to_ret @ %lx - setting "
-                                   "prev_sp=%lx prev_ip=%lx\n", 
-                                   info->ip, info->prev_sp, 
-                                   info->prev_ip);
-                               return;
-                       } else if (strcmp(symname, "ret_from_kernel_thread") == 0 ||
-                                  strcmp(symname, "syscall_exit") == 0) {
-                               info->prev_ip = info->prev_sp = 0;
-                               return;
-                       }
-               }
-#endif
+               dbg("Cannot find unwind entry for %pS; forced unwinding\n",
+                       (void *) info->ip);
 
                /* Since we are doing the unwinding blind, we don't know if
                   we are adjusting the stack correctly or extracting the rp
index d4fe19806d57764144e0b52e9feddc83a18fc160..b53fb6fedf06c466f8ad8ed738c49171a4bcdda5 100644 (file)
@@ -64,9 +64,6 @@
         */
 
 ENTRY_CFI(lclear_user)
-       .proc
-       .callinfo NO_CALLS
-       .entry
        comib,=,n   0,%r25,$lclu_done
        get_sr
 $lclu_loop:
@@ -81,13 +78,9 @@ $lclu_done:
        ldo         1(%r25),%r25
 
        ASM_EXCEPTIONTABLE_ENTRY(1b,2b)
-
-       .exit
 ENDPROC_CFI(lclear_user)
 
 
-       .procend
-
        /*
         * long lstrnlen_user(char *s, long n)
         *
@@ -97,9 +90,6 @@ ENDPROC_CFI(lclear_user)
         */
 
 ENTRY_CFI(lstrnlen_user)
-       .proc
-       .callinfo NO_CALLS
-       .entry
        comib,=     0,%r25,$lslen_nzero
        copy        %r26,%r24
        get_sr
@@ -111,7 +101,6 @@ $lslen_loop:
 $lslen_done:
        bv          %r0(%r2)
        sub         %r26,%r24,%r28
-       .exit
 
 $lslen_nzero:
        b           $lslen_done
@@ -125,9 +114,6 @@ $lslen_nzero:
 
 ENDPROC_CFI(lstrnlen_user)
 
-       .procend
-
-
 
 /*
  * unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
@@ -186,10 +172,6 @@ ENDPROC_CFI(lstrnlen_user)
        save_len = r31
 
 ENTRY_CFI(pa_memcpy)
-       .proc
-       .callinfo NO_CALLS
-       .entry
-
        /* Last destination address */
        add     dst,len,end
 
@@ -439,9 +421,6 @@ ENTRY_CFI(pa_memcpy)
        b       .Lcopy_done
 10:    stw,ma  t1,4(dstspc,dst)
        ASM_EXCEPTIONTABLE_ENTRY(10b,.Lcopy_done)
-
-       .exit
 ENDPROC_CFI(pa_memcpy)
-       .procend
 
        .end