Commit c0007f1a65762eaf55633d403b380130ec60adad
Committed by
Martin Schwidefsky
1 parent
bb11e3bdba
[S390] Use generic bug.
Generic bug implementation for s390. Will increase the value of the console output on BUG() statements since registers r0-r5,r14 will not be clobbered by a printk() call that was previously done before the illegal instruction of BUG() was hit. Also implements an architecture specific WARN_ON(). Output of that could be increased but requires common code change. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Showing 6 changed files with 89 additions and 18 deletions Side-by-side Diff
arch/s390/Kconfig
arch/s390/defconfig
... | ... | @@ -12,6 +12,7 @@ |
12 | 12 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
13 | 13 | CONFIG_GENERIC_HWEIGHT=y |
14 | 14 | CONFIG_GENERIC_TIME=y |
15 | +CONFIG_GENERIC_BUG=y | |
15 | 16 | CONFIG_NO_IOMEM=y |
16 | 17 | CONFIG_S390=y |
17 | 18 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
... | ... | @@ -705,6 +706,7 @@ |
705 | 706 | CONFIG_DEBUG_SPINLOCK_SLEEP=y |
706 | 707 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set |
707 | 708 | # CONFIG_DEBUG_KOBJECT is not set |
709 | +CONFIG_DEBUG_BUGVERBOSE=y | |
708 | 710 | # CONFIG_DEBUG_INFO is not set |
709 | 711 | # CONFIG_DEBUG_VM is not set |
710 | 712 | # CONFIG_DEBUG_LIST is not set |
arch/s390/kernel/module.c
... | ... | @@ -31,6 +31,7 @@ |
31 | 31 | #include <linux/string.h> |
32 | 32 | #include <linux/kernel.h> |
33 | 33 | #include <linux/moduleloader.h> |
34 | +#include <linux/bug.h> | |
34 | 35 | |
35 | 36 | #if 0 |
36 | 37 | #define DEBUGP printk |
37 | 38 | |
... | ... | @@ -398,10 +399,11 @@ |
398 | 399 | struct module *me) |
399 | 400 | { |
400 | 401 | vfree(me->arch.syminfo); |
401 | - return 0; | |
402 | + return module_bug_finalize(hdr, sechdrs, me); | |
402 | 403 | } |
403 | 404 | |
404 | 405 | void module_arch_cleanup(struct module *mod) |
405 | 406 | { |
407 | + module_bug_cleanup(mod); | |
406 | 408 | } |
arch/s390/kernel/traps.c
... | ... | @@ -30,7 +30,7 @@ |
30 | 30 | #include <linux/kallsyms.h> |
31 | 31 | #include <linux/reboot.h> |
32 | 32 | #include <linux/kprobes.h> |
33 | - | |
33 | +#include <linux/bug.h> | |
34 | 34 | #include <asm/system.h> |
35 | 35 | #include <asm/uaccess.h> |
36 | 36 | #include <asm/io.h> |
... | ... | @@ -297,6 +297,11 @@ |
297 | 297 | #endif |
298 | 298 | } |
299 | 299 | |
300 | +int is_valid_bugaddr(unsigned long addr) | |
301 | +{ | |
302 | + return 1; | |
303 | +} | |
304 | + | |
300 | 305 | static void __kprobes inline do_trap(long interruption_code, int signr, |
301 | 306 | char *str, struct pt_regs *regs, |
302 | 307 | siginfo_t *info) |
... | ... | @@ -323,8 +328,14 @@ |
323 | 328 | fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); |
324 | 329 | if (fixup) |
325 | 330 | regs->psw.addr = fixup->fixup | PSW_ADDR_AMODE; |
326 | - else | |
327 | - die(str, regs, interruption_code); | |
331 | + else { | |
332 | + enum bug_trap_type btt; | |
333 | + | |
334 | + btt = report_bug(regs->psw.addr & PSW_ADDR_INSN); | |
335 | + if (btt == BUG_TRAP_TYPE_WARN) | |
336 | + return; | |
337 | + die(str, regs, interruption_code); | |
338 | + } | |
328 | 339 | } |
329 | 340 | } |
330 | 341 |
arch/s390/kernel/vmlinux.lds.S
... | ... | @@ -45,6 +45,8 @@ |
45 | 45 | __ex_table : { *(__ex_table) } |
46 | 46 | __stop___ex_table = .; |
47 | 47 | |
48 | + BUG_TABLE | |
49 | + | |
48 | 50 | .data : { /* Data */ |
49 | 51 | *(.data) |
50 | 52 | CONSTRUCTORS |
... | ... | @@ -77,6 +79,12 @@ |
77 | 79 | *(.init.text) |
78 | 80 | _einittext = .; |
79 | 81 | } |
82 | + /* | |
83 | + * .exit.text is discarded at runtime, not link time, | |
84 | + * to deal with references from __bug_table | |
85 | + */ | |
86 | + .exit.text : { *(.exit.text) } | |
87 | + | |
80 | 88 | .init.data : { *(.init.data) } |
81 | 89 | . = ALIGN(256); |
82 | 90 | __setup_start = .; |
... | ... | @@ -116,7 +124,7 @@ |
116 | 124 | |
117 | 125 | /* Sections to be discarded */ |
118 | 126 | /DISCARD/ : { |
119 | - *(.exit.text) *(.exit.data) *(.exitcall.exit) | |
127 | + *(.exit.data) *(.exitcall.exit) | |
120 | 128 | } |
121 | 129 | |
122 | 130 | /* Stabs debugging sections. */ |
include/asm-s390/bug.h
1 | -#ifndef _S390_BUG_H | |
2 | -#define _S390_BUG_H | |
1 | +#ifndef _ASM_S390_BUG_H | |
2 | +#define _ASM_S390_BUG_H | |
3 | 3 | |
4 | 4 | #include <linux/kernel.h> |
5 | 5 | |
6 | 6 | #ifdef CONFIG_BUG |
7 | 7 | |
8 | -static inline __attribute__((noreturn)) void __do_illegal_op(void) | |
9 | -{ | |
10 | -#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) | |
11 | - __builtin_trap(); | |
8 | +#ifdef CONFIG_64BIT | |
9 | +#define S390_LONG ".quad" | |
12 | 10 | #else |
13 | - asm volatile(".long 0"); | |
11 | +#define S390_LONG ".long" | |
14 | 12 | #endif |
15 | -} | |
16 | 13 | |
17 | -#define BUG() do { \ | |
18 | - printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | |
19 | - __do_illegal_op(); \ | |
14 | +#ifdef CONFIG_DEBUG_BUGVERBOSE | |
15 | + | |
16 | +#define __EMIT_BUG(x) do { \ | |
17 | + asm volatile( \ | |
18 | + "0: j 0b+2\n" \ | |
19 | + "1:\n" \ | |
20 | + ".section .rodata.str,\"aMS\",@progbits,1\n" \ | |
21 | + "2: .asciz \""__FILE__"\"\n" \ | |
22 | + ".previous\n" \ | |
23 | + ".section __bug_table,\"a\"\n" \ | |
24 | + "3:\t" S390_LONG "\t1b,2b\n" \ | |
25 | + " .short %0,%1\n" \ | |
26 | + " .org 3b+%2\n" \ | |
27 | + ".previous\n" \ | |
28 | + : : "i" (__LINE__), \ | |
29 | + "i" (x), \ | |
30 | + "i" (sizeof(struct bug_entry))); \ | |
20 | 31 | } while (0) |
21 | 32 | |
33 | +#else /* CONFIG_DEBUG_BUGVERBOSE */ | |
34 | + | |
35 | +#define __EMIT_BUG(x) do { \ | |
36 | + asm volatile( \ | |
37 | + "0: j 0b+2\n" \ | |
38 | + "1:\n" \ | |
39 | + ".section __bug_table,\"a\"\n" \ | |
40 | + "2:\t" S390_LONG "\t1b\n" \ | |
41 | + " .short %0\n" \ | |
42 | + " .org 2b+%1\n" \ | |
43 | + ".previous\n" \ | |
44 | + : : "i" (x), \ | |
45 | + "i" (sizeof(struct bug_entry))); \ | |
46 | +} while (0) | |
47 | + | |
48 | +#endif /* CONFIG_DEBUG_BUGVERBOSE */ | |
49 | + | |
50 | +#define BUG() __EMIT_BUG(0) | |
51 | + | |
52 | +#define WARN_ON(x) ({ \ | |
53 | + typeof(x) __ret_warn_on = (x); \ | |
54 | + if (__builtin_constant_p(__ret_warn_on)) { \ | |
55 | + if (__ret_warn_on) \ | |
56 | + __EMIT_BUG(BUGFLAG_WARNING); \ | |
57 | + } else { \ | |
58 | + if (unlikely(__ret_warn_on)) \ | |
59 | + __EMIT_BUG(BUGFLAG_WARNING); \ | |
60 | + } \ | |
61 | + unlikely(__ret_warn_on); \ | |
62 | +}) | |
63 | + | |
22 | 64 | #define HAVE_ARCH_BUG |
23 | -#endif | |
65 | +#define HAVE_ARCH_WARN_ON | |
66 | +#endif /* CONFIG_BUG */ | |
24 | 67 | |
25 | 68 | #include <asm-generic/bug.h> |
26 | 69 | |
27 | -#endif | |
70 | +#endif /* _ASM_S390_BUG_H */ |