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.

Signed-off-by: Anton Vorontsov <anton.vorontsov@linaro.org>
Acked-by: Jason Wessel <jason.wessel@windriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Anton Vorontsov 2012-09-24 14:27:50 -07:00 committed by Greg Kroah-Hartman
parent c5dd553b9f
commit 5a14fead07
2 changed files with 14 additions and 3 deletions

View File

@ -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);
};
/**

View File

@ -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)