Commit 74c68810 authored by Ravi Bangoria's avatar Ravi Bangoria Committed by Michael Ellerman

powerpc/watchpoint: Prepare handler to handle more than one watchpoint

Currently we assume that we have only one watchpoint supported by hw.
Get rid of that assumption and use dynamic loop instead. This should
make supporting more watchpoints very easy.

With more than one watchpoint, exception handler needs to know which
DAWR caused the exception, and hw currently does not provide it. So
we need sw logic for the same. To figure out which DAWR caused the
exception, check all different combinations of user specified range,
DAWR address range, actual access range and DAWRX constrains. For ex,
if user specified range and actual access range overlaps but DAWRX is
configured for readonly watchpoint and the instruction is store, this
DAWR must not have caused exception.
Signed-off-by: default avatarRavi Bangoria <ravi.bangoria@linux.ibm.com>
Reviewed-by: default avatarMichael Neuling <mikey@neuling.org>
[mpe: Unsplit multi-line printk() strings, fix some sparse warnings]
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20200514111741.97993-14-ravi.bangoria@linux.ibm.com
parent e68ef121
...@@ -185,7 +185,7 @@ struct thread_struct { ...@@ -185,7 +185,7 @@ struct thread_struct {
* Helps identify source of single-step exception and subsequent * Helps identify source of single-step exception and subsequent
* hw-breakpoint enablement * hw-breakpoint enablement
*/ */
struct perf_event *last_hit_ubp; struct perf_event *last_hit_ubp[HBP_NUM_MAX];
#endif /* CONFIG_HAVE_HW_BREAKPOINT */ #endif /* CONFIG_HAVE_HW_BREAKPOINT */
struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint info */ struct arch_hw_breakpoint hw_brk[HBP_NUM_MAX]; /* hardware breakpoint info */
unsigned long trap_nr; /* last trap # on this thread */ unsigned long trap_nr; /* last trap # on this thread */
......
...@@ -49,6 +49,8 @@ enum instruction_type { ...@@ -49,6 +49,8 @@ enum instruction_type {
#define INSTR_TYPE_MASK 0x1f #define INSTR_TYPE_MASK 0x1f
#define OP_IS_LOAD(type) ((LOAD <= (type) && (type) <= LOAD_VSX) || (type) == LARX)
#define OP_IS_STORE(type) ((STORE <= (type) && (type) <= STORE_VSX) || (type) == STCX)
#define OP_IS_LOAD_STORE(type) (LOAD <= (type) && (type) <= STCX) #define OP_IS_LOAD_STORE(type) (LOAD <= (type) && (type) <= STCX)
/* Compute flags, ORed in with type */ /* Compute flags, ORed in with type */
......
This diff is collapsed.
...@@ -629,9 +629,6 @@ void do_break (struct pt_regs *regs, unsigned long address, ...@@ -629,9 +629,6 @@ void do_break (struct pt_regs *regs, unsigned long address,
if (debugger_break_match(regs)) if (debugger_break_match(regs))
return; return;
/* Clear the breakpoint */
hw_breakpoint_disable();
/* Deliver the signal to userspace */ /* Deliver the signal to userspace */
force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address); force_sig_fault(SIGTRAP, TRAP_HWBKPT, (void __user *)address);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment