]> git.baikalelectronics.ru Git - kernel.git/commitdiff
arm/asm: add loglvl to c_backtrace()
authorDmitry Safonov <dima@arista.com>
Tue, 9 Jun 2020 04:30:07 +0000 (21:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jun 2020 16:39:10 +0000 (09:39 -0700)
Currently, the log-level of show_stack() depends on a platform
realization.  It creates situations where the headers are printed with
lower log level or higher than the stacktrace (depending on a platform or
user).

Furthermore, it forces the logic decision from user to an architecture
side.  In result, some users as sysrq/kdb/etc are doing tricks with
temporary rising console_loglevel while printing their messages.  And in
result it not only may print unwanted messages from other CPUs, but also
omit printing at all in the unlucky case where the printk() was deferred.

Introducing log-level parameter and KERN_UNSUPPRESSED [1] seems an easier
approach than introducing more printk buffers.  Also, it will consolidate
printings with headers.

Add log level argument to c_backtrace() as a preparation for introducing
show_stack_loglvl().

[1]: https://lore.kernel.org/lkml/20190528002412.1625-1-dima@arista.com/T/#u

Signed-off-by: Dmitry Safonov <dima@arista.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Russell King <linux@armlinux.org.uk>
Cc: Will Deacon <will@kernel.org>
Link: http://lkml.kernel.org/r/20200418201944.482088-5-dima@arista.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/arm/include/asm/bug.h
arch/arm/include/asm/traps.h
arch/arm/kernel/traps.c
arch/arm/kernel/unwind.c
arch/arm/lib/backtrace-clang.S
arch/arm/lib/backtrace.S

index deef4d0cb3b50030c621eb200c2226af6b1f6685..673c7dd75ab90c0a6475bacde3adec9743adfd15 100644 (file)
@@ -82,7 +82,8 @@ void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
                                       struct pt_regs *),
                     int sig, int code, const char *name);
 
-extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
+extern asmlinkage void c_backtrace(unsigned long fp, int pmode,
+                                  const char *loglvl);
 
 struct mm_struct;
 void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr);
index 172b08ff3760d43bc46306b630a64646b65d5a72..987fefb0a4dbc452fda484512cedf6818838d965 100644 (file)
@@ -29,7 +29,8 @@ static inline int __in_irqentry_text(unsigned long ptr)
 }
 
 extern void __init early_trap_init(void *);
-extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
+extern void dump_backtrace_entry(unsigned long where, unsigned long from,
+                                unsigned long frame, const char *loglvl);
 extern void ptrace_break(struct pt_regs *regs);
 
 extern void *vectors_page;
index 316a7687f8133356979b2f26701daaa00b2c34cb..7bba15fdce9f6f26813e171d688e0d1fb6fba0a9 100644 (file)
@@ -62,7 +62,8 @@ __setup("user_debug=", user_debug_setup);
 
 static void dump_mem(const char *, const char *, unsigned long, unsigned long);
 
-void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
+void dump_backtrace_entry(unsigned long where, unsigned long from,
+                         unsigned long frame, const char *loglvl)
 {
        unsigned long end = frame + 4 + sizeof(struct pt_regs);
 
@@ -76,7 +77,7 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long
                dump_mem("", "Exception stack", frame + 4, end);
 }
 
-void dump_backtrace_stm(u32 *stack, u32 instruction)
+void dump_backtrace_stm(u32 *stack, u32 instruction, const char *loglvl)
 {
        char str[80], *p;
        unsigned int x;
@@ -238,7 +239,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
        pr_cont("\n");
 
        if (ok)
-               c_backtrace(fp, mode);
+               c_backtrace(fp, mode, NULL);
 }
 #endif
 
@@ -666,7 +667,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
                dump_instr("", regs);
                if (user_mode(regs)) {
                        __show_regs(regs);
-                       c_backtrace(frame_pointer(regs), processor_mode(regs));
+                       c_backtrace(frame_pointer(regs), processor_mode(regs), NULL);
                }
        }
 #endif
index 11a964fd66f474b7090a45cf8f65938c65bd12d2..343cc27b36c4c131dfe70250bb47b7f0740ee2d0 100644 (file)
@@ -493,7 +493,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
                urc = unwind_frame(&frame);
                if (urc < 0)
                        break;
-               dump_backtrace_entry(where, frame.pc, frame.sp - 4);
+               dump_backtrace_entry(where, frame.pc, frame.sp - 4, NULL);
        }
 }
 
index 2ff375144b55b0347240441205f476aae1a837cc..6174c45f53a5dbfc8c0e2de3de8175b6e17a8d5e 100644 (file)
@@ -17,6 +17,7 @@
 #define sv_pc  r6
 #define mask   r7
 #define sv_lr  r8
+#define loglvl r9
 
 ENTRY(c_backtrace)
 
@@ -99,6 +100,7 @@ ENDPROC(c_backtrace)
                                                @ to ensure 8 byte alignment
                movs    frame, r0               @ if frame pointer is zero
                beq     no_frame                @ we have no stack frames
+               mov     loglvl, r2
                tst     r1, #0x10               @ 26 or 32-bit mode?
                moveq   mask, #0xfc000003
                movne   mask, #0                @ mask for 32-bit
@@ -167,6 +169,7 @@ finished_setup:
                mov     r1, sv_lr
                mov     r2, frame
                bic     r1, r1, mask            @ mask PC/LR for the mode
+               mov     r3, loglvl
                bl      dump_backtrace_entry
 
 /*
@@ -183,6 +186,7 @@ finished_setup:
                ldr     r0, [frame]             @ locals are stored in
                                                @ the preceding frame
                subeq   r0, r0, #4
+               mov     r2, loglvl
                bleq    dump_backtrace_stm      @ dump saved registers
 
 /*
@@ -196,7 +200,8 @@ finished_setup:
                bhi     for_each_frame
 
 1006:          adr     r0, .Lbad
-               mov     r1, frame
+               mov     r1, loglvl
+               mov     r2, frame
                bl      printk
 no_frame:      ldmfd   sp!, {r4 - r9, fp, pc}
 ENDPROC(c_backtrace)
@@ -209,7 +214,7 @@ ENDPROC(c_backtrace)
                .long   1005b, 1006b
                .popsection
 
-.Lbad:         .asciz  "Backtrace aborted due to bad frame pointer <%p>\n"
+.Lbad:         .asciz  "%sBacktrace aborted due to bad frame pointer <%p>\n"
                .align
 .Lopcode:      .word   0xe92d4800 >> 11        @ stmfd sp!, {... fp, lr}
                .word   0x0b000000              @ bl if these bits are set
index 582925238d65ea261cc126078462ce2a66421549..872f658638d99710710963266900701a3a69c2a7 100644 (file)
@@ -18,6 +18,7 @@
 #define sv_pc  r6
 #define mask   r7
 #define offset r8
+#define loglvl r9
 
 ENTRY(c_backtrace)
 
@@ -25,9 +26,10 @@ ENTRY(c_backtrace)
                ret     lr
 ENDPROC(c_backtrace)
 #else
-               stmfd   sp!, {r4 - r8, lr}      @ Save an extra register so we have a location...
+               stmfd   sp!, {r4 - r9, lr}      @ Save an extra register so we have a location...
                movs    frame, r0               @ if frame pointer is zero
                beq     no_frame                @ we have no stack frames
+               mov     loglvl, r2
 
                tst     r1, #0x10               @ 26 or 32-bit mode?
  ARM(          moveq   mask, #0xfc000003       )
@@ -73,6 +75,7 @@ for_each_frame:       tst     frame, mask             @ Check for address exceptions
                ldr     r1, [frame, #-4]        @ get saved lr
                mov     r2, frame
                bic     r1, r1, mask            @ mask PC/LR for the mode
+               mov     r3, loglvl
                bl      dump_backtrace_entry
 
                ldr     r1, [sv_pc, #-4]        @ if stmfd sp!, {args} exists,
@@ -80,12 +83,14 @@ for_each_frame:     tst     frame, mask             @ Check for address exceptions
                teq     r3, r1, lsr #11
                ldreq   r0, [frame, #-8]        @ get sp
                subeq   r0, r0, #4              @ point at the last arg
+               mov     r2, loglvl
                bleq    dump_backtrace_stm      @ dump saved registers
 
 1004:          ldr     r1, [sv_pc, #0]         @ if stmfd sp!, {..., fp, ip, lr, pc}
                ldr     r3, .Ldsi               @ instruction exists,
                teq     r3, r1, lsr #11
                subeq   r0, frame, #16
+               mov     r2, loglvl
                bleq    dump_backtrace_stm      @ dump saved registers
 
                teq     sv_fp, #0               @ zero saved fp means
@@ -96,9 +101,10 @@ for_each_frame:     tst     frame, mask             @ Check for address exceptions
                bhi     for_each_frame
 
 1006:          adr     r0, .Lbad
-               mov     r1, frame
+               mov     r1, loglvl
+               mov     r2, frame
                bl      printk
-no_frame:      ldmfd   sp!, {r4 - r8, pc}
+no_frame:      ldmfd   sp!, {r4 - r9, pc}
 ENDPROC(c_backtrace)
                
                .pushsection __ex_table,"a"
@@ -109,7 +115,7 @@ ENDPROC(c_backtrace)
                .long   1004b, 1006b
                .popsection
 
-.Lbad:         .asciz  "Backtrace aborted due to bad frame pointer <%p>\n"
+.Lbad:         .asciz  "%sBacktrace aborted due to bad frame pointer <%p>\n"
                .align
 .Ldsi:         .word   0xe92dd800 >> 11        @ stmfd sp!, {... fp, ip, lr, pc}
                .word   0xe92d0000 >> 11        @ stmfd sp!, {}