KGDB/KDB FIQ (NMI) debugger
Subsystems (7)
v8 cover KGDB/KDB FIQ (NMI) debugger
Hi all,
In v8, addressed Jason's comments:
- Changed kgdb_enable_nmi() weak function to kgdb_arch callbck;
- We no longer register disable_nmi command if arch does not register KGDB NMI handling (i.e. not filling kgdb_arch.enable_nmi callback);
- The same is for ttyNMI: if architecure does not provide us with enable_nmi call, we don't need the tty device. Of course, there is no way to tell wether a specific serial device can be used for NMI debugging, as it is not serial-device specific, but specific to whether IRQ can be rerouted to an NMI (for most our cases, pretty much every IRQ can be rerouted, e.g. a hot-pluggable serial device on a PCI bus).
- Rebased on the latest and greatest tty-next, just in case.
These patches can be found in the following repo (based on tty-next):
git://git.infradead.org/users/cbou/linux-nmi-kdb.git master
Old changelogs and rationale for these patches can be found here:
v1-v5, rationale: http://lkml.org/lkml/2012/9/10/2 v6: http://lkml.org/lkml/2012/9/10/2 v7: http://lkml.org/lkml/2012/9/13/367
Thanks,
--
arch/arm/Kconfig | 19 ++ arch/arm/common/vic.c | 28 +++ arch/arm/include/asm/hardware/vic.h | 2 + arch/arm/include/asm/kgdb.h | 8 + arch/arm/kernel/Makefile | 1 + arch/arm/kernel/entry-armv.S | 167 +------------ arch/arm/kernel/entry-header.S | 170 +++++++++++++ arch/arm/kernel/kgdb_fiq.c | 124 +++++++++ arch/arm/kernel/kgdb_fiq_entry.S | 87 +++++++ arch/arm/mach-versatile/Makefile | 1 + arch/arm/mach-versatile/kgdb_fiq.c | 31 +++ drivers/tty/serial/Kconfig | 19 ++ drivers/tty/serial/Makefile | 1 + drivers/tty/serial/amba-pl011.c | 73 +++++- drivers/tty/serial/kgdb_nmi.c | 402 ++++++++++++++++++++++++++++++ drivers/tty/serial/kgdboc.c | 9 + drivers/tty/serial/serial_core.c | 17 ++ include/linux/kdb.h | 29 ++- include/linux/kgdb.h | 13 + include/linux/serial_core.h | 1 + kernel/debug/debug_core.c | 14 +- kernel/debug/kdb/kdb_main.c | 31 +++ 22 files changed, 1054 insertions(+), 193 deletions(-)
PATCH v8 1/11 kernel/debug: Mask KGDB NMI upon entry
The new arch callback should manage NMIs that usually cause KGDB to enter. That is, not all NMIs should be enabled/disabled, but only those that issue kgdb_handle_exception().
We must mask it as serial-line interrupt can be used as an NMI, so if the original KGDB-entry cause was say a breakpoint, then every input to KDB console will cause KGDB to reenter, which we don't want.
--- include/linux/kgdb.h | 3 +++ kernel/debug/debug_core.c | 14 +++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-)
include/linux/kgdb.h +3 -0
@@ -240,6 +240,7 @@ extern void kgdb_arch_late(void);* hardware breakpoints. * @correct_hw_break: Allow an architecture to specify how to correct the * hardware debug registers. +* @enable_nmi: Manage NMI-triggered entry to KGDB */ struct kgdb_arch {unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE ];
@@ -252,6 +253,8 @@ struct kgdb_arch {void (*disable_hw_break)(struct pt_regs *regs);void (*remove_all_hw_break)(void );void (*correct_hw_break)(void ); + +void (*enable_nmi)(bool on); };/**
kernel/debug/debug_core.c +11 -3
@@ -672,6 +672,10 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) {struct kgdb_state kgdb_var;struct kgdb_state *ks = &kgdb_var; +int ret =0 ; + +if (arch_kgdb_ops.enable_nmi) + arch_kgdb_ops.enable_nmi (0 ); ks->cpu =raw_smp_processor_id (); ks->ex_vector = evector;
@@ -681,11 +685,15 @@ kgdb_handle_exception(int evector, int signo, int ecode, struct pt_regs *regs) ks->linux_regs = regs;if (kgdb_reenter_check (ks)) -return 0 ;/* Ouch, double exception ! */ + goto out;/* Ouch, double exception ! */ if (kgdb_info[ks->cpu].enter_kgdb !=0 ) -return 0 ; + goto out; -return kgdb_cpu_enter (ks, regs,DCPU_WANT_MASTER ); + ret =kgdb_cpu_enter (ks, regs,DCPU_WANT_MASTER ); +out: +if (arch_kgdb_ops.enable_nmi) + arch_kgdb_ops.enable_nmi (1 ); +return ret; }int kgdb_nmicallback (int cpu,void *regs)
Signature · 1 line
1.7.11.5
PATCH v8 2/11 kdb: Implement disable_nmi command
In reply to Anton VorontsovThis command disables NMI-entry. If NMI source has been previously shared with a serial console ("debug port"), this effectively releases the port from KDB exclusive use, and makes the console available for normal use.
Of course, NMI can be reenabled, enable_nmi modparam is used for that:
echo 1 > /sys/module/kdb/parameters/enable_nmi
--- kernel/debug/kdb/kdb_main.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+)
kernel/debug/kdb/kdb_main.c +31 -0
@@ -21,6 +21,7 @@#include <linux/smp.h> #include <linux/utsname.h> #include <linux/vmalloc.h> +#include <linux/atomic.h> #include <linux/module.h> #include <linux/mm.h> #include <linux/init.h>
@@ -2107,6 +2108,32 @@ static int kdb_dmesg(int argc, const char **argv) return 0; }#endif /* CONFIG_PRINTK */ + +/* Make sure we balance enable/disable calls, must disable first. */ +static atomic_t kdb_nmi_disabled; + +static int kdb_disable_nmi (int argc,const char *argv[]) +{ +if (atomic_read (&kdb_nmi_disabled)) +return 0 ; +atomic_set (&kdb_nmi_disabled,1 ); + arch_kgdb_ops.enable_nmi (0 ); +return 0 ; +} + +static int kdb_param_enable_nmi (const char *val,const struct kernel_param *kp) +{ +if (!atomic_add_unless (&kdb_nmi_disabled,-1 ,0 )) +return -EINVAL ; + arch_kgdb_ops.enable_nmi (1 ); +return 0 ; +} + +static const struct kernel_param_ops kdb_param_ops_enable_nmi = { + .set = kdb_param_enable_nmi, +}; +module_param_cb (enable_nmi, &kdb_param_ops_enable_nmi,NULL ,0600 ); +/* * kdb_cpu - This function implements the 'cpu' command. * cpu [<cpunum>]
@@ -2851,6 +2878,10 @@ static void __init kdb_inittab(void)kdb_register_repeat ("dmesg" , kdb_dmesg,"[lines]" ,"Display syslog buffer" ,0 ,KDB_REPEAT_NONE );#endif +if (arch_kgdb_ops.enable_nmi) { +kdb_register_repeat ("disable_nmi" , kdb_disable_nmi,"" , +"Disable NMI entry to KDB" ,0 ,KDB_REPEAT_NONE ); + }kdb_register_repeat ("defcmd" , kdb_defcmd,"name \"usage\" \"help\"" ,"Define a set of commands, down to endefcmd" ,0 ,KDB_REPEAT_NONE ); kdb_register_repeat("kill", kdb_kill, "<-signal> <pid>",
Signature · 1 line
1.7.11.5
PATCH v8 3/11 kdb: Turn KGDB_KDB=n stubs into static inlines
In reply to Anton VorontsovThis makes the stubs actually usable, since e.g. 'foo = kdb_register();' leads to build errors in !KGDB_KDB case. Plus, with static inlines we do type checking.
--- include/linux/kdb.h | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-)
include/linux/kdb.h +16 -13
@@ -13,6 +13,14 @@* Copyright (C) 2009 Jason Wessel <[email protected]> */ +typedef enum { +KDB_REPEAT_NONE =0 ,/* Do not repeat this command */ +KDB_REPEAT_NO_ARGS ,/* Repeat the command without arguments */ +KDB_REPEAT_WITH_ARGS ,/* Repeat the command including its arguments */ +}kdb_repeat_t ; + +typedef int (*kdb_func_t )(int ,const char **); +#ifdef CONFIG_KGDB_KDB #include <linux/init.h> #include <linux/sched.h>
@@ -32,14 +40,6 @@ extern atomic_t kdb_event;#define KDB_MAXARGS 16/* Maximum number of arguments to a function */ -typedef enum { -KDB_REPEAT_NONE =0 ,/* Do not repeat this command */ -KDB_REPEAT_NO_ARGS ,/* Repeat the command without arguments */ -KDB_REPEAT_WITH_ARGS ,/* Repeat the command including its arguments */ -}kdb_repeat_t ; - -typedef int (*kdb_func_t )(int ,const char **); -/* KDB return codes from a command or internal kdb function */ #define KDB_NOTFOUND (-1)#define KDB_ARGCOUNT (-2)
@@ -149,11 +149,14 @@ extern int kdb_register_repeat(char *, kdb_func_t, char *, char *, short, kdb_repeat_t);extern int kdb_unregister (char *);#else /* ! CONFIG_KGDB_KDB */ -#define kdb_printf (...) -#define kdb_init (x) -#define kdb_register (...) -#define kdb_register_repeat (...) -#define kdb_uregister (x) +static inline __printf(1, 2) int kdb_printf(const char *fmt, ...) { return 0; } +static inline void kdb_init (int level) {} +static inline int kdb_register (char *cmd,kdb_func_t func,char *usage, +char *help,short minlen) {return 0 ; } +static inline int kdb_register_repeat (char *cmd,kdb_func_t func,char *usage, +char *help,short minlen, +kdb_repeat_t repeat) {return 0 ; } +static inline int kdb_unregister (char *cmd) {return 0 ; }#endif /* CONFIG_KGDB_KDB */ enum {KDB_NOT_INITIALIZED ,
Signature · 1 line
1.7.11.5
PATCH v8 4/11 tty/serial/core: Introduce poll_init callback
In reply to Anton VorontsovIt was noticed that polling drivers (like KGDB) are not able to use serial ports if the ports were not previously initialized via console. I.e. when booting with console=ttyAMA0 kgdboc=ttyAMA0, everything works fine, but with console=ttyFOO kgdboc=ttyAMA0, the kgdboc doesn't work.
This is because we don't initialize the hardware. Calling ->startup() is not an option, because drivers request interrupts there, and drivers fail to handle situations when tty isn't opened with interrupts enabled.
So, we have to implement a new callback (actually, tty_ops already have a similar callback), which does everything needed to initialize just the hardware.
--- drivers/tty/serial/serial_core.c | 17 +++++++++++++++++ include/linux/serial_core.h | 1 + 2 files changed, 18 insertions(+)
drivers/tty/serial/serial_core.c +17 -0
@@ -2129,6 +2129,7 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)int bits =8 ;int parity ='n' ;int flow ='n' ; +int ret;if (!state || !state->uart_port)return -1 ;
@@ -2137,6 +2138,22 @@ static int uart_poll_init(struct tty_driver *driver, int line, char *options)if (!(port->ops->poll_get_char && port->ops->poll_put_char))return -1 ; +if (port->ops->poll_init) { +struct tty_port *tport = &state->port; + + ret =0 ; +mutex_lock (&tport->mutex); +/* +* We don't set ASYNCB_INITIALIZED as we only initialized the +* hw, e.g. state->xmit is still uninitialized. +*/ +if (!test_bit (ASYNCB_INITIALIZED , &tport->flags)) + ret = port->ops->poll_init (port); +mutex_unlock (&tport->mutex); +if (ret) +return ret; + } +if (options) {uart_parse_options (options, &baud, &parity, &bits, &flow);return uart_set_options (port,NULL , baud, parity, bits, flow);
include/linux/serial_core.h +1 -0
@@ -274,6 +274,7 @@ struct uart_ops {int (*verify_port)(struct uart_port *,struct serial_struct *);int (*ioctl)(struct uart_port *,unsigned int ,unsigned long );#ifdef CONFIG_CONSOLE_POLL +int (*poll_init)(struct uart_port *);void (*poll_put_char)(struct uart_port *,unsigned char );int (*poll_get_char)(struct uart_port *);#endif
Signature · 1 line
1.7.11.5
PATCH v8 5/11 tty/serial/amba-pl011: Implement poll_init callback
In reply to Anton VorontsovThe callback is used to initialize the hardware, nothing else should be done, i.e. we should not request interrupts (but we can and do unmask some of them, as they might be useful for NMI entry).
As a side-effect, the patch also fixes a division by zero[1] when booting with kgdboc options specified (e.g. kgdboc=ttyAMA0,115200n8). The issue happens because serial core calls set_termios callback, but the driver doesn't know clock frequency, and thus cannot calculate proper baud rate values.
[1]
WARNING: at drivers/tty/serial/serial_core.c:400 uart_get_baud_rate+0xe8/0x14c() Modules linked in: [<c0018e50>] (unwind_backtrace+0x0/0xf0) from [<c0020ae8>] (warn_slowpath_common+0x4c/0x64) [<c0020ae8>] (warn_slowpath_common+0x4c/0x64) from [<c0020b1c>] (warn_slowpath_null+0x1c/0x24) [<c0020b1c>] (warn_slowpath_null+0x1c/0x24) from [<c0185ed8>] (uart_get_baud_rate+0xe8/0x14c) [<c0185ed8>] (uart_get_baud_rate+0xe8/0x14c) from [<c0187078>] (pl011_set_termios+0x48/0x278) [<c0187078>] (pl011_set_termios+0x48/0x278) from [<c01850b0>] (uart_set_options+0xe8/0x114) [<c01850b0>] (uart_set_options+0xe8/0x114) from [<c0185de4>] (uart_poll_init+0xd4/0xe0) [<c0185de4>] (uart_poll_init+0xd4/0xe0) from [<c016da8c>] (tty_find_polling_driver+0x100/0x17c) [<c016da8c>] (tty_find_polling_driver+0x100/0x17c) from [<c0188538>] (configure_kgdboc+0xc8/0x1b8) [<c0188538>] (configure_kgdboc+0xc8/0x1b8) from [<c00088a4>] (do_one_initcall+0x30/0x168) [<c00088a4>] (do_one_initcall+0x30/0x168) from [<c033784c>] (do_basic_setup+0x94/0xc8) [<c033784c>] (do_basic_setup+0x94/0xc8) from [<c03378e0>] (kernel_init+0x60/0xf4) [<c03378e0>] (kernel_init+0x60/0xf4) from [<c00144a0>] (kernel_thread_exit+0x0/0x8) ---[ end trace 7d41c9186f342c40 ]---
Division by zero in kernel.
[<c0018e50>] (unwind_backtrace+0x0/0xf0) from [<c014546c>] (Ldiv0+0x8/0x10) [<c014546c>] (Ldiv0+0x8/0x10) from [<c0187098>] (pl011_set_termios+0x68/0x278) [<c0187098>] (pl011_set_termios+0x68/0x278) from [<c01850b0>] (uart_set_options+0xe8/0x114) [<c01850b0>] (uart_set_options+0xe8/0x114) from [<c0185de4>] (uart_poll_init+0xd4/0xe0) [<c0185de4>] (uart_poll_init+0xd4/0xe0) from [<c016da8c>] (tty_find_polling_driver+0x100/0x17c) [<c016da8c>] (tty_find_polling_driver+0x100/0x17c) from [<c0188538>] (configure_kgdboc+0xc8/0x1b8) [<c0188538>] (configure_kgdboc+0xc8/0x1b8) from [<c00088a4>] (do_one_initcall+0x30/0x168) [<c00088a4>] (do_one_initcall+0x30/0x168) from [<c033784c>] (do_basic_setup+0x94/0xc8) [<c033784c>] (do_basic_setup+0x94/0xc8) from [<c03378e0>] (kernel_init+0x60/0xf4) [<c03378e0>] (kernel_init+0x60/0xf4) from [<c00144a0>] (kernel_thread_exit+0x0/0x8) Division by zero in kernel.
[<c0018e50>] (unwind_backtrace+0x0/0xf0) from [<c014546c>] (Ldiv0+0x8/0x10) [<c014546c>] (Ldiv0+0x8/0x10) from [<c0183a98>] (uart_update_timeout+0x4c/0x5c) [<c0183a98>] (uart_update_timeout+0x4c/0x5c) from [<c01870f8>] (pl011_set_termios+0xc8/0x278) [<c01870f8>] (pl011_set_termios+0xc8/0x278) from [<c01850b0>] (uart_set_options+0xe8/0x114) [<c01850b0>] (uart_set_options+0xe8/0x114) from [<c0185de4>] (uart_poll_init+0xd4/0xe0) [<c0185de4>] (uart_poll_init+0xd4/0xe0) from [<c016da8c>] (tty_find_polling_driver+0x100/0x17c) [<c016da8c>] (tty_find_polling_driver+0x100/0x17c) from [<c0188538>] (configure_kgdboc+0xc8/0x1b8) [<c0188538>] (configure_kgdboc+0xc8/0x1b8) from [<c00088a4>] (do_one_initcall+0x30/0x168) [<c00088a4>] (do_one_initcall+0x30/0x168) from [<c033784c>] (do_basic_setup+0x94/0xc8) [<c033784c>] (do_basic_setup+0x94/0xc8) from [<c03378e0>] (kernel_init+0x60/0xf4) [<c03378e0>] (kernel_init+0x60/0xf4) from [<c00144a0>] (kernel_thread_exit+0x0/0x8)
--- drivers/tty/serial/amba-pl011.c | 44 ++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-)
drivers/tty/serial/amba-pl011.c +33 -11
@@ -1309,10 +1309,9 @@ static void pl011_put_poll_char(struct uart_port *port,#endif /* CONFIG_CONSOLE_POLL */ -static int pl011_startup (struct uart_port *port) +static int pl011_hwinit (struct uart_port *port) {struct uart_amba_port *uap = (struct uart_amba_port *)port; -unsigned int cr;int retval;/* Optionaly enable pins to be muxed in and configured */
@@ -1337,6 +1336,37 @@ static int pl011_startup(struct uart_port *port) UART011_RTIS | UART011_RXIS, uap->port.membase + UART011_ICR);/* +* Save interrupts enable mask, and enable RX interrupts in case if +* the interrupt is used for NMI entry. +*/ + uap->im =readw (uap->port.membase +UART011_IMSC ); +writew (UART011_RTIM |UART011_RXIM , uap->port.membase +UART011_IMSC ); + +if (uap->port.dev->platform_data) { +struct amba_pl011_data *plat; + + plat = uap->port.dev->platform_data; +if (plat->init) + plat->init (); + } +return 0 ; + out: +return retval; +} + +static int pl011_startup (struct uart_port *port) +{ +struct uart_amba_port *uap = (struct uart_amba_port *)port; +unsigned int cr; +int retval; + + retval =pl011_hwinit (port); +if (retval) + goto clk_dis; + +writew (uap->im, uap->port.membase +UART011_IMSC ); + +/* * Allocate the IRQ */ retval =request_irq (uap->port.irq, pl011_int,0 ,"uart-pl011" , uap);
@@ -1395,19 +1425,10 @@ static int pl011_startup(struct uart_port *port)writew (uap->im, uap->port.membase +UART011_IMSC );spin_unlock_irq (&uap->port.lock); -if (uap->port.dev->platform_data) { -struct amba_pl011_data *plat; - - plat = uap->port.dev->platform_data; -if (plat->init) - plat->init (); - } -return 0 ; clk_dis:clk_disable_unprepare (uap->clk); - out:return retval; }
@@ -1688,6 +1709,7 @@ static struct uart_ops amba_pl011_pops = { .config_port = pl011_config_port, .verify_port = pl011_verify_port, #ifdef CONFIG_CONSOLE_POLL + .poll_init = pl011_hwinit, .poll_get_char = pl011_get_poll_char, .poll_put_char = pl011_put_poll_char, #endif
Signature · 1 line
1.7.11.5
PATCH v8 6/11 tty/serial/amba-pl011: Quiesce interrupts in poll_get_char
In reply to Anton VorontsovWe need to quiesce interrupts in the poll_get_char routine, otherwise, if used with KGDB NMI debugger, we'll keep reentering the NMI.
Quiescing interrupts is pretty straightforward, except for TXIM interrupt. The interrupt has "ready to transmit" meaning, so it's almost always raised, and the only way to silence it is to mask it. But that's OK, ops->start_tx will unmask it.
--- drivers/tty/serial/amba-pl011.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
drivers/tty/serial/amba-pl011.c +29 -0
@@ -1284,11 +1284,40 @@ static void pl011_break_ctl(struct uart_port *port, int break_state) }#ifdef CONFIG_CONSOLE_POLL + +static void pl011_quiesce_irqs (struct uart_port *port) +{ +struct uart_amba_port *uap = (struct uart_amba_port *)port; +unsigned char __iomem *regs = uap->port.membase; + +writew (readw (regs +UART011_MIS ), regs +UART011_ICR ); +/* +* There is no way to clear TXIM as this is "ready to transmit IRQ", so +* we simply mask it. start_tx() will unmask it. +* +* Note we can race with start_tx(), and if the race happens, the +* polling user might get another interrupt just after we clear it. +* But it should be OK and can happen even w/o the race, e.g. +* controller immediately got some new data and raised the IRQ. +* +* And whoever uses polling routines assumes that it manages the device +* (including tx queue), so we're also fine with start_tx()'s caller +* side. +*/ +writew (readw (regs +UART011_IMSC ) & ~UART011_TXIM , regs +UART011_IMSC ); +} +static int pl011_get_poll_char (struct uart_port *port) {struct uart_amba_port *uap = (struct uart_amba_port *)port;unsigned int status; +/* +* The caller might need IRQs lowered, e.g. if used with KDB NMI +* debugger. +*/ +pl011_quiesce_irqs (port); + status =readw (uap->port.membase + UART01x_FR);if (status & UART01x_FR_RXFE)return NO_POLL_CHAR ;
Signature · 1 line
1.7.11.5
PATCH v8 7/11 tty/serial: Add kgdb_nmi driver
In reply to Anton VorontsovThis special driver makes it possible to temporary use NMI debugger port as a normal console by issuing 'nmi_console' command (assuming that the port is attached to KGDB).
Unlike KDB's disable_nmi command, with this driver you are always able to go back to the debugger using KGDB escape sequence ($3#33). This is because this console driver processes the input in NMI context, and thus is able to intercept the magic sequence.
Note that since the console interprets input and uses polling communication methods, for things like PPP it is still better to fully detach debugger port from the KGDB NMI (i.e. disable_nmi), and use raw console.
Usually, to enter the debugger one have to type the magic sequence, so initially the kernel will print the following prompt on the NMI debugger console:
Type $3#33 to enter the debugger>
For convenience, there is a kgdb_fiq.knock kernel command line option, when set to 0, this turns the special command to just a return key press, so the kernel will be printing this:
Hit <return> to enter the debugger>
This is more convenient for long debugging sessions, although it makes nmi_console feature somewhat useless.
And for the cases when NMI connected to a dedicated button, the knocking can be disabled altogether by setting kgdb_fiq.knock to -1.
--- drivers/tty/serial/Kconfig | 19 ++ drivers/tty/serial/Makefile | 1 + drivers/tty/serial/kgdb_nmi.c | 402 ++++++++++++++++++++++++++++++++++++++++++ drivers/tty/serial/kgdboc.c | 9 + include/linux/kgdb.h | 10 ++ 5 files changed, 441 insertions(+) create mode 100644 drivers/tty/serial/kgdb_nmi.c
drivers/tty/serial/Kconfig +19 -0
@@ -141,6 +141,25 @@ config SERIAL_ATMEL_TTYAT Say Y if you have an external 8250/16C550 UART. If unsure, say N. +config SERIAL_KGDB_NMI + bool "Serial console over KGDB NMI debugger port" + depends on KGDB_SERIAL_CONSOLE + help + This special driver allows you to temporary use NMI debugger port + as a normal console (assuming that the port is attached to KGDB). + + Unlike KDB's disable_nmi command, with this driver you are always + able to go back to the debugger using KGDB escape sequence ($3#33). + This is because this console driver processes the input in NMI + context, and thus is able to intercept the magic sequence. + + Note that since the console interprets input and uses polling + communication methods, for things like PPP you still must fully + detach debugger port from the KGDB NMI (i.e. disable_nmi), and + use raw console. + + If unsure, say N. + config SERIAL_KS8695 bool "Micrel KS8695 (Centaur) serial port support" depends on ARCH_KS8695
drivers/tty/serial/Makefile +1 -0
@@ -61,6 +61,7 @@ obj-$(CONFIG_SERIAL_MSM_HS) += msm_serial_hs.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o +obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
drivers/tty/serial/kgdb_nmi.c new file +402 -0
402 lines not on this page · raw message
drivers/tty/serial/kgdboc.c +9 -0
@@ -145,6 +145,8 @@ __setup("kgdboc=", kgdboc_option_setup);static void cleanup_kgdboc (void ) { +if (kgdb_unregister_nmi_console ()) +return ;kgdboc_unregister_kbd ();if (configured ==1 )kgdb_unregister_io_module (&kgdboc_io_ops);
@@ -198,11 +200,18 @@ do_register:if (err) goto noconfig; + err =kgdb_register_nmi_console (); +if (err) + goto nmi_con_failed; + configured =1 ;return 0 ; +nmi_con_failed: +kgdb_unregister_io_module (&kgdboc_io_ops); noconfig: +kgdboc_unregister_kbd (); config[0 ] =0 ; configured =0 ;cleanup_kgdboc ();
include/linux/kgdb.h +10 -0
@@ -286,6 +286,16 @@ extern struct kgdb_arch arch_kgdb_ops;extern unsigned long __weak kgdb_arch_pc (int exception,struct pt_regs *regs); +#ifdef CONFIG_SERIAL_KGDB_NMI +extern int kgdb_register_nmi_console (void ); +extern int kgdb_unregister_nmi_console (void ); +extern bool kgdb_nmi_poll_knock (void ); +#else +static inline int kgdb_register_nmi_console (void ) {return 0 ; } +static inline int kgdb_unregister_nmi_console (void ) {return 0 ; } +static inline bool kgdb_nmi_poll_knock (void ) {return 1 ; } +#endif +extern int kgdb_register_io_module (struct kgdb_io *local_kgdb_io_ops);extern void kgdb_unregister_io_module (struct kgdb_io *local_kgdb_io_ops);extern struct kgdb_io *dbg_io_ops;
Signature · 1 line
1.7.11.5
Jason Wessel
maintainerRe: [PATCH 07/11] tty/serial: Add kgdb_nmi driver
Quoted 4 lines · Anton Vorontsov
This special driver makes it possible to temporary use NMI debugger port as a normal console by issuing '
nmi_console' command (assuming that the port is attached to KGDB).
The kgdb regression compiler also does checkpatch, so the "check patch police" don't come chasing us let's get rid of this warning. This comes with the disclaimer that I believe checkpatch is a bit overly agressive in the first place. :-)
WARNING: quoted string split across lines
#133: FILE: drivers/tty/serial/kgdb_nmi.c:36:
+MODULE_PARM_DESC(knock, "if set to 1 (default), the special '$3#33' command "
+ "must be used to enter the debugger; when set to 0, "
--- drivers/tty/serial/kgdb_nmi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/tty/serial/kgdb_nmi.c +4 -4
@@ -32,10 +32,10 @@static int kgdb_nmi_knock =1 ;module_param_named (knock, kgdb_nmi_knock, int,0600 ); -MODULE_PARM_DESC (knock,"if set to 1 (default), the special '$3#33' command " -"must be used to enter the debugger; when set to 0, " -"hitting return key is enough to enter the debugger; " -"when set to -1, the debugger is entered immediately " +MODULE_PARM_DESC (knock,"if set to 1 (default), the special '$3#33' command " \ +"must be used to enter the debugger; when set to 0, " \ +"hitting return key is enough to enter the debugger; " \ +"when set to -1, the debugger is entered immediately " \"upon NMI" );static char *kgdb_nmi_magic ="$3#33" ;
PATCH v8 7/11 tty/serial: Add kgdb_nmi driver
This special driver makes it possible to temporary use NMI debugger port as a normal console by issuing 'nmi_console' command (assuming that the port is attached to KGDB).
Unlike KDB's disable_nmi command, with this driver you are always able to go back to the debugger using KGDB escape sequence ($3#33). This is because this console driver processes the input in NMI context, and thus is able to intercept the magic sequence.
Note that since the console interprets input and uses polling communication methods, for things like PPP it is still better to fully detach debugger port from the KGDB NMI (i.e. disable_nmi), and use raw console.
Usually, to enter the debugger one have to type the magic sequence, so initially the kernel will print the following prompt on the NMI debugger console:
Type $3#33 to enter the debugger>
For convenience, there is a kgdb_fiq.knock kernel command line option, when set to 0, this turns the special command to just a return key press, so the kernel will be printing this:
Hit <return> to enter the debugger>
This is more convenient for long debugging sessions, although it makes nmi_console feature somewhat useless.
And for the cases when NMI connected to a dedicated button, the knocking can be disabled altogether by setting kgdb_fiq.knock to -1.
---
Quoted 11 lines · Jason Wessel
Quoted 4 lines · Anton Vorontsov
This special driver makes it possible to temporary use NMI debugger port as a normal console by issuing '
nmi_console' command (assuming that the port is attached to KGDB).The kgdb regression compiler also does checkpatch, so the "check patch police" don't come chasing us let's get rid of this warning. This comes with the disclaimer that I believe checkpatch is a bit overly agressive in the first place. :-)
Yup, I saw that warning, but decided to ignore as it was not legitimate.
But sure, I'm fine either way, let's silence it.
[....]
Quoted 4 lines
I have the kgdb regression builder running right now (it will be done in about 1 hour), and so far it picked up one new warning.
drivers/tty/serial/kgdb_nmi.c: In function 'kgdb_nmi_poll_one_knock':drivers/tty/serial/kgdb_nmi.c:161: warning: field width should have type 'int', but argument 4 has type 'size_t'
Ouch, 64 bit. This is something I forgot to test, as I work mostly with 32 bit ARM builds.
This small hunk fixes it up:
- kgdb_nmi_knock ? magic : "<return>", m, ""); + kgdb_nmi_knock ? magic : "<return>", (int)m, "");
Thanks for catching this!
These two fixups included in the patch down below.
drivers/tty/serial/Kconfig | 19 ++ drivers/tty/serial/Makefile | 1 + drivers/tty/serial/kgdb_nmi.c | 402 ++++++++++++++++++++++++++++++++++++++++++ drivers/tty/serial/kgdboc.c | 9 + include/linux/kgdb.h | 10 ++ 5 files changed, 441 insertions(+) create mode 100644 drivers/tty/serial/kgdb_nmi.c
drivers/tty/serial/Kconfig +19 -0
@@ -141,6 +141,25 @@ config SERIAL_ATMEL_TTYAT Say Y if you have an external 8250/16C550 UART. If unsure, say N. +config SERIAL_KGDB_NMI + bool "Serial console over KGDB NMI debugger port" + depends on KGDB_SERIAL_CONSOLE + help + This special driver allows you to temporary use NMI debugger port + as a normal console (assuming that the port is attached to KGDB). + + Unlike KDB's disable_nmi command, with this driver you are always + able to go back to the debugger using KGDB escape sequence ($3#33). + This is because this console driver processes the input in NMI + context, and thus is able to intercept the magic sequence. + + Note that since the console interprets input and uses polling + communication methods, for things like PPP you still must fully + detach debugger port from the KGDB NMI (i.e. disable_nmi), and + use raw console. + + If unsure, say N. + config SERIAL_KS8695 bool "Micrel KS8695 (Centaur) serial port support" depends on ARCH_KS8695
drivers/tty/serial/Makefile +1 -0
@@ -61,6 +61,7 @@ obj-$(CONFIG_SERIAL_MSM_HS) += msm_serial_hs.o obj-$(CONFIG_SERIAL_NETX) += netx-serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM) += of_serial.o obj-$(CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL) += nwpserial.o +obj-$(CONFIG_SERIAL_KGDB_NMI) += kgdb_nmi.o obj-$(CONFIG_SERIAL_KS8695) += serial_ks8695.o obj-$(CONFIG_SERIAL_OMAP) += omap-serial.o obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
drivers/tty/serial/kgdb_nmi.c new file +402 -0
402 lines not on this page · raw message
drivers/tty/serial/kgdboc.c +9 -0
@@ -145,6 +145,8 @@ __setup("kgdboc=", kgdboc_option_setup);static void cleanup_kgdboc (void ) { +if (kgdb_unregister_nmi_console ()) +return ;kgdboc_unregister_kbd ();if (configured ==1 )kgdb_unregister_io_module (&kgdboc_io_ops);
@@ -198,11 +200,18 @@ do_register:if (err) goto noconfig; + err =kgdb_register_nmi_console (); +if (err) + goto nmi_con_failed; + configured =1 ;return 0 ; +nmi_con_failed: +kgdb_unregister_io_module (&kgdboc_io_ops); noconfig: +kgdboc_unregister_kbd (); config[0 ] =0 ; configured =0 ;cleanup_kgdboc ();
include/linux/kgdb.h +10 -0
@@ -286,6 +286,16 @@ extern struct kgdb_arch arch_kgdb_ops;extern unsigned long __weak kgdb_arch_pc (int exception,struct pt_regs *regs); +#ifdef CONFIG_SERIAL_KGDB_NMI +extern int kgdb_register_nmi_console (void ); +extern int kgdb_unregister_nmi_console (void ); +extern bool kgdb_nmi_poll_knock (void ); +#else +static inline int kgdb_register_nmi_console (void ) {return 0 ; } +static inline int kgdb_unregister_nmi_console (void ) {return 0 ; } +static inline bool kgdb_nmi_poll_knock (void ) {return 1 ; } +#endif +extern int kgdb_register_io_module (struct kgdb_io *local_kgdb_io_ops);extern void kgdb_unregister_io_module (struct kgdb_io *local_kgdb_io_ops);extern struct kgdb_io *dbg_io_ops;
Signature · 1 line
1.7.11.5
PATCH v8 8/11 ARM: Move some macros from entry-armv to entry-header
In reply to Anton VorontsovJust move the macros into header file as we would want to use them for KGDB FIQ entry code.
The following macros were moved:
- svc_entry
- usr_entry
- kuser_cmpxchg_check
- vector_stub
To make kuser_cmpxchg_check actually work across different files, we also have to make kuser_cmpxchg64_fixup global.
--- arch/arm/kernel/entry-armv.S | 167 +--------------------------------------- arch/arm/kernel/entry-header.S | 170 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+), 166 deletions(-)
arch/arm/kernel/entry-armv.S +1 -166
@@ -136,57 +136,6 @@ common_invalid: b bad_mode ENDPROC(__und_invalid) -/* - * SVC mode handlers - */ - -#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) -#define SPFIX(code...) code -#else -#define SPFIX(code...) -#endif - - .macro svc_entry, stack_hole=0 - UNWIND(.fnstart ) - UNWIND(.save {r0 - pc} ) - sub sp, sp, #(S_FRAME_SIZE + \stack_hole - 4) -#ifdef CONFIG_THUMB2_KERNEL - SPFIX( str r0, [sp] ) @ temporarily saved - SPFIX( mov r0, sp ) - SPFIX( tst r0, #4 ) @ test original stack alignment - SPFIX( ldr r0, [sp] ) @ restored -#else - SPFIX( tst sp, #4 ) -#endif - SPFIX( subeq sp, sp, #4 ) - stmia sp, {r1 - r12} - - ldmia r0, {r3 - r5} - add r7, sp, #S_SP - 4 @ here for interlock avoidance - mov r6, #-1 @ "" "" "" "" - add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4) - SPFIX( addeq r2, r2, #4 ) - str r3, [sp, #-4]! @ save the "real" r0 copied - @ from the exception stack - - mov r3, lr - - @ - @ We are now ready to fill in the remaining blanks on the stack: - @ - @ r2 - sp_svc - @ r3 - lr_svc - @ r4 - lr_<exception>, already fixed up for correct return/restart - @ r5 - spsr_<exception> - @ r6 - orig_r0 (see pt_regs definition in ptrace.h) - @ - stmia r7, {r2 - r6} - -#ifdef CONFIG_TRACE_IRQFLAGS - bl trace_hardirqs_off -#endif - .endm - .align 5 __dabt_svc: svc_entry
@@ -348,71 +297,8 @@ ENDPROC(__pabt_svc) /* * User mode handlers - * - * EABI note: sp_svc is always 64-bit aligned here, so should S_FRAME_SIZE */ -#if defined(CONFIG_AEABI) && (__LINUX_ARM_ARCH__ >= 5) && (S_FRAME_SIZE & 7) -#error "sizeof(struct pt_regs) must be a multiple of 8" -#endif - - .macro usr_entry - UNWIND(.fnstart ) - UNWIND(.cantunwind ) @ don't unwind the user space - sub sp, sp, #S_FRAME_SIZE - ARM( stmib sp, {r1 - r12} ) - THUMB( stmia sp, {r0 - r12} ) - - ldmia r0, {r3 - r5} - add r0, sp, #S_PC @ here for interlock avoidance - mov r6, #-1 @ "" "" "" "" - - str r3, [sp] @ save the "real" r0 copied - @ from the exception stack - - @ - @ We are now ready to fill in the remaining blanks on the stack: - @ - @ r4 - lr_<exception>, already fixed up for correct return/restart - @ r5 - spsr_<exception> - @ r6 - orig_r0 (see pt_regs definition in ptrace.h) - @ - @ Also, separately save sp_usr and lr_usr - @ - stmia r0, {r4 - r6} - ARM( stmdb r0, {sp, lr}^ ) - THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) - - @ - @ Enable the alignment trap while in kernel mode - @ - alignment_trap r0 - - @ - @ Clear FP to mark the first stack frame - @ - zero_fp - -#ifdef CONFIG_IRQSOFF_TRACER - bl trace_hardirqs_off -#endif - .endm - - .macro kuser_cmpxchg_check -#if !defined(CONFIG_CPU_32v6K) && !defined(CONFIG_NEEDS_SYSCALL_FOR_CMPXCHG) -#ifndef CONFIG_MMU -#warning "NPTL on non MMU needs fixing" -#else - @ Make sure our user space atomic helper is restarted - @ if it was interrupted in a critical region. Here we - @ perform a quick test inline since it should be false - @ 99.9999% of the time. The rest is done out of line. - cmp r4, #TASK_SIZE - blhs kuser_cmpxchg64_fixup -#endif -#endif - .endm - .align 5 __dabt_usr: usr_entry
@@ -846,6 +732,7 @@ __kuser_cmpxchg64: @ 0xffff0f60 ldmfd sp!, {r4, r5, r6, pc} .text + .global kuser_cmpxchg64_fixup kuser_cmpxchg64_fixup: @ Called from kuser_cmpxchg_fixup. @ r4 = address of interrupted insn (must be preserved).
@@ -976,58 +863,6 @@ __kuser_helper_end: THUMB( .thumb ) -/* - * Vector stubs. - * - * This code is copied to 0xffff0200 so we can use branches in the - * vectors, rather than ldr's. Note that this code must not - * exceed 0x300 bytes. - * - * Common stub entry macro: - * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC - * - * SP points to a minimal amount of processor-private memory, the address - * of which is copied into r0 for the mode specific abort handler. - */ - .macro vector_stub, name, mode, correction=0 - .align 5 - -vector_\name: - .if \correction - sub lr, lr, #\correction - .endif - - @ - @ Save r0, lr_<exception> (parent PC) and spsr_<exception> - @ (parent CPSR) - @ - stmia sp, {r0, lr} @ save r0, lr - mrs lr, spsr - str lr, [sp, #8] @ save spsr - - @ - @ Prepare for SVC32 mode. IRQs remain disabled. - @ - mrs r0, cpsr - eor r0, r0, #(\mode ^ SVC_MODE | PSR_ISETSTATE) - msr spsr_cxsf, r0 - - @ - @ the branch table must immediately follow this code - @ - and lr, lr, #0x0f - THUMB( adr r0, 1f ) - THUMB( ldr lr, [r0, lr, lsl #2] ) - mov r0, sp - ARM( ldr lr, [pc, lr, lsl #2] ) - movs pc, lr @ branch to handler in SVC mode -ENDPROC(vector_\name) - - .align 2 - @ handler addresses follow this label -1: - .endm - .globl __stubs_start __stubs_start: /*
arch/arm/kernel/entry-header.S +170 -0
182 lines not on this page · raw message
Signature · 1 line
1.7.11.5
PATCH v8 9/11 ARM: Add KGDB/KDB FIQ debugger generic code
In reply to Anton VorontsovThe FIQ debugger may be used to debug situations when the kernel stuck in uninterruptable sections, e.g. the kernel infinitely loops or deadlocked in an interrupt or with interrupts disabled.
By default KGDB FIQ is disabled in runtime, but can be enabled with kgdb_fiq.enable=1 kernel command line option.
--- arch/arm/Kconfig | 18 ++++++ arch/arm/include/asm/kgdb.h | 8 +++ arch/arm/kernel/Makefile | 1 + arch/arm/kernel/kgdb_fiq.c | 124 +++++++++++++++++++++++++++++++++++++++ arch/arm/kernel/kgdb_fiq_entry.S | 87 +++++++++++++++++++++++++++ 5 files changed, 238 insertions(+) create mode 100644 arch/arm/kernel/kgdb_fiq.c create mode 100644 arch/arm/kernel/kgdb_fiq_entry.S
arch/arm/Kconfig +18 -0
@@ -171,6 +171,24 @@ config GENERIC_ISA_DMA config FIQ bool +config ARCH_MIGHT_HAVE_KGDB_FIQ + bool + +config KGDB_FIQ + bool "KGDB/KDB FIQ debugger" + depends on KGDB_KDB && ARCH_MIGHT_HAVE_KGDB_FIQ && !THUMB2_KERNEL + select FIQ + help + The FIQ debugger may be used to debug situations when the + kernel stuck in uninterruptable sections, e.g. the kernel + infinitely loops or deadlocked in an interrupt or with + interrupts disabled. + + By default KGDB FIQ is disabled in runtime, but can be + enabled with kgdb_fiq.enable=1 kernel command line option. + + If unsure, say N. + config NEED_RET_TO_USER bool
arch/arm/include/asm/kgdb.h +8 -0
@@ -11,6 +11,8 @@#define __ARM_KGDB_H__#include <linux/ptrace.h> +#include <linux/linkage.h> +#include <asm/exception.h> /* * GDB assumes that we're a user process being debugged, so
@@ -47,6 +49,12 @@ static inline void arch_kgdb_breakpoint(void)extern void kgdb_handle_bus_error (void );extern int kgdb_fault_expected; +extern char kgdb_fiq_handler; +extern char kgdb_fiq_handler_end; +asmlinkage void __exception_irq_entry kgdb_fiq_do_handle(struct pt_regs *regs); +extern int __init kgdb_register_fiq (unsigned int mach_kgdb_fiq, +void (*mach_kgdb_enable_fiq)(unsigned int irq,bool on), +bool (*mach_is_kgdb_fiq)(unsigned int irq));#endif /* !__ASSEMBLY__ */ /*
arch/arm/kernel/Makefile +1 -0
@@ -56,6 +56,7 @@ obj-$(CONFIG_ATAGS_PROC) += atags.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o obj-$(CONFIG_ARM_THUMBEE) += thumbee.o obj-$(CONFIG_KGDB) += kgdb.o +obj-$(CONFIG_KGDB_FIQ) += kgdb_fiq_entry.o kgdb_fiq.o obj-$(CONFIG_ARM_UNWIND) += unwind.o obj-$(CONFIG_HAVE_TCM) += tcm.o obj-$(CONFIG_OF) += devtree.o
arch/arm/kernel/kgdb_fiq.c new file +124 -0
124 lines not on this page · raw message
arch/arm/kernel/kgdb_fiq_entry.S new file +87 -0
87 lines not on this page · raw message
Signature · 1 line
1.7.11.5
PATCH v8 10/11 ARM: VIC: Add a couple of low-level FIQ management helpers
In reply to Anton VorontsovJust a couple of calls to manage VIC FIQ routing. We'll use them for KGDB FIQ support on ARM Versatile machines.
--- arch/arm/common/vic.c | 28 ++++++++++++++++++++++++++++ arch/arm/include/asm/hardware/vic.h | 2 ++ 2 files changed, 30 insertions(+)
arch/arm/common/vic.c +28 -0
@@ -66,6 +66,34 @@ static struct vic_device vic_devices[CONFIG_ARM_VIC_NR];static int vic_id; +static void __iomem *vic_base (struct irq_data *d) +{ +return (void __iomem *)irq_data_get_irq_chip_data (d); +} + +void vic_fiq_select (unsigned int irq,bool on) +{ +void __iomem *base =vic_base (&irq_to_desc (irq)->irq_data); +void __iomem *sel = base +VIC_INT_SELECT ; +u32 msk =1 << irq; +u32 val; + +pr_debug ("rerouting VIC vector %d to %s\n" , irq, on ?"FIQ" :"IRQ" ); + + val =readl (sel); + val &= ~msk; +if (on) + val |= msk; +writel (val, sel); +} + +bool vic_is_fiq_rised (unsigned int irq) +{ +void __iomem *base =vic_base (&irq_to_desc (irq)->irq_data); + +return readl (base +VIC_FIQ_STATUS ) & (1 << irq); +} +/** * vic_init2 - common initialisation code * @base: Base of the VIC.
arch/arm/include/asm/hardware/vic.h +2 -0
@@ -52,6 +52,8 @@ void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,void vic_init (void __iomem *base,unsigned int irq_start,u32 vic_sources,u32 resume_sources);int vic_of_init (struct device_node *node,struct device_node *parent);void vic_handle_irq (struct pt_regs *regs); +void vic_fiq_select (unsigned int irq,bool on); +bool vic_is_fiq_rised (unsigned int irq);#endif /* __ASSEMBLY__ */ #endif
Signature · 1 line
1.7.11.5
PATCH v8 11/11 ARM: versatile: Make able to use UART ports for KGDB FIQ debugger
In reply to Anton VorontsovIf enabled, kernel will able to enter KGDB upon serial line activity on UART ports.
Note that even with this patch and CONFIG_KGDB_FIQ is enabled, you still need to pass kgdb_fiq.enable=1 kernel command line option, otherwise UART will behave in a normal way.
By default UART0 is used, but this can be changed via kgdb_fiq.uart_num kernel command line option.
--- arch/arm/Kconfig | 1 + arch/arm/mach-versatile/Makefile | 1 + arch/arm/mach-versatile/kgdb_fiq.c | 31 +++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 arch/arm/mach-versatile/kgdb_fiq.c
arch/arm/Kconfig +1 -0
@@ -336,6 +336,7 @@ config ARCH_VERSATILE select PLAT_VERSATILE_CLCD select PLAT_VERSATILE_FPGA_IRQ select ARM_TIMER_SP804 + select ARCH_MIGHT_HAVE_KGDB_FIQ help This enables support for ARM Ltd Versatile board.
arch/arm/mach-versatile/Makefile +1 -0
@@ -7,3 +7,4 @@ obj-$(CONFIG_ARCH_VERSATILE_PB) += versatile_pb.o obj-$(CONFIG_MACH_VERSATILE_AB) += versatile_ab.o obj-$(CONFIG_MACH_VERSATILE_DT) += versatile_dt.o obj-$(CONFIG_PCI) += pci.o +obj-$(CONFIG_KGDB_FIQ) += kgdb_fiq.o
arch/arm/mach-versatile/kgdb_fiq.c new file +31 -0
@@ -0,0 +1,31 @@ +/* +* KGDB FIQ board support +* +* Copyright 2012 Linaro Ltd. +* Anton Vorontsov <[email protected]> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License version 2 as published +* by the Free Software Foundation. +*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kgdb.h> +#include <mach/hardware.h> +#include <mach/platform.h> +#include <asm/hardware/vic.h> + +static int kgdb_fiq; +module_param_named (uart_num, kgdb_fiq, int,0600 ); +MODULE_PARM_DESC (uart_num,"UART<number> port to use for KGDB FIQ" ); + +static int __init kgdb_fiq_init (void ) +{ +WARN_ON (kgdb_fiq >INT_UARTINT2 -INT_UARTINT0 ); + +return kgdb_register_fiq (INT_UARTINT0 + kgdb_fiq, + vic_fiq_select, + vic_is_fiq_rised); +} +console_initcall (kgdb_fiq_init);
Signature · 1 line
1.7.11.5
Jason Wessel
maintainerQuoted 4 lines · Anton Vorontsov
Hi all,
In v8, addressed Jason's comments:
Quoted 11 lines
- Changed
kgdb_enable_nmi()weak function tokgdb_archcallbck;
- We no longer registerdisable_nmicommand if arch does not register KGDB NMI handling (i.e. not filling kgdb_arch.enable_nmi callback);
- The same is for ttyNMI: if architecure does not provide us withenable_nmicall, we don't need the tty device. Of course, there is no way to tell wether a specific serial device can be used for NMI debugging, as it is not serial-device specific, but specific to whether IRQ can be rerouted to an NMI (for most our cases, pretty much every IRQ can be rerouted, e.g. a hot-pluggable serial device on a PCI bus).
- Rebased on the latest and greatest tty-next, just in case.
I have the kgdb regression builder running right now (it will be done in about 1 hour), and so far it picked up one new warning.
drivers/tty/serial/kgdb_nmi.c: In function 'kgdb_nmi_poll_one_knock':drivers/tty/serial/kgdb_nmi.c:161: warning: field width should have type 'int', but argument 4 has type 'size_t'
Jason.
Quoted 17 lines · Jason Wessel
Quoted 4 lines · Anton Vorontsov
Hi all,
In v8, addressed Jason's comments:
Quoted 11 lines
- Changed
kgdb_enable_nmi()weak function tokgdb_archcallbck;
- We no longer registerdisable_nmicommand if arch does not register KGDB NMI handling (i.e. not filling kgdb_arch.enable_nmi callback);
- The same is for ttyNMI: if architecure does not provide us withenable_nmicall, we don't need the tty device. Of course, there is no way to tell wether a specific serial device can be used for NMI debugging, as it is not serial-device specific, but specific to whether IRQ can be rerouted to an NMI (for most our cases, pretty much every IRQ can be rerouted, e.g. a hot-pluggable serial device on a PCI bus).
- Rebased on the latest and greatest tty-next, just in case.
Quoted 5 lines
I have the kgdb regression builder running right now (it will be done in about 1 hour), and so far it picked up one new warning.
drivers/tty/serial/kgdb_nmi.c: In function 'kgdb_nmi_poll_one_knock':drivers/tty/serial/kgdb_nmi.c:161: warning: field width should have type 'int', but argument 4 has type 'size_t'
Hi Anton,
You can add my ack to the series, for what you have in: "git://git.infradead.org/users/cbou/linux-nmi-kdb.git master", and then drop a pull request to Greg for the next merge window. Thank you for your hard work through all the revisions of this code and this slick new feature.
Cheers,
Jason.
On Mon, Sep 24, 2012 at 05:46:09AM -0500, Jason Wessel wrote: [...]
Quoted 7 lines
You can add my ack to the series, for what you have in:
"git://git.infradead.org/users/cbou/linux-nmi-kdb.gitmaster", and then drop a pull request to Greg for the next merge window. Thank you for your hard work through all the revisions of this code and this slick new feature.Acked-by Jason Wessel <[email protected]>
Great! Much thanks for your reviews, Jason!