mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
de985dd501
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 parameter 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: Guan Xuetao <gxt@pku.edu.cn> Link: http://lkml.kernel.org/r/20200418201944.482088-39-dima@arista.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
169 lines
3.7 KiB
ArmAsm
169 lines
3.7 KiB
ArmAsm
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* linux/arch/unicore32/lib/backtrace.S
|
|
*
|
|
* Code specific to PKUnity SoC and UniCore ISA
|
|
*
|
|
* Copyright (C) 2001-2010 GUAN Xue-tao
|
|
*/
|
|
#include <linux/linkage.h>
|
|
#include <asm/assembler.h>
|
|
.text
|
|
|
|
@ fp is 0 or stack frame
|
|
|
|
#define frame v4
|
|
#define sv_fp v5
|
|
#define sv_pc v6
|
|
#define offset v8
|
|
#define loglvl v9
|
|
|
|
ENTRY(__backtrace)
|
|
mov r0, fp
|
|
|
|
ENTRY(c_backtrace)
|
|
|
|
#if !defined(CONFIG_FRAME_POINTER) || !defined(CONFIG_PRINTK)
|
|
mov pc, lr
|
|
ENDPROC(__backtrace)
|
|
ENDPROC(c_backtrace)
|
|
#else
|
|
stm.w (v4 - v10, lr), [sp-] @ Save an extra register
|
|
@ so we have a location...
|
|
mov.a frame, r0 @ if frame pointer is zero
|
|
beq no_frame @ we have no stack frames
|
|
mov loglvl, r1
|
|
|
|
1: stm.w (pc), [sp-] @ calculate offset of PC stored
|
|
ldw.w r0, [sp]+, #4 @ by stmfd for this CPU
|
|
adr r1, 1b
|
|
sub offset, r0, r1
|
|
|
|
/*
|
|
* Stack frame layout:
|
|
* optionally saved caller registers (r4 - r10)
|
|
* saved fp
|
|
* saved sp
|
|
* saved lr
|
|
* frame => saved pc
|
|
* optionally saved arguments (r0 - r3)
|
|
* saved sp => <next word>
|
|
*
|
|
* Functions start with the following code sequence:
|
|
* mov ip, sp
|
|
* stm.w (r0 - r3), [sp-] (optional)
|
|
* corrected pc => stm.w sp, (..., fp, ip, lr, pc)
|
|
*/
|
|
for_each_frame:
|
|
|
|
1001: ldw sv_pc, [frame+], #0 @ get saved pc
|
|
1002: ldw sv_fp, [frame+], #-12 @ get saved fp
|
|
|
|
sub sv_pc, sv_pc, offset @ Correct PC for prefetching
|
|
|
|
1003: ldw r2, [sv_pc+], #-4 @ if stmfd sp, {args} exists,
|
|
ldw r3, .Ldsi+4 @ adjust saved 'pc' back one
|
|
cxor.a r3, r2 >> #14 @ instruction
|
|
beq 201f
|
|
sub r0, sv_pc, #4 @ allow for mov
|
|
b 202f
|
|
201:
|
|
sub r0, sv_pc, #8 @ allow for mov + stmia
|
|
202:
|
|
ldw r1, [frame+], #-4 @ get saved lr
|
|
mov r2, frame
|
|
b.l dump_backtrace_entry
|
|
|
|
ldw r1, [sv_pc+], #-4 @ if stmfd sp, {args} exists,
|
|
ldw r3, .Ldsi+4
|
|
cxor.a r3, r1 >> #14
|
|
bne 1004f
|
|
ldw r0, [frame+], #-8 @ get sp
|
|
sub r0, r0, #4 @ point at the last arg
|
|
b.l .Ldumpstm @ dump saved registers
|
|
|
|
1004: ldw r1, [sv_pc+], #0 @ if stmfd {, fp, ip, lr, pc}
|
|
ldw r3, .Ldsi @ instruction exists,
|
|
cxor.a r3, r1 >> #14
|
|
bne 201f
|
|
sub r0, frame, #16
|
|
b.l .Ldumpstm @ dump saved registers
|
|
201:
|
|
cxor.a sv_fp, #0 @ zero saved fp means
|
|
beq no_frame @ no further frames
|
|
|
|
csub.a sv_fp, frame @ next frame must be
|
|
mov frame, sv_fp @ above the current frame
|
|
bua for_each_frame
|
|
|
|
1006: adr r0, .Lbad
|
|
mov r1, loglvl
|
|
mov r2, frame
|
|
b.l printk
|
|
no_frame: ldm.w (v4 - v10, pc), [sp]+
|
|
ENDPROC(__backtrace)
|
|
ENDPROC(c_backtrace)
|
|
|
|
.pushsection __ex_table,"a"
|
|
.align 3
|
|
.long 1001b, 1006b
|
|
.long 1002b, 1006b
|
|
.long 1003b, 1006b
|
|
.long 1004b, 1006b
|
|
.popsection
|
|
|
|
#define instr v4
|
|
#define reg v5
|
|
#define stack v6
|
|
|
|
.Ldumpstm: stm.w (instr, reg, stack, v7, lr), [sp-]
|
|
mov stack, r0
|
|
mov instr, r1
|
|
mov reg, #14
|
|
mov v7, #0
|
|
1: mov r3, #1
|
|
csub.a reg, #8
|
|
bne 201f
|
|
sub reg, reg, #3
|
|
201:
|
|
cand.a instr, r3 << reg
|
|
beq 2f
|
|
add v7, v7, #1
|
|
cxor.a v7, #6
|
|
cmoveq v7, #1
|
|
bne 201f
|
|
adr r0, .Lcr
|
|
mov r1, loglvl
|
|
b.l printk
|
|
201:
|
|
ldw.w r3, [stack]+, #-4
|
|
mov r2, reg
|
|
csub.a r2, #8
|
|
bsl 201f
|
|
sub r2, r2, #3
|
|
201:
|
|
cand.a instr, #0x40 @ if H is 1, high 16 regs
|
|
beq 201f
|
|
add r2, r2, #0x10 @ so r2 need add 16
|
|
201:
|
|
adr r0, .Lfp
|
|
mov r1, loglvl
|
|
b.l printk
|
|
2: sub.a reg, reg, #1
|
|
bns 1b
|
|
cxor.a v7, #0
|
|
beq 201f
|
|
adr r0, .Lcr
|
|
mov r1, loglvl
|
|
b.l printk
|
|
201: ldm.w (instr, reg, stack, v7, pc), [sp]+
|
|
|
|
.Lfp: .asciz "%sr%d:%08x "
|
|
.Lcr: .asciz "%s\n"
|
|
.Lbad: .asciz "%sBacktrace aborted due to bad frame pointer <%p>\n"
|
|
.align
|
|
.Ldsi: .word 0x92eec000 >> 14 @ stm.w sp, (... fp, ip, lr, pc)
|
|
.word 0x92e10000 >> 14 @ stm.w sp, ()
|
|
|
|
#endif
|