debug: Fix WARN_ON_ONCE() for modules

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>
This commit is contained in:
Josh Poimboeuf
2017-07-15 00:10:58 -05:00
committed by Ingo Molnar
parent 095f6d7622
commit 325cdacd03
9 changed files with 18 additions and 18 deletions

View File

@@ -37,7 +37,7 @@ do { \
".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \ ".pushsection .rodata.str, \"aMS\", %progbits, 1\n" \
"2:\t.asciz " #__file "\n" \ "2:\t.asciz " #__file "\n" \
".popsection\n" \ ".popsection\n" \
".pushsection __bug_table,\"a\"\n" \ ".pushsection __bug_table,\"aw\"\n" \
".align 2\n" \ ".align 2\n" \
"3:\t.word 1b, 2b\n" \ "3:\t.word 1b, 2b\n" \
"\t.hword " #__line ", 0\n" \ "\t.hword " #__line ", 0\n" \

View File

@@ -36,7 +36,7 @@
#ifdef CONFIG_GENERIC_BUG #ifdef CONFIG_GENERIC_BUG
#define __BUG_ENTRY(flags) \ #define __BUG_ENTRY(flags) \
".pushsection __bug_table,\"a\"\n\t" \ ".pushsection __bug_table,\"aw\"\n\t" \
".align 2\n\t" \ ".align 2\n\t" \
"0: .long 1f - 0b\n\t" \ "0: .long 1f - 0b\n\t" \
_BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ _BUGVERBOSE_LOCATION(__FILE__, __LINE__) \

View File

@@ -21,7 +21,7 @@
#define _BUG_OR_WARN(flags) \ #define _BUG_OR_WARN(flags) \
asm volatile( \ asm volatile( \
"1: .hword %0\n" \ "1: .hword %0\n" \
" .section __bug_table,\"a\",@progbits\n" \ " .section __bug_table,\"aw\",@progbits\n" \
"2: .long 1b\n" \ "2: .long 1b\n" \
" .long %1\n" \ " .long %1\n" \
" .short %2\n" \ " .short %2\n" \
@@ -38,7 +38,7 @@
#define _BUG_OR_WARN(flags) \ #define _BUG_OR_WARN(flags) \
asm volatile( \ asm volatile( \
"1: .hword %0\n" \ "1: .hword %0\n" \
" .section __bug_table,\"a\",@progbits\n" \ " .section __bug_table,\"aw\",@progbits\n" \
"2: .long 1b\n" \ "2: .long 1b\n" \
" .short %1\n" \ " .short %1\n" \
" .org 2b + %2\n" \ " .org 2b + %2\n" \

View File

@@ -21,7 +21,7 @@ do { \
asm volatile( \ asm volatile( \
" syscall 15 \n" \ " syscall 15 \n" \
"0: \n" \ "0: \n" \
" .section __bug_table,\"a\" \n" \ " .section __bug_table,\"aw\" \n" \
" .long 0b,%0,%1 \n" \ " .long 0b,%0,%1 \n" \
" .previous \n" \ " .previous \n" \
: \ : \

View File

@@ -27,7 +27,7 @@
do { \ do { \
asm volatile("\n" \ asm volatile("\n" \
"1:\t" PARISC_BUG_BREAK_ASM "\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \
"\t.pushsection __bug_table,\"a\"\n" \ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t" ASM_WORD_INSN "1b, %c0\n" \ "2:\t" ASM_WORD_INSN "1b, %c0\n" \
"\t.short %c1, %c2\n" \ "\t.short %c1, %c2\n" \
"\t.org 2b+%c3\n" \ "\t.org 2b+%c3\n" \
@@ -50,7 +50,7 @@
do { \ do { \
asm volatile("\n" \ asm volatile("\n" \
"1:\t" PARISC_BUG_BREAK_ASM "\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \
"\t.pushsection __bug_table,\"a\"\n" \ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t" ASM_WORD_INSN "1b, %c0\n" \ "2:\t" ASM_WORD_INSN "1b, %c0\n" \
"\t.short %c1, %c2\n" \ "\t.short %c1, %c2\n" \
"\t.org 2b+%c3\n" \ "\t.org 2b+%c3\n" \
@@ -64,7 +64,7 @@
do { \ do { \
asm volatile("\n" \ asm volatile("\n" \
"1:\t" PARISC_BUG_BREAK_ASM "\n" \ "1:\t" PARISC_BUG_BREAK_ASM "\n" \
"\t.pushsection __bug_table,\"a\"\n" \ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t" ASM_WORD_INSN "1b\n" \ "2:\t" ASM_WORD_INSN "1b\n" \
"\t.short %c0\n" \ "\t.short %c0\n" \
"\t.org 2b+%c1\n" \ "\t.org 2b+%c1\n" \

View File

@@ -18,7 +18,7 @@
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
.macro EMIT_BUG_ENTRY addr,file,line,flags .macro EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"a" .section __bug_table,"aw"
5001: PPC_LONG \addr, 5002f 5001: PPC_LONG \addr, 5002f
.short \line, \flags .short \line, \flags
.org 5001b+BUG_ENTRY_SIZE .org 5001b+BUG_ENTRY_SIZE
@@ -29,7 +29,7 @@
.endm .endm
#else #else
.macro EMIT_BUG_ENTRY addr,file,line,flags .macro EMIT_BUG_ENTRY addr,file,line,flags
.section __bug_table,"a" .section __bug_table,"aw"
5001: PPC_LONG \addr 5001: PPC_LONG \addr
.short \flags .short \flags
.org 5001b+BUG_ENTRY_SIZE .org 5001b+BUG_ENTRY_SIZE
@@ -42,14 +42,14 @@
sizeof(struct bug_entry), respectively */ sizeof(struct bug_entry), respectively */
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
#define _EMIT_BUG_ENTRY \ #define _EMIT_BUG_ENTRY \
".section __bug_table,\"a\"\n" \ ".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "1b, %0\n" \ "2:\t" PPC_LONG "1b, %0\n" \
"\t.short %1, %2\n" \ "\t.short %1, %2\n" \
".org 2b+%3\n" \ ".org 2b+%3\n" \
".previous\n" ".previous\n"
#else #else
#define _EMIT_BUG_ENTRY \ #define _EMIT_BUG_ENTRY \
".section __bug_table,\"a\"\n" \ ".section __bug_table,\"aw\"\n" \
"2:\t" PPC_LONG "1b\n" \ "2:\t" PPC_LONG "1b\n" \
"\t.short %2\n" \ "\t.short %2\n" \
".org 2b+%3\n" \ ".org 2b+%3\n" \

View File

@@ -14,7 +14,7 @@
".section .rodata.str,\"aMS\",@progbits,1\n" \ ".section .rodata.str,\"aMS\",@progbits,1\n" \
"2: .asciz \""__FILE__"\"\n" \ "2: .asciz \""__FILE__"\"\n" \
".previous\n" \ ".previous\n" \
".section __bug_table,\"a\"\n" \ ".section __bug_table,\"aw\"\n" \
"3: .long 1b-3b,2b-3b\n" \ "3: .long 1b-3b,2b-3b\n" \
" .short %0,%1\n" \ " .short %0,%1\n" \
" .org 3b+%2\n" \ " .org 3b+%2\n" \
@@ -30,7 +30,7 @@
asm volatile( \ asm volatile( \
"0: j 0b+2\n" \ "0: j 0b+2\n" \
"1:\n" \ "1:\n" \
".section __bug_table,\"a\"\n" \ ".section __bug_table,\"aw\"\n" \
"2: .long 1b-2b\n" \ "2: .long 1b-2b\n" \
" .short %0\n" \ " .short %0\n" \
" .org 2b+%1\n" \ " .org 2b+%1\n" \

View File

@@ -24,14 +24,14 @@
*/ */
#ifdef CONFIG_DEBUG_BUGVERBOSE #ifdef CONFIG_DEBUG_BUGVERBOSE
#define _EMIT_BUG_ENTRY \ #define _EMIT_BUG_ENTRY \
"\t.pushsection __bug_table,\"a\"\n" \ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t.long 1b, %O1\n" \ "2:\t.long 1b, %O1\n" \
"\t.short %O2, %O3\n" \ "\t.short %O2, %O3\n" \
"\t.org 2b+%O4\n" \ "\t.org 2b+%O4\n" \
"\t.popsection\n" "\t.popsection\n"
#else #else
#define _EMIT_BUG_ENTRY \ #define _EMIT_BUG_ENTRY \
"\t.pushsection __bug_table,\"a\"\n" \ "\t.pushsection __bug_table,\"aw\"\n" \
"2:\t.long 1b\n" \ "2:\t.long 1b\n" \
"\t.short %O3\n" \ "\t.short %O3\n" \
"\t.org 2b+%O4\n" \ "\t.org 2b+%O4\n" \

View File

@@ -35,7 +35,7 @@
#define _BUG_FLAGS(ins, flags) \ #define _BUG_FLAGS(ins, flags) \
do { \ do { \
asm volatile("1:\t" ins "\n" \ asm volatile("1:\t" ins "\n" \
".pushsection __bug_table,\"a\"\n" \ ".pushsection __bug_table,\"aw\"\n" \
"2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
"\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \ "\t" __BUG_REL(%c0) "\t# bug_entry::file\n" \
"\t.word %c1" "\t# bug_entry::line\n" \ "\t.word %c1" "\t# bug_entry::line\n" \
@@ -52,7 +52,7 @@ do { \
#define _BUG_FLAGS(ins, flags) \ #define _BUG_FLAGS(ins, flags) \
do { \ do { \
asm volatile("1:\t" ins "\n" \ asm volatile("1:\t" ins "\n" \
".pushsection __bug_table,\"a\"\n" \ ".pushsection __bug_table,\"aw\"\n" \
"2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \ "2:\t" __BUG_REL(1b) "\t# bug_entry::bug_addr\n" \
"\t.word %c0" "\t# bug_entry::flags\n" \ "\t.word %c0" "\t# bug_entry::flags\n" \
"\t.org 2b+%c1\n" \ "\t.org 2b+%c1\n" \