mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-26 13:45:08 +07:00
325cdacd03
Mike Galbraith reported a situation where a WARN_ON_ONCE() call in DRM code turned into an oops. As it turns out, WARN_ON_ONCE() seems to be completely broken when called from a module. The bug was introduced with the following commit:19d436268d
("debug: Add _ONCE() logic to report_bug()") That commit changed WARN_ON_ONCE() to move its 'once' logic into the bug trap handler. It requires a writable bug table so that the BUGFLAG_DONE bit can be written to the flags to indicate the first warning has occurred. The bug table was made writable for vmlinux, which relies on vmlinux.lds.S and vmlinux.lds.h for laying out the sections. However, it wasn't made writable for modules, which rely on the ELF section header flags. Reported-by: Mike Galbraith <efault@gmx.de> Tested-by: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Fixes:19d436268d
("debug: Add _ONCE() logic to report_bug()") Link: http://lkml.kernel.org/r/a53b04235a65478dd9afc51f5b329fdc65c84364.1500095401.git.jpoimboe@redhat.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
74 lines
1.5 KiB
C
74 lines
1.5 KiB
C
/*
|
|
* Copyright 2004-2009 Analog Devices Inc.
|
|
*
|
|
* Licensed under the GPL-2 or later.
|
|
*/
|
|
|
|
#ifndef _BLACKFIN_BUG_H
|
|
#define _BLACKFIN_BUG_H
|
|
|
|
#ifdef CONFIG_BUG
|
|
|
|
/*
|
|
* This can be any undefined 16-bit opcode, meaning
|
|
* ((opcode & 0xc000) != 0xc000)
|
|
* Anything from 0x0001 to 0x000A (inclusive) will work
|
|
*/
|
|
#define BFIN_BUG_OPCODE 0x0001
|
|
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
|
|
#define _BUG_OR_WARN(flags) \
|
|
asm volatile( \
|
|
"1: .hword %0\n" \
|
|
" .section __bug_table,\"aw\",@progbits\n" \
|
|
"2: .long 1b\n" \
|
|
" .long %1\n" \
|
|
" .short %2\n" \
|
|
" .short %3\n" \
|
|
" .org 2b + %4\n" \
|
|
" .previous" \
|
|
: \
|
|
: "i"(BFIN_BUG_OPCODE), "i"(__FILE__), \
|
|
"i"(__LINE__), "i"(flags), \
|
|
"i"(sizeof(struct bug_entry)))
|
|
|
|
#else
|
|
|
|
#define _BUG_OR_WARN(flags) \
|
|
asm volatile( \
|
|
"1: .hword %0\n" \
|
|
" .section __bug_table,\"aw\",@progbits\n" \
|
|
"2: .long 1b\n" \
|
|
" .short %1\n" \
|
|
" .org 2b + %2\n" \
|
|
" .previous" \
|
|
: \
|
|
: "i"(BFIN_BUG_OPCODE), "i"(flags), \
|
|
"i"(sizeof(struct bug_entry)))
|
|
|
|
#endif /* CONFIG_DEBUG_BUGVERBOSE */
|
|
|
|
#define BUG() \
|
|
do { \
|
|
_BUG_OR_WARN(0); \
|
|
unreachable(); \
|
|
} while (0)
|
|
|
|
#define WARN_ON(condition) \
|
|
({ \
|
|
int __ret_warn_on = !!(condition); \
|
|
if (unlikely(__ret_warn_on)) \
|
|
_BUG_OR_WARN(BUGFLAG_WARNING); \
|
|
unlikely(__ret_warn_on); \
|
|
})
|
|
|
|
#define HAVE_ARCH_BUG
|
|
#define HAVE_ARCH_WARN_ON
|
|
|
|
#endif
|
|
|
|
#include <asm-generic/bug.h>
|
|
|
|
#endif
|