diff options
Diffstat (limited to 'arch/arm/kernel/hw_breakpoint.c')
-rw-r--r-- | arch/arm/kernel/hw_breakpoint.c | 18 |
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 | */ |
741 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | 742 | static 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 | /* |
765 | out: | 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 | ||