mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-17 07:54:54 +08:00
5489ab50c2
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>
93 lines
2.5 KiB
C
93 lines
2.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASMARM_BUG_H
|
|
#define _ASMARM_BUG_H
|
|
|
|
#include <linux/linkage.h>
|
|
#include <linux/types.h>
|
|
#include <asm/opcodes.h>
|
|
|
|
/*
|
|
* Use a suitable undefined instruction to use for ARM/Thumb2 bug handling.
|
|
* We need to be careful not to conflict with those used by other modules and
|
|
* the register_undef_hook() system.
|
|
*/
|
|
#ifdef CONFIG_THUMB2_KERNEL
|
|
#define BUG_INSTR_VALUE 0xde02
|
|
#define BUG_INSTR(__value) __inst_thumb16(__value)
|
|
#else
|
|
#define BUG_INSTR_VALUE 0xe7f001f2
|
|
#define BUG_INSTR(__value) __inst_arm(__value)
|
|
#endif
|
|
|
|
|
|
#define BUG() _BUG(__FILE__, __LINE__, BUG_INSTR_VALUE)
|
|
#define _BUG(file, line, value) __BUG(file, line, value)
|
|
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
|
|
/*
|
|
* The extra indirection is to ensure that the __FILE__ string comes through
|
|
* OK. Many version of gcc do not support the asm %c parameter which would be
|
|
* preferable to this unpleasantness. We use mergeable string sections to
|
|
* avoid multiple copies of the string appearing in the kernel image.
|
|
*/
|
|
|
|
#define __BUG(__file, __line, __value) \
|
|
do { \
|
|
asm volatile("1:\t" BUG_INSTR(__value) "\n" \
|
|
".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
|
|
"2:\t.asciz " #__file "\n" \
|
|
".popsection\n" \
|
|
".pushsection __bug_table,\"aw\"\n" \
|
|
".align 2\n" \
|
|
"3:\t.word 1b, 2b\n" \
|
|
"\t.hword " #__line ", 0\n" \
|
|
".popsection"); \
|
|
unreachable(); \
|
|
} while (0)
|
|
|
|
#else
|
|
|
|
#define __BUG(__file, __line, __value) \
|
|
do { \
|
|
asm volatile(BUG_INSTR(__value) "\n"); \
|
|
unreachable(); \
|
|
} while (0)
|
|
#endif /* CONFIG_DEBUG_BUGVERBOSE */
|
|
|
|
#define HAVE_ARCH_BUG
|
|
|
|
#include <asm-generic/bug.h>
|
|
|
|
struct pt_regs;
|
|
void die(const char *msg, struct pt_regs *regs, int err);
|
|
|
|
void arm_notify_die(const char *str, struct pt_regs *regs,
|
|
int signo, int si_code, void __user *addr,
|
|
unsigned long err, unsigned long trap);
|
|
|
|
#ifdef CONFIG_ARM_LPAE
|
|
#define FAULT_CODE_ALIGNMENT 33
|
|
#define FAULT_CODE_DEBUG 34
|
|
#else
|
|
#define FAULT_CODE_ALIGNMENT 1
|
|
#define FAULT_CODE_DEBUG 2
|
|
#endif
|
|
|
|
void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
|
|
struct pt_regs *),
|
|
int sig, int code, const char *name);
|
|
|
|
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,
|
|
const char *loglvl);
|
|
|
|
struct mm_struct;
|
|
void show_pte(const char *lvl, struct mm_struct *mm, unsigned long addr);
|
|
extern void __show_regs(struct pt_regs *);
|
|
|
|
#endif
|