ARM: 6355/1: hw-breakpoint: add mechanism for hooking into prefetch aborts
authorWill Deacon <will.deacon@arm.com>
Fri, 3 Sep 2010 09:39:59 +0000 (10:39 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Wed, 8 Sep 2010 09:04:59 +0000 (10:04 +0100)
On ARM processors with hardware breakpoint and watchpoint support,
triggering these events results in a debug exception. These manifest
as prefetch and data aborts respectively.

arch/arm/mm/fault.c already provides hook_fault_code for hooking
into data aborts dependent on the DFSR. This patch adds a new function,
hook_ifault_code for hooking into prefetch aborts in the same manner.

Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: S. Karthikeyan <informkarthik@gmail.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
arch/arm/include/asm/system.h
arch/arm/mm/fault.c

index 8ba1ccf..b516cde 100644 (file)
@@ -85,6 +85,10 @@ void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
                                       struct pt_regs *),
                     int sig, int code, const char *name);
 
+void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
+                                      struct pt_regs *),
+                    int sig, int code, const char *name);
+
 #define xchg(ptr,x) \
        ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
 
index 23b0b03..1e21e12 100644 (file)
@@ -581,6 +581,19 @@ static struct fsr_info ifsr_info[] = {
        { do_bad,               SIGBUS,  0,             "unknown 31"                       },
 };
 
+void __init
+hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *),
+                int sig, int code, const char *name)
+{
+       if (nr < 0 || nr >= ARRAY_SIZE(ifsr_info))
+               BUG();
+
+       ifsr_info[nr].fn   = fn;
+       ifsr_info[nr].sig  = sig;
+       ifsr_info[nr].code = code;
+       ifsr_info[nr].name = name;
+}
+
 asmlinkage void __exception
 do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
 {