2012-08-12 12:18:18

by Jason Wessel

[permalink] [raw]
Subject: [PATCH 1/4] mips,kgdb: fix recursive page fault with CONFIG_KPROBES

This fault was detected using the kgdb test suite on boot and it
crashes recursively due to the fact that CONFIG_KPROBES on mips adds
an extra die notifier in the page fault handler. The crash signature
looks like this:

kgdbts:RUN bad memory access test
KGDB: re-enter exception: ALL breakpoints killed
Call Trace:
[<807b7548>] dump_stack+0x20/0x54
[<807b7548>] dump_stack+0x20/0x54

The fix for now is to have kgdb return immediately if the fault type
is DIE_PAGE_FAULT and allow the kprobe code to decide what is supposed
to happen.

Cc: Masami Hiramatsu <[email protected]>
Cc: David S. Miller <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
arch/mips/kernel/kgdb.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/arch/mips/kernel/kgdb.c b/arch/mips/kernel/kgdb.c
index f4546e9..23817a6 100644
--- a/arch/mips/kernel/kgdb.c
+++ b/arch/mips/kernel/kgdb.c
@@ -283,6 +283,15 @@ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd,
struct pt_regs *regs = args->regs;
int trap = (regs->cp0_cause & 0x7c) >> 2;

+#ifdef CONFIG_KPROBES
+ /*
+ * Return immediately if the kprobes fault notifier has set
+ * DIE_PAGE_FAULT.
+ */
+ if (cmd == DIE_PAGE_FAULT)
+ return NOTIFY_DONE;
+#endif /* CONFIG_KPROBES */
+
/* Userspace events, ignore. */
if (user_mode(regs))
return NOTIFY_DONE;
--
1.7.9.5


2012-08-12 12:17:21

by Jason Wessel

[permalink] [raw]
Subject: [PATCH 3/4] kgdb,x86: fix warning about unused variable

When compiling without CONFIG_DEBUG_RODATA the following
compiler warning is generated:

arch/x86/kernel/kgdb.c: In function 'kgdb_arch_set_breakpoint':
arch/x86/kernel/kgdb.c:749: warning: unused variable 'opc'

The variable instantiation needs to be inside the #ifdef to
make the warning go away.

Reported-by: Thiago Rafael Becker <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
arch/x86/kernel/kgdb.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c
index 3f61904..836f832 100644
--- a/arch/x86/kernel/kgdb.c
+++ b/arch/x86/kernel/kgdb.c
@@ -746,7 +746,9 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long ip)
int kgdb_arch_set_breakpoint(struct kgdb_bkpt *bpt)
{
int err;
+#ifdef CONFIG_DEBUG_RODATA
char opc[BREAK_INSTR_SIZE];
+#endif /* CONFIG_DEBUG_RODATA */

bpt->type = BP_BREAKPOINT;
err = probe_kernel_read(bpt->saved_instr, (char *)bpt->bpt_addr,
--
1.7.9.5

2012-08-12 12:18:15

by Jason Wessel

[permalink] [raw]
Subject: [PATCH 2/4] pmac_zilog,kdb: Fix console poll hook to return instead of loop

kdb <-> kgdb transitioning does not work properly with this UART
driver because the get character routine loops indefinitely as opposed
to returning NO_POLL_CHAR per the expectation of the KDB I/O driver
API.

The symptom is a kernel hang when trying to switch debug modes.

Cc: Alan Cox <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Jason Wessel <[email protected]>
---
drivers/tty/serial/pmac_zilog.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c
index 654755a..333c8d0 100644
--- a/drivers/tty/serial/pmac_zilog.c
+++ b/drivers/tty/serial/pmac_zilog.c
@@ -1348,10 +1348,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser)
static int pmz_poll_get_char(struct uart_port *port)
{
struct uart_pmac_port *uap = (struct uart_pmac_port *)port;
+ int tries = 2;

- while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0)
- udelay(5);
- return read_zsdata(uap);
+ while (tries) {
+ if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0)
+ return read_zsdata(uap);
+ if (tries--)
+ udelay(5);
+ }
+
+ return NO_POLL_CHAR;
}

static void pmz_poll_put_char(struct uart_port *port, unsigned char c)
--
1.7.9.5

2012-08-12 12:18:13

by Jason Wessel

[permalink] [raw]
Subject: [PATCH 4/4] kgdboc: Accept either kbd or kdb to activate the vga + keyboard kdb shell

It is a common enough mistake for people to specify "kdb" when they
meant to type "kbd" that the kgdboc can just accept both since they
both mean the same thing anyway. Specifically it is for the case
where you want kdb to be active on your graphics console + keyboard
(where kbd was the original abbreviation for keyboard).

With this change kgdboc will now accept either to mean the same thing:
kgdboc=kbd
kgdboc=kdb

Signed-off-by: Jason Wessel <[email protected]>
---
drivers/tty/serial/kgdboc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index 2b42a01..509e714 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -97,7 +97,8 @@ static void kgdboc_restore_input(void)

static int kgdboc_register_kbd(char **cptr)
{
- if (strncmp(*cptr, "kbd", 3) == 0) {
+ if (strncmp(*cptr, "kbd", 3) == 0 ||
+ strncmp(*cptr, "kdb", 3) == 0) {
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
kdb_poll_idx++;
--
1.7.9.5