diff options
Diffstat (limited to 'arch/powerpc/kernel/kgdb.c')
| -rw-r--r-- | arch/powerpc/kernel/kgdb.c | 27 | 
1 files changed, 24 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c index 782bd0a3c2f..c470a40b29f 100644 --- a/arch/powerpc/kernel/kgdb.c +++ b/arch/powerpc/kernel/kgdb.c @@ -25,6 +25,7 @@  #include <asm/processor.h>  #include <asm/machdep.h>  #include <asm/debug.h> +#include <linux/slab.h>  /*   * This table contains the mapping between PowerPC hardware trap types, and @@ -101,6 +102,21 @@ static int computeSignal(unsigned int tt)  	return SIGHUP;		/* default for things we don't know about */  } +/** + * + *	kgdb_skipexception - Bail out of KGDB when we've been triggered. + *	@exception: Exception vector number + *	@regs: Current &struct pt_regs. + * + *	On some architectures we need to skip a breakpoint exception when + *	it occurs after a breakpoint has been removed. + * + */ +int kgdb_skipexception(int exception, struct pt_regs *regs) +{ +	return kgdb_isremovedbreak(regs->nip); +} +  static int kgdb_call_nmi_hook(struct pt_regs *regs)  {  	kgdb_nmicallback(raw_smp_processor_id(), regs); @@ -138,6 +154,8 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)  static int kgdb_singlestep(struct pt_regs *regs)  {  	struct thread_info *thread_info, *exception_thread_info; +	struct thread_info *backup_current_thread_info = \ +		(struct thread_info *)kmalloc(sizeof(struct thread_info), GFP_KERNEL);  	if (user_mode(regs))  		return 0; @@ -155,13 +173,17 @@ static int kgdb_singlestep(struct pt_regs *regs)  	thread_info = (struct thread_info *)(regs->gpr[1] & ~(THREAD_SIZE-1));  	exception_thread_info = current_thread_info(); -	if (thread_info != exception_thread_info) +	if (thread_info != exception_thread_info) { +		/* Save the original current_thread_info. */ +		memcpy(backup_current_thread_info, exception_thread_info, sizeof *thread_info);  		memcpy(exception_thread_info, thread_info, sizeof *thread_info); +	}  	kgdb_handle_exception(0, SIGTRAP, 0, regs);  	if (thread_info != exception_thread_info) -		memcpy(thread_info, exception_thread_info, sizeof *thread_info); +		/* Restore current_thread_info lastly. */ +		memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);  	return 1;  } @@ -410,7 +432,6 @@ int kgdb_arch_handle_exception(int vector, int signo, int err_code,  #else  			linux_regs->msr |= MSR_SE;  #endif -			kgdb_single_step = 1;  			atomic_set(&kgdb_cpu_doing_single_step,  				   raw_smp_processor_id());  		}  |