From: sjg@chromium.org (Simon Glass)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH] ARM: Use generic BUG() handler
Date: Mon, 28 Feb 2011 16:27:43 -0800 [thread overview]
Message-ID: <1298939263-16421-1-git-send-email-sjg@chromium.org> (raw)
I am looking for comments please on this patch.
ARM uses its own BUG() handler which makes its output slightly different
from other archtectures.
One of the problems is that the ARM implementation doesn't report the function
with the BUG() in it, but always reports the PC being in __bug(). The generic
implementation doesn't have this problem.
Currently we get something like:
kernel BUG at fs/proc/breakme.c:35!
Unable to handle kernel NULL pointer dereference at virtual address 00000000
...
PC is at __bug+0x20/0x2c
With this patch it displays:
kernel BUG at fs/proc/breakme.c:35!
Internal error: Oops - undefined instruction: 0 [#1] PREEMPT SMP
...
PC is at write_breakme+0xd0/0x1b4
This implementation uses an undefined instruction to implement BUG, and sets up
a bug table containing the relevant information.
Also backtraces were reported slightly differently - so I have added a newline
after the backtrace message, a space before the address, and ensured that the
message appears even when CONFIG_ARM_UNWIND is defined. These are aimed at
consistency between architectures, and may or may not be acceptable for ARM.
In any case they may be best as a separate patch.
Change-Id: I515db9a04e98084e6bbb21c4a1d13579568a0904
Signed-off-by: Simon Glass <sjg@chromium.org>
---
arch/arm/Kconfig | 4 ++++
arch/arm/include/asm/bug.h | 40 +++++++++++++++++++++++++++++++++++++++-
arch/arm/kernel/traps.c | 21 +++++++++++++++++++--
arch/arm/kernel/unwind.c | 1 +
arch/arm/kernel/vmlinux.lds.S | 15 +++++++++++++--
5 files changed, 76 insertions(+), 5 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 26d45e5..d4fb0fb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -191,6 +191,10 @@ config VECTORS_BASE
help
The base address of exception vectors.
+config GENERIC_BUG
+ def_bool y
+ depends on BUG
+
source "init/Kconfig"
source "kernel/Kconfig.freezer"
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index 4d88425..bbbebe4 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -3,6 +3,40 @@
#ifdef CONFIG_BUG
+
+#ifdef CONFIG_GENERIC_BUG
+
+
+/* A suitable undefined instruction to use for ARM bug handling */
+#define BUG_INSTR_ARM 0xec000000
+
+
+#ifdef CONFIG_DEBUG_BUGVERBOSE
+#define BUG() \
+do { \
+ asm volatile("1:\t.word %c3\n" \
+ ".pushsection __bug_table,\"a\"\n" \
+ "2:\t.word 1b, %c0\n" \
+ "\t.hword %c1, 0\n" \
+ "\t.org 2b+%c2\n" \
+ ".popsection" \
+ : \
+ : "i" (__FILE__), "i" (__LINE__), \
+ "i" (sizeof(struct bug_entry)), \
+ "i" (BUG_INSTR_ARM)); \
+ unreachable(); \
+} while (0)
+
+#else
+#define BUG() \
+do { \
+ asm volatile("ud2"); \
+ unreachable(); \
+} while (0)
+#endif
+
+#else /* not CONFIG_GENERIC_BUG */
+
#ifdef CONFIG_DEBUG_BUGVERBOSE
extern void __bug(const char *file, int line) __attribute__((noreturn));
@@ -16,8 +50,12 @@ extern void __bug(const char *file, int line) __attribute__((noreturn));
#endif
+#endif /* CONFIG_GENERIC_BUG */
+
#define HAVE_ARCH_BUG
-#endif
+
+#endif /* CONFIG_BUG */
+
#include <asm-generic/bug.h>
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index ee57640..d5e5df9 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -21,6 +21,7 @@
#include <linux/kdebug.h>
#include <linux/module.h>
#include <linux/kexec.h>
+#include <linux/bug.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -55,7 +56,8 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
{
#ifdef CONFIG_KALLSYMS
- printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
+ printk(" [<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where,
+ from, (void *)from);
#else
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
@@ -171,7 +173,7 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
unsigned int fp, mode;
int ok = 1;
- printk("Backtrace: ");
+ printk("Backtrace:\n");
if (!tsk)
tsk = current;
@@ -271,6 +273,8 @@ void die(const char *str, struct pt_regs *regs, int err)
spin_lock_irq(&die_lock);
console_verbose();
bust_spinlocks(1);
+ if (!user_mode(regs))
+ report_bug(regs->ARM_pc, regs);
ret = __die(str, err, thread, regs);
if (regs && kexec_should_crash(thread->task))
@@ -302,6 +306,19 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
}
}
+int is_valid_bugaddr(unsigned long pc)
+{
+ unsigned bkpt;
+
+ if (pc < PAGE_OFFSET)
+ return 0;
+ if (probe_kernel_address((unsigned *)pc, bkpt))
+ return 0;
+
+ return bkpt == BUG_INSTR_ARM;
+}
+
+
static LIST_HEAD(undef_hook);
static DEFINE_SPINLOCK(undef_lock);
diff --git a/arch/arm/kernel/unwind.c b/arch/arm/kernel/unwind.c
index d2cb0b3..3f065bd 100644
--- a/arch/arm/kernel/unwind.c
+++ b/arch/arm/kernel/unwind.c
@@ -355,6 +355,7 @@ void unwind_backtrace(struct pt_regs *regs, struct task_struct *tsk)
register unsigned long current_sp asm ("sp");
pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
+ printk("Backtrace:\n");
if (!tsk)
tsk = current;
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 86b66f3..591ab50 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -72,6 +72,18 @@ SECTIONS
PERCPU(PAGE_SIZE)
+ /*
+ * .exit.text is discarded@runtime, not link time, to deal with
+ * references from bug_table
+ */
+ .exit.text : AT(ADDR(.exit.text)) {
+ EXIT_TEXT
+ }
+
+ .exit.data : AT(ADDR(.exit.data)) {
+ EXIT_DATA
+ }
+
#ifndef CONFIG_XIP_KERNEL
. = ALIGN(PAGE_SIZE);
__init_end = .;
@@ -246,7 +258,6 @@ SECTIONS
__tcm_end = .;
}
#endif
-
BSS_SECTION(0, 0, 0)
_end = .;
@@ -254,7 +265,7 @@ SECTIONS
.comment 0 : { *(.comment) }
/* Default discards */
- DISCARDS
+ /*DISCARDS*/
#ifndef CONFIG_SMP_ON_UP
/DISCARD/ : {
--
1.7.3.1
next reply other threads:[~2011-03-01 0:27 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-01 0:27 Simon Glass [this message]
2011-03-01 8:49 ` [RFC PATCH] ARM: Use generic BUG() handler Russell King - ARM Linux
2011-03-01 8:59 ` Russell King - ARM Linux
2011-03-01 9:12 ` Mikael Pettersson
2011-03-01 10:03 ` Russell King - ARM Linux
2011-03-01 16:34 ` Simon Glass
2011-03-01 20:28 ` Russell King - ARM Linux
2011-03-02 10:59 ` Dave Martin
2011-03-03 14:11 ` Russell King - ARM Linux
2011-03-03 14:44 ` Dave Martin
2011-03-01 17:48 ` Dave Martin
2011-03-01 20:32 ` Russell King - ARM Linux
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1298939263-16421-1-git-send-email-sjg@chromium.org \
--to=sjg@chromium.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).