aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/hw_breakpoint.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/kernel/hw_breakpoint.c')
-rw-r--r--arch/arm/kernel/hw_breakpoint.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index d37ed3501e5..eeba3800803 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -24,6 +24,7 @@
24#define pr_fmt(fmt) "hw-breakpoint: " fmt 24#define pr_fmt(fmt) "hw-breakpoint: " fmt
25 25
26#include <linux/errno.h> 26#include <linux/errno.h>
27#include <linux/hardirq.h>
27#include <linux/perf_event.h> 28#include <linux/perf_event.h>
28#include <linux/hw_breakpoint.h> 29#include <linux/hw_breakpoint.h>
29#include <linux/smp.h> 30#include <linux/smp.h>
@@ -736,14 +737,17 @@ unlock:
736 737
737/* 738/*
738 * Called from either the Data Abort Handler [watchpoint] or the 739 * Called from either the Data Abort Handler [watchpoint] or the
739 * Prefetch Abort Handler [breakpoint]. 740 * Prefetch Abort Handler [breakpoint] with preemption disabled.
740 */ 741 */
741static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, 742static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
742 struct pt_regs *regs) 743 struct pt_regs *regs)
743{ 744{
744 int ret = 1; /* Unhandled fault. */ 745 int ret = 0;
745 u32 dscr; 746 u32 dscr;
746 747
748 /* We must be called with preemption disabled. */
749 WARN_ON(preemptible());
750
747 /* We only handle watchpoints and hardware breakpoints. */ 751 /* We only handle watchpoints and hardware breakpoints. */
748 ARM_DBG_READ(c1, 0, dscr); 752 ARM_DBG_READ(c1, 0, dscr);
749 753
@@ -758,11 +762,15 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr,
758 watchpoint_handler(addr, regs); 762 watchpoint_handler(addr, regs);
759 break; 763 break;
760 default: 764 default:
761 goto out; 765 ret = 1; /* Unhandled fault. */
762 } 766 }
763 767
764 ret = 0; 768 /*
765out: 769 * Re-enable preemption after it was disabled in the
770 * low-level exception handling code.
771 */
772 preempt_enable();
773
766 return ret; 774 return ret;
767} 775}
768 776