On Mon, May 25, 2009 at 06:46:50AM +0530, K.Prasad wrote:
Modify process handling code to recognise hardware debug registers during copy
and flush operations. Introduce a new TIF_DEBUG task flag to indicate a
process's use of debug register. Load the debug register values into a
new CPU during initialisation.
[snip]
quoted hunk ↗ jump to hunk
Index: linux-2.6-tip.hbkpt/arch/powerpc/kernel/process.c
===================================================================
--- linux-2.6-tip.hbkpt.orig/arch/powerpc/kernel/process.c
+++ linux-2.6-tip.hbkpt/arch/powerpc/kernel/process.c
@@ -50,6 +50,7 @@
#include <asm/syscalls.h>
#ifdef CONFIG_PPC64
#include <asm/firmware.h>
+#include <asm/hw_breakpoint.h>
#endif
#include <linux/kprobes.h>
#include <linux/kdebug.h>
@@ -254,8 +255,10 @@ void do_dabr(struct pt_regs *regs, unsig
11, SIGSEGV) == NOTIFY_STOP)
return;
+#ifndef CONFIG_PPC64
if (debugger_dabr_match(regs))
return;
+#endif
/* Clear the DAC and struct entries. One shot trigger */
#if defined(CONFIG_BOOKE)
@@ -372,8 +375,13 @@ struct task_struct *__switch_to(struct t
#endif /* CONFIG_SMP */
+#ifdef CONFIG_PPC64
+ if (unlikely(test_tsk_thread_flag(new, TIF_DEBUG)))
+ arch_install_thread_hw_breakpoint(new);
+#else
if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
set_dabr(new->thread.dabr);
+#endif /* CONFIG_PPC64 */
#if defined(CONFIG_BOOKE)
/* If new thread DAC (HW breakpoint) is the same then leave it */
@@ -550,6 +558,10 @@ void show_regs(struct pt_regs * regs)
void exit_thread(void)
{
discard_lazy_cpu_state();
+#ifdef CONFIG_PPC64
+ if (unlikely(test_tsk_thread_flag(current, TIF_DEBUG)))
+ flush_thread_hw_breakpoint(current);
+#endif /* CONFIG_PPC64 */
}
void flush_thread(void)@@ -605,6 +617,9 @@ int copy_thread(unsigned long clone_flag
struct pt_regs *childregs, *kregs;
extern void ret_from_fork(void);
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
+#ifdef CONFIG_PPC64
+ struct task_struct *tsk = current;
I don't see any point to adding this variable, just reference current
directly below.
quoted hunk ↗ jump to hunk
+#endif
CHECK_FULL_REGS(regs);
/* Copy registers */
@@ -672,6 +687,9 @@ int copy_thread(unsigned long clone_flag
* function.
*/
kregs->nip = *((unsigned long *)ret_from_fork);
+
+ if (unlikely(test_tsk_thread_flag(tsk, TIF_DEBUG)))
+ copy_thread_hw_breakpoint(tsk, p, clone_flags);
#else
kregs->nip = (unsigned long)ret_from_fork;
#endif
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson