mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 01:26:29 +07:00
17248ea036
Setting a kprobe on getname_flags() failed: $ echo 'p:tmr1 getname_flags +0(%r2):ustring' > kprobe_events -bash: echo: write error: Invalid argument Debugging the kprobes code showed that the address of getname_flags() is contained in the __bug_table. Kprobes doesn't allow to set probes at BUG() locations. $ objdump -j __bug_table -x build/fs/namei.o [..] 0000000000000108 R_390_PC32 .text+0x00000000000075a8 000000000000010c R_390_PC32 .L223+0x0000000000000004 I was expecting getname_flags() to start with a BUG(), but: 7598: e3 20 10 00 00 04 lg %r2,0(%r1) 759e: c0 f4 00 00 00 00 jg 759e <putname+0x7e> 75a0: R_390_PLT32DBL kmem_cache_free+0x2 75a4: a7 f4 00 01 j 75a6 <putname+0x86> 00000000000075a8 <getname_flags>: 75a8: c0 04 00 00 00 00 brcl 0,75a8 <getname_flags> 75ae: eb 6f f0 48 00 24 stmg %r6,%r15,72(%r15) 75b4: b9 04 00 ef lgr %r14,%r15 75b8: e3 f0 ff a8 ff 71 lay %r15,-88(%r15) So the BUG() is actually the last opcode of the previous function. Fix this by switching to using the MONITOR CALL (MC) instruction, and set the entry in __bug_table to the beginning of that MC. Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
71 lines
1.5 KiB
C
71 lines
1.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef _ASM_S390_BUG_H
|
|
#define _ASM_S390_BUG_H
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
#ifdef CONFIG_BUG
|
|
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
|
|
#define __EMIT_BUG(x) do { \
|
|
asm_inline volatile( \
|
|
"0: mc 0,0\n" \
|
|
".section .rodata.str,\"aMS\",@progbits,1\n" \
|
|
"1: .asciz \""__FILE__"\"\n" \
|
|
".previous\n" \
|
|
".section __bug_table,\"awM\",@progbits,%2\n" \
|
|
"2: .long 0b-2b,1b-2b\n" \
|
|
" .short %0,%1\n" \
|
|
" .org 2b+%2\n" \
|
|
".previous\n" \
|
|
: : "i" (__LINE__), \
|
|
"i" (x), \
|
|
"i" (sizeof(struct bug_entry))); \
|
|
} while (0)
|
|
|
|
#else /* CONFIG_DEBUG_BUGVERBOSE */
|
|
|
|
#define __EMIT_BUG(x) do { \
|
|
asm_inline volatile( \
|
|
"0: mc 0,0\n" \
|
|
".section __bug_table,\"awM\",@progbits,%1\n" \
|
|
"1: .long 0b-1b\n" \
|
|
" .short %0\n" \
|
|
" .org 1b+%1\n" \
|
|
".previous\n" \
|
|
: : "i" (x), \
|
|
"i" (sizeof(struct bug_entry))); \
|
|
} while (0)
|
|
|
|
#endif /* CONFIG_DEBUG_BUGVERBOSE */
|
|
|
|
#define BUG() do { \
|
|
__EMIT_BUG(0); \
|
|
unreachable(); \
|
|
} while (0)
|
|
|
|
#define __WARN_FLAGS(flags) do { \
|
|
__EMIT_BUG(BUGFLAG_WARNING|(flags)); \
|
|
} while (0)
|
|
|
|
#define WARN_ON(x) ({ \
|
|
int __ret_warn_on = !!(x); \
|
|
if (__builtin_constant_p(__ret_warn_on)) { \
|
|
if (__ret_warn_on) \
|
|
__WARN(); \
|
|
} else { \
|
|
if (unlikely(__ret_warn_on)) \
|
|
__WARN(); \
|
|
} \
|
|
unlikely(__ret_warn_on); \
|
|
})
|
|
|
|
#define HAVE_ARCH_BUG
|
|
#define HAVE_ARCH_WARN_ON
|
|
#endif /* CONFIG_BUG */
|
|
|
|
#include <asm-generic/bug.h>
|
|
|
|
#endif /* _ASM_S390_BUG_H */
|