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>
 
                                       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);
 
 }
 
 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;
 
 
 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);
 
                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;
        pr_cont("\n");
 
        if (ok)
-               c_backtrace(fp, mode);
+               c_backtrace(fp, mode, NULL);
 }
 #endif
 
                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
 
                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);
        }
 }
 
 
 #define sv_pc  r6
 #define mask   r7
 #define sv_lr  r8
+#define loglvl r9
 
 ENTRY(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
                mov     r1, sv_lr
                mov     r2, frame
                bic     r1, r1, mask            @ mask PC/LR for the mode
+               mov     r3, loglvl
                bl      dump_backtrace_entry
 
 /*
                ldr     r0, [frame]             @ locals are stored in
                                                @ the preceding frame
                subeq   r0, r0, #4
+               mov     r2, loglvl
                bleq    dump_backtrace_stm      @ dump saved registers
 
 /*
                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)
                .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
 
 #define sv_pc  r6
 #define mask   r7
 #define offset r8
+#define loglvl r9
 
 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       )
                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,
                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
                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"
                .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!, {}